[Crash-utility] [PATCH] Debugging xen hypervisor failed

Dietmar Hahn dietmar.hahn at ts.fujitsu.com
Wed Dec 11 11:15:29 UTC 2019


Hi Dave,

debugging newer xen hypervisors failed with:

crash: cannot resolve "init_tss"

This is caused by a change in the xen hypervisor with commit 78884406256,
from 4.12.0-rc5-763-g7888440625. In this patch the struct tss_struct was
renamed to tss64 and the structure tss_page was introduced which contains a
single tss64.
Now tss information are accessible via symbol "per_cpu__tss_page"

The code is as follows:

struct __packed tss64 {
    uint32_t :32;
    uint64_t rsp0, rsp1, rsp2;
    uint64_t :64;
    /*
     * Interrupt Stack Table is 1-based so tss->ist[0] corresponds to an IST
     * value of 1 in an Interrupt Descriptor.
     */
    uint64_t ist[7];
    uint64_t :64;
    uint16_t :16, bitmap;
};
struct tss_page {
    struct tss64 __aligned(PAGE_SIZE) tss;
};
DECLARE_PER_CPU(struct tss_page, tss_page);

To keep the change simple and small I renamed xen_hyper_size_table.tss_struct
to xen_hyper_size_table.tss and consequently I did the same for
tss_struct_rsp0, tss_struct_esp0 and tss_struct_ist.
But I'm not sure this is the way to go.
Thanks.

Dietmar.

---
 x86_64.c                | 20 +++++++++++++++-----
 xen_hyper.c             | 22 ++++++++++++----------
 xen_hyper_defs.h        |  8 ++++----
 xen_hyper_dump_tables.c |  8 ++++----
 4 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/x86_64.c b/x86_64.c
index a4138ed..4f1a6d7 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -7973,13 +7973,23 @@ x86_64_init_hyper(int when)
 
 	case POST_GDB:
 		XEN_HYPER_STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
