Since Xen commit 666aca08175b ("sched: use the auto-generated list of
schedulers") crash cannot open Xen vmcores, because symbol 'schedulers'
does not exits. Xen 4.7 implemented schedulers as its own section.
xen/arch/x86/xen.lds.S
__start_schedulers_array = .;
*(.data.schedulers)
__end_schedulers_array = .;
Crash must not look up for "schedulers" symbol and fails, if symbol is
not found. It must check if __start_schedulers_array exits, and if it
does, use it and get size of the section. Otherwise, crash fallback to
looking up "schedulers" symbol. That way, crash can open vmcore before
and after Xen 4.7.
Signed-off-by: Nikola Pajkovsky <npajkovsky(a)suse.cz>
---
xen_hyper.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/xen_hyper.c b/xen_hyper.c
index 479aa1acfd43..2a42e44b1f70 100644
--- a/xen_hyper.c
+++ b/xen_hyper.c
@@ -437,6 +437,16 @@ xen_hyper_misc_init(void)
*/
#define XEN_HYPER_SCHEDULER_NAME 1024
+static int section_size(char *start_section, char *end_section)
+{
+ ulong sp_start, sp_end;
+
+ sp_start = symbol_value(start_section);
+ sp_end = symbol_value(end_section);
+
+ return (sp_end - sp_start) / sizeof(long);
+}
+
static void
xen_hyper_schedule_init(void)
{
@@ -448,6 +458,7 @@ xen_hyper_schedule_init(void)
char *buf;
char opt_name_buf[XEN_HYPER_OPT_SCHED_SIZE];
int i, cpuid, flag;
+ char *sp_name;
/* get scheduler information */
if((xhscht->scheduler_struct =
@@ -469,9 +480,19 @@ xen_hyper_schedule_init(void)
XEN_HYPER_OPT_SCHED_SIZE, "opt_sched,", RETURN_ON_ERROR)) {
error(FATAL, "cannot read opt_sched,.\n");
}
- nr_schedulers = get_array_length("schedulers", 0, 0);
+
+ /* symbol exists since Xen 4.7 */
+ if (symbol_exists("__start_schedulers_array")) {
+ sp_name = "__start_schedulers_array";
+ nr_schedulers = section_size("__start_schedulers_array",
+ "__end_schedulers_array");
+ } else {
+ sp_name = "schedulers";
+ nr_schedulers = get_array_length("schedulers", 0, 0);
+ }
+
schedulers_buf = (long *)GETBUF(nr_schedulers * sizeof(long));
- schedulers = symbol_value("schedulers");
+ schedulers = symbol_value(sp_name);
addr = schedulers;
while (xhscht->name == NULL) {
if (!readmem(addr, KVADDR, schedulers_buf,
--
2.13.6