On Wed, Dec 7, 2022 at 8:47 AM HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab@xxxxxxx> wrote: > > The following kernel commits (in linux-next now, to be updated) > introduced struct pcpu_hot and moved several per-cpu variables into it. > > d7b6d709a76a x86/percpu: Move irq_stack variables next to current_task > 7443b296e699 x86/percpu: Move cpu_number next to current_task > e57ef2ed97c1 x86: Put hot per CPU variables into a struct > > Without the patch, crash fails to start session with the following > error: > > bt: invalid size request: 0 type: "stack contents" > bt: read of stack at 0 failed > <segmentation violation in gdb> > Thank you for the early fix, Kazu. This change looks good. So: Ack Thanks. Lianbo > Signed-off-by: Kazuhito Hagio <k-hagio-ab@xxxxxxx> > --- > x86_64.c | 44 +++++++++++++++++++++++++++++++++----------- > 1 file changed, 33 insertions(+), 11 deletions(-) > > diff --git a/x86_64.c b/x86_64.c > index 74bd1bbde41c..7a5d6f050c89 100644 > --- a/x86_64.c > +++ b/x86_64.c > @@ -1290,12 +1290,15 @@ x86_64_per_cpu_init(void) > { > int i, cpus, cpunumber; > struct machine_specific *ms; > - struct syment *irq_sp, *curr_sp, *cpu_sp, *hardirq_stack_ptr_sp; > + struct syment *irq_sp, *curr_sp, *cpu_sp, *hardirq_stack_ptr_sp, *pcpu_sp; > ulong hardirq_stack_ptr; > ulong __per_cpu_load = 0; > + long hardirq_addr = 0, cpu_addr = 0, curr_addr = 0; > > ms = machdep->machspec; > > + pcpu_sp = per_cpu_symbol_search("pcpu_hot"); > + > hardirq_stack_ptr_sp = per_cpu_symbol_search("hardirq_stack_ptr"); > irq_sp = per_cpu_symbol_search("per_cpu__irq_stack_union"); > cpu_sp = per_cpu_symbol_search("per_cpu__cpu_number"); > @@ -1324,7 +1327,7 @@ x86_64_per_cpu_init(void) > return; > } > > - if (!cpu_sp || (!irq_sp && !hardirq_stack_ptr_sp)) > + if (!pcpu_sp && (!cpu_sp || (!irq_sp && !hardirq_stack_ptr_sp))) > return; > > if (MEMBER_EXISTS("irq_stack_union", "irq_stack")) > @@ -1337,10 +1340,21 @@ x86_64_per_cpu_init(void) > if (kernel_symbol_exists("__per_cpu_load")) > __per_cpu_load = symbol_value("__per_cpu_load"); > > + if (pcpu_sp) { > + hardirq_addr = pcpu_sp->value + MEMBER_OFFSET("pcpu_hot", "hardirq_stack_ptr"); > + cpu_addr = pcpu_sp->value + MEMBER_OFFSET("pcpu_hot", "cpu_number"); > + curr_addr = pcpu_sp->value + MEMBER_OFFSET("pcpu_hot", "current_task"); > + } else { > + if (hardirq_stack_ptr_sp) > + hardirq_addr = hardirq_stack_ptr_sp->value; > + cpu_addr = cpu_sp->value; > + curr_addr = curr_sp->value; > + } > + > for (i = cpus = 0; i < NR_CPUS; i++) { > if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load) > break; > - if (!readmem(cpu_sp->value + kt->__per_cpu_offset[i], > + if (!readmem(cpu_addr + kt->__per_cpu_offset[i], > KVADDR, &cpunumber, sizeof(int), > "cpu number (per_cpu)", QUIET|RETURN_ON_ERROR)) > break; > @@ -1349,8 +1363,8 @@ x86_64_per_cpu_init(void) > break; > cpus++; > > - if (hardirq_stack_ptr_sp) { > - if (!readmem(hardirq_stack_ptr_sp->value + kt->__per_cpu_offset[i], > + if (pcpu_sp || hardirq_stack_ptr_sp) { > + if (!readmem(hardirq_addr + kt->__per_cpu_offset[i], > KVADDR, &hardirq_stack_ptr, sizeof(void *), > "hardirq_stack_ptr (per_cpu)", QUIET|RETURN_ON_ERROR)) > continue; > @@ -1373,13 +1387,13 @@ x86_64_per_cpu_init(void) > else > kt->cpus = cpus; > > - if (DUMPFILE() && curr_sp) { > + if (DUMPFILE() && (pcpu_sp || curr_sp)) { > if ((ms->current = calloc(kt->cpus, sizeof(ulong))) == NULL) > error(FATAL, > "cannot calloc %d x86_64 current pointers!\n", > kt->cpus); > for (i = 0; i < kt->cpus; i++) > - if (!readmem(curr_sp->value + kt->__per_cpu_offset[i], > + if (!readmem(curr_addr + kt->__per_cpu_offset[i], > KVADDR, &ms->current[i], sizeof(ulong), > "current_task (per_cpu)", RETURN_ON_ERROR)) > continue; > @@ -5625,11 +5639,19 @@ x86_64_get_smp_cpus(void) > char *cpu_pda_buf; > ulong level4_pgt, cpu_pda_addr; > struct syment *sp; > - ulong __per_cpu_load = 0; > + ulong __per_cpu_load = 0, cpu_addr; > > if (!VALID_STRUCT(x8664_pda)) { > - if (!(sp = per_cpu_symbol_search("per_cpu__cpu_number")) || > - !(kt->flags & PER_CPU_OFF)) > + > + if (!(kt->flags & PER_CPU_OFF)) > + return 1; > + > + if ((sp = per_cpu_symbol_search("pcpu_hot")) && > + (cpu_addr = MEMBER_OFFSET("pcpu_hot", "cpu_number")) != INVALID_OFFSET) > + cpu_addr += sp->value; > + else if ((sp = per_cpu_symbol_search("per_cpu__cpu_number"))) > + cpu_addr = sp->value; > + else > return 1; > > if (kernel_symbol_exists("__per_cpu_load")) > @@ -5638,7 +5660,7 @@ x86_64_get_smp_cpus(void) > for (i = cpus = 0; i < NR_CPUS; i++) { > if (__per_cpu_load && kt->__per_cpu_offset[i] == __per_cpu_load) > break; > - if (!readmem(sp->value + kt->__per_cpu_offset[i], > + if (!readmem(cpu_addr + kt->__per_cpu_offset[i], > KVADDR, &cpunumber, sizeof(int), > "cpu number (per_cpu)", QUIET|RETURN_ON_ERROR)) > break; > -- > 2.31.1 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki