There is a regression been found for xen hyper due to the commit:
f615f8fab7bf ("Fix "irq -a" exceeding the memory range issue").
The reason is for xen hyper, kt->cpu is not initialized due to
kernel_init() won't be called. So 0 would be assigned to cpulen and
fails the GETBUF().
Before:
crash> bt -c 2
bt: zero-size memory allocation! (called from 51f168)
After:
crash> bt -c 2
PCPU: 0 VCPU: ffff8300001b8080
#0 [ffff8300001bfe00] machine_crash_kexec at ffff83000010de72
#1 [ffff8300001bfe10] do_kexec_op at ffff83000010e3cb
#2 [ffff8300001bfe50] do_console_io at ffff83000011aff4
#3 [ffff8300001bfe90] mod_l1_entry at ffff830000129045
#4 [ffff8300001bfea0] toggle_guest_mode at ffff8300001641bf
#5 [ffff8300001bfeb0] do_iret at ffff830000164888
#6 [ffff8300001bff20] syscall_enter at ffff8300001633d2
Since xen hyper will initialize its own cpumask_t, this patch will reuse
it for XEN_HYPER_MODE.
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
Link to v1:
https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01080.html
v1 -> v2: 1) Remove "xen_hyper_defs.h" include for tools.c.
2) Modified the same code hunk in generic_get_irq_affinity().
Note this patch will cause a small merge conflict with the NO.2 patch[1] of the
v7 gdb stack unwinding support. Should be easy to fix since it has no
functional modification on [1].
[1]:
https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg01081.html
---
defs.h | 3 +++
kernel.c | 10 ++++++----
tools.c | 3 +++
xen_hyper.c | 9 +++++++++
4 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index dfbd241..94f86e6 100644
--- a/defs.h
+++ b/defs.h
@@ -8031,6 +8031,9 @@ extern int have_full_symbols(void);
#if defined(X86) || defined(X86_64) || defined(IA64)
#define XEN_HYPERVISOR_ARCH
+long xen_get_cpumask_size(void);
+#else
+#define xen_get_cpumask_size() -1
#endif
/*
diff --git a/kernel.c b/kernel.c
index adb19ad..56deb3a 100644
--- a/kernel.c
+++ b/kernel.c
@@ -7382,10 +7382,12 @@ generic_get_irq_affinity(int irq)
if (!action)
return;
- len = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong);
- len_cpumask = STRUCT_SIZE("cpumask_t");
- if (len_cpumask > 0)
- len = len_cpumask > len ? len : len_cpumask;
+ if (!XEN_HYPER_MODE() || (len = xen_get_cpumask_size()) < 0) {
+ len = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong);
+ len_cpumask = STRUCT_SIZE("cpumask_t");
+ if (len_cpumask > 0)
+ len = len_cpumask > len ? len : len_cpumask;
+ }
affinity = (ulong *)GETBUF(len);
if (VALID_MEMBER(irq_common_data_affinity))
diff --git a/tools.c b/tools.c
index 2b78b95..c4fe9c8 100644
--- a/tools.c
+++ b/tools.c
@@ -6720,6 +6720,9 @@ get_cpumask_buf(void)
{
int cpulen, len_cpumask;
+ if (XEN_HYPER_MODE() && (cpulen = xen_get_cpumask_size()) >= 0)
+ return (ulong *)GETBUF(cpulen);
+
cpulen = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong);
len_cpumask = STRUCT_SIZE("cpumask_t");
if (len_cpumask > 0)
diff --git a/xen_hyper.c b/xen_hyper.c
index 32e56fa..db2dd6f 100644
--- a/xen_hyper.c
+++ b/xen_hyper.c
@@ -2201,4 +2201,13 @@ xen_hyper_print_bt_header(FILE *out, ulong vcpu, int newline)
error(FATAL, "invalid vcpu\n");
fprintf(out, "PCPU: %2d VCPU: %lx\n", vcc->processor, vcpu);
}
+
+long
+xen_get_cpumask_size(void)
+{
+ if (XEN_HYPER_VALID_SIZE(cpumask_t))
+ return XEN_HYPER_SIZE(cpumask_t);
+ else
+ return -1;
+}
#endif
--
2.40.1