-		XEN_HYPER_STRUCT_SIZE_INIT(tss_struct, "tss_struct");
-		if (MEMBER_EXISTS("tss_struct", "__blh")) {
-			XEN_HYPER_ASSIGN_OFFSET(tss_struct_rsp0) = MEMBER_OFFSET("tss_struct", "__blh") + sizeof(short unsigned int);
+		if (symbol_exists("per_cpu__tss_page")) {
+			XEN_HYPER_STRUCT_SIZE_INIT(tss, "tss64");
+			XEN_HYPER_ASSIGN_OFFSET(tss_rsp0) =
+							MEMBER_OFFSET("tss64", "rsp0");
+			XEN_HYPER_MEMBER_OFFSET_INIT(tss_ist, "tss64", "ist");
 		} else {
-			XEN_HYPER_ASSIGN_OFFSET(tss_struct_rsp0) = MEMBER_OFFSET("tss_struct", "rsp0");
+			XEN_HYPER_STRUCT_SIZE_INIT(tss, "tss_struct");
+			XEN_HYPER_MEMBER_OFFSET_INIT(tss_ist, "tss_struct", "ist");
+			if (MEMBER_EXISTS("tss_struct", "__blh")) {
+				XEN_HYPER_ASSIGN_OFFSET(tss_rsp0) =
+					MEMBER_OFFSET("tss_struct", "__blh") +
+								sizeof(short unsigned int);
+			} else	{
+				XEN_HYPER_ASSIGN_OFFSET(tss_rsp0) =
+							MEMBER_OFFSET("tss_struct", "rsp0");
+			}
 		}
-		XEN_HYPER_MEMBER_OFFSET_INIT(tss_struct_ist, "tss_struct", "ist");
 		if (symbol_exists("cpu_data")) {
 			xht->cpu_data_address = symbol_value("cpu_data");
 		}
diff --git a/xen_hyper.c b/xen_hyper.c
index f2f00e6..1030c0a 100644
--- a/xen_hyper.c
+++ b/xen_hyper.c
@@ -338,33 +338,35 @@ xen_hyper_x86_pcpu_init(void)
 	if((xhpct->pcpu_struct = malloc(XEN_HYPER_SIZE(cpu_info))) == NULL) {
 		error(FATAL, "cannot malloc pcpu struct space.\n");
 	}
-
 	/* get physical cpu context */
 	xen_hyper_alloc_pcpu_context_space(XEN_HYPER_MAX_CPUS());
 	if (symbol_exists("per_cpu__init_tss")) {
 		init_tss_base = symbol_value("per_cpu__init_tss");
 		flag = TRUE;
+	} else if (symbol_exists("per_cpu__tss_page")) {
+			init_tss_base = symbol_value("per_cpu__tss_page");
+			flag = TRUE;
 	} else {
 		init_tss_base = symbol_value("init_tss");
 		flag = FALSE;
 	}
-	buf = GETBUF(XEN_HYPER_SIZE(tss_struct));	
+	buf = GETBUF(XEN_HYPER_SIZE(tss));
 	for_cpu_indexes(i, cpuid)
 	{
 		if (flag)
 			init_tss = xen_hyper_per_cpu(init_tss_base, cpuid);
 		else
 			init_tss = init_tss_base +
-				XEN_HYPER_SIZE(tss_struct) * cpuid;
+				XEN_HYPER_SIZE(tss) * cpuid;
 		if (!readmem(init_tss, KVADDR, buf,
-			XEN_HYPER_SIZE(tss_struct), "init_tss", RETURN_ON_ERROR)) {
+			XEN_HYPER_SIZE(tss), "init_tss", RETURN_ON_ERROR)) {
 			error(FATAL, "cannot read init_tss.\n");
 		}
 		if (machine_type("X86")) {
-			sp = ULONG(buf + XEN_HYPER_OFFSET(tss_struct_esp0));
+			sp = ULONG(buf + XEN_HYPER_OFFSET(tss_esp0));
 		} else if (machine_type("X86_64")) {
-			sp = ULONG(buf + XEN_HYPER_OFFSET(tss_struct_rsp0));
-		} else 
+			sp = ULONG(buf + XEN_HYPER_OFFSET(tss_rsp0));
+		} else
 			sp = 0;
 		cpu_info = XEN_HYPER_GET_CPU_INFO(sp);
 		if (CRASHDEBUG(1)) {
@@ -1777,10 +1779,10 @@ xen_hyper_store_pcpu_context_tss(struct xen_hyper_pcpu_context *pcc,
 
 	pcc->init_tss = init_tss;
 	if (machine_type("X86")) {
-		pcc->sp.esp0 = ULONG(tss + XEN_HYPER_OFFSET(tss_struct_esp0));
+		pcc->sp.esp0 = ULONG(tss + XEN_HYPER_OFFSET(tss_esp0));
 	} else if (machine_type("X86_64")) {
-		pcc->sp.rsp0 = ULONG(tss + XEN_HYPER_OFFSET(tss_struct_rsp0));
-		ist_p = (uint64_t *)(tss + XEN_HYPER_OFFSET(tss_struct_ist));
+		pcc->sp.rsp0 = ULONG(tss + XEN_HYPER_OFFSET(tss_rsp0));
+		ist_p = (uint64_t *)(tss + XEN_HYPER_OFFSET(tss_ist));
 		for (i = 0; i < XEN_HYPER_TSS_IST_MAX; i++, ist_p++) {
 			pcc->ist[i] = ULONG(ist_p);
 		}
diff --git a/xen_hyper_defs.h b/xen_hyper_defs.h
index b871bdd..acf910a 100644
--- a/xen_hyper_defs.h
+++ b/xen_hyper_defs.h
@@ -598,7 +598,7 @@ struct xen_hyper_size_table {
 	long scheduler;
 	long shared_info;
 	long timer;
-	long tss_struct;
+	long tss;
 	long vcpu;
 	long vcpu_runstate_info;
 	long xen_crash_xen_regs_t;		/* elf note v2 */
@@ -727,9 +727,9 @@ struct xen_hyper_offset_table {
 	long timer_heap_offset;
 	long timer_killed;
 	/* tss */
-	long tss_struct_rsp0;
-	long tss_struct_esp0;
-	long tss_struct_ist;
+	long tss_rsp0;
+	long tss_esp0;
+	long tss_ist;
 	/* vcpu */
 	long vcpu_vcpu_id;
 	long vcpu_processor;
diff --git a/xen_hyper_dump_tables.c b/xen_hyper_dump_tables.c
index eb646b6..0360d25 100644
--- a/xen_hyper_dump_tables.c
+++ b/xen_hyper_dump_tables.c
@@ -636,8 +636,8 @@ xen_hyper_dump_xen_hyper_size_table(char *spec, ulong makestruct)
 		(buf, "%ld\n", xen_hyper_size_table.shared_info));
 	XEN_HYPER_PRI(fp, len, "timer: ", buf, flag,
 		(buf, "%ld\n", xen_hyper_size_table.timer));
-	XEN_HYPER_PRI(fp, len, "tss_struct: ", buf, flag,
-		(buf, "%ld\n", xen_hyper_size_table.tss_struct));
+	XEN_HYPER_PRI(fp, len, "tss: ", buf, flag,
+		(buf, "%ld\n", xen_hyper_size_table.tss));
 	XEN_HYPER_PRI(fp, len, "vcpu: ", buf, flag,
 		(buf, "%ld\n", xen_hyper_size_table.vcpu));
 	XEN_HYPER_PRI(fp, len, "vcpu_runstate_info: ", buf, flag,
@@ -868,9 +868,9 @@ xen_hyper_dump_xen_hyper_offset_table(char *spec, ulong makestruct)
 		(buf, "%ld\n", xen_hyper_offset_table.timer_killed));
 
 	XEN_HYPER_PRI(fp, len, "tss_struct_rsp0: ", buf, flag,
-		(buf, "%ld\n", xen_hyper_offset_table.tss_struct_rsp0));
+		(buf, "%ld\n", xen_hyper_offset_table.tss_rsp0));
 	XEN_HYPER_PRI(fp, len, "tss_struct_esp0: ", buf, flag,
-		(buf, "%ld\n", xen_hyper_offset_table.tss_struct_esp0));
+		(buf, "%ld\n", xen_hyper_offset_table.tss_esp0));
 
 	XEN_HYPER_PRI(fp, len, "vcpu_vcpu_id: ", buf, flag,
 		(buf, "%ld\n", xen_hyper_offset_table.vcpu_vcpu_id));
-- 
2.16.4









More information about the Crash-utility mailing list