[Crash-utility] [PATCH v2 4/6] ppc64: handle backtrace when CPU is in an emerency stack
Hari Bathini
hbathini at linux.ibm.com
Mon Jul 4 10:59:44 UTC 2022
On 04/07/22 2:09 pm, HAGIO KAZUHITO(萩尾 一仁) wrote:
> On 2022/07/04 14:25, Hari Bathini wrote:
>> A CPU could be in an emergency stack when it is running in real mode
>> or any special scenario like TM bad thing. Also, there are dedicated
>> emergency stacks for machine check and system reset interrupt. Right
>> now, no backtrace is provided if a CPU is in any of these stacks.
>> This change ensures backtrace is processed appropriately even when
>> a CPU is in any one of these emergency stacks. Also, if stack info
>> cannot be found, print that message always instead of only when
>> verbose logs are enabled.
>>
>> Signed-off-by: Hari Bathini <hbathini at linux.ibm.com>
>> ---
>>
>> Changes in v2:
>> * Avoid using variable length array for paca_ptrs.
>>
>>
>> defs.h | 12 ++++
>> ppc64.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
>> 2 files changed, 203 insertions(+), 12 deletions(-)
>>
>> diff --git a/defs.h b/defs.h
>> index d1d3ea9..9b1b69a 100644
>> --- a/defs.h
>> +++ b/defs.h
>> @@ -6288,6 +6288,13 @@ struct ppc64_elf_prstatus {
>>
>> #ifdef PPC64
>>
>> +enum emergency_stack_type {
>> + NONE_STACK = 0,
>> + EMERGENCY_STACK,
>> + NMI_EMERGENCY_STACK,
>> + MC_EMERGENCY_STACK
>> +};
>> +
>> struct ppc64_opal {
>> uint64_t base;
>> uint64_t entry;
>> @@ -6307,6 +6314,11 @@ struct machine_specific {
>> char *hwstackbuf;
>> uint hwstacksize;
>>
>> + /* Emergency stacks */
>> + ulong *emergency_sp;
>> + ulong *nmi_emergency_sp;
>> + ulong *mc_emergency_sp;
>> +
>> uint l4_index_size;
>> uint l3_index_size;
>> uint l2_index_size;
>> diff --git a/ppc64.c b/ppc64.c
>> index 0a3aa5f..8ea91c2 100644
>> --- a/ppc64.c
>> +++ b/ppc64.c
>> @@ -48,6 +48,10 @@ static ulong ppc64_get_stackbase(ulong);
>> static ulong ppc64_get_stacktop(ulong);
>> void ppc64_compiler_warning_stub(void);
>> static ulong ppc64_in_irqstack(ulong);
>> +static enum emergency_stack_type ppc64_in_emergency_stack(int cpu, ulong addr,
>> + bool verbose);
>> +static void ppc64_set_bt_emergency_stack(enum emergency_stack_type type,
>> + struct bt_info *bt);
>> static char * ppc64_check_eframe(struct ppc64_pt_regs *);
>> static void ppc64_print_eframe(char *, struct ppc64_pt_regs *,
>> struct bt_info *);
>> @@ -56,6 +60,7 @@ static int ppc64_paca_percpu_offset_init(int);
>> static void ppc64_init_cpu_info(void);
>> static int ppc64_get_cpu_map(void);
>> static void ppc64_clear_machdep_cache(void);
>> +static void ppc64_init_paca_info(void);
>> static void ppc64_vmemmap_init(void);
>> static int ppc64_get_kvaddr_ranges(struct vaddr_range *);
>> static uint get_ptetype(ulong pte);
>> @@ -692,6 +697,8 @@ ppc64_init(int when)
>> error(FATAL, "cannot malloc hwirqstack buffer space.");
>> }
>>
>> + ppc64_init_paca_info();
>> +
>> if (!machdep->hz) {
>> machdep->hz = HZ;
>> if (THIS_KERNEL_VERSION >= LINUX(2,6,0))
>> @@ -1204,6 +1211,70 @@ ppc64_kvtop(struct task_context *tc, ulong kvaddr,
>> return ppc64_vtop(kvaddr, (ulong *)vt->kernel_pgd[0], paddr, verbose);
>> }
>>
>> +static void
>> +ppc64_init_paca_info(void)
>> +{
>> + struct machine_specific *ms = machdep->machspec;
>> + ulong *paca_ptr;
>> + int i;
>> +
>> + if (!(paca_ptrs = (ulong *)calloc(kt->cpus, sizeof(ulong))))
>
> s/paca_ptrs/paca_ptr/
>
> ppc64.c: In function ‘ppc64_init_paca_info’:
> ppc64.c:1219:8: error: ‘paca_ptrs’ undeclared (first use in this function); did you mean ‘paca_ptr’?
> if (!(paca_ptrs = (ulong *)calloc(kt->cpus, sizeof(ulong))))
> ^~~~~~~~~
> paca_ptr
> ppc64.c:1219:8: note: each undeclared identifier is reported only once for each function it appears in
>
>> + error(FATAL, "cannot malloc paca pointers space.\n");
>> +
>> + /* Get paca pointers for all CPUs. */
>> + if (symbol_exists("paca_ptrs")) {
>> + ulong paca_loc;
>> +
>> + readmem(symbol_value("paca_ptrs"), KVADDR, &paca_loc, sizeof(void *),
>> + "paca double pointer", FAULT_ON_ERROR);
>> + readmem(paca_loc, KVADDR, paca_ptr, sizeof(void *) * kt->cpus,
>> + "paca pointers", FAULT_ON_ERROR);
>> + } else if (symbol_exists("paca") &&
>> + (get_symbol_type("paca", NULL, NULL) == TYPE_CODE_PTR)) {
>> + readmem(symbol_value("paca"), KVADDR, paca_ptr, sizeof(void *) * kt->cpus,
>> + "paca pointers", FAULT_ON_ERROR);
>> + } else {
>> + free(paca_ptrs);
>
> Ditto.
>
>> + return;
>> + }
>> +
>> + /* Initialize emergency stacks info. */
>> + if (MEMBER_EXISTS("paca_struct", "emergency_sp")) {
>> + ulong offset = MEMBER_OFFSET("paca_struct", "emergency_sp");
>> +
>> + if (!(ms->emergency_sp = (ulong *)calloc(kt->cpus, sizeof(ulong))))
>> + error(FATAL, "cannot malloc emergency stack space.\n");
>> + for (i = 0; i < kt->cpus; i++)
>> + readmem(paca_ptr[i] + offset, KVADDR, &ms->emergency_sp[i],
>> + sizeof(void *), "paca->emergency_sp",
>> + FAULT_ON_ERROR);
>> + }
>> +
>> + if (MEMBER_EXISTS("paca_struct", "nmi_emergency_sp")) {
>> + ulong offset = MEMBER_OFFSET("paca_struct", "nmi_emergency_sp");
>> +
>> + if (!(ms->nmi_emergency_sp = (ulong *)calloc(kt->cpus, sizeof(ulong))))
>> + error(FATAL, "cannot malloc NMI emergency stack space.\n");
>> + for (i = 0; i < kt->cpus; i++)
>> + readmem(paca_ptr[i] + offset, KVADDR, &ms->nmi_emergency_sp[i],
>> + sizeof(void *), "paca->nmi_emergency_sp",
>> + FAULT_ON_ERROR);
>> + }
>> +
>> + if (MEMBER_EXISTS("paca_struct", "mc_emergency_sp")) {
>> + ulong offset = MEMBER_OFFSET("paca_struct", "mc_emergency_sp");
>> +
>> + if (!(ms->mc_emergency_sp = (ulong *)calloc(kt->cpus, sizeof(ulong))))
>> + error(FATAL, "cannot malloc machine check emergency stack space.\n");
>> + for (i = 0; i < kt->cpus; i++)
>> + readmem(paca_ptr[i] + offset, KVADDR, &ms->mc_emergency_sp[i],
>> + sizeof(void *), "paca->mc_emergency_sp",
>> + FAULT_ON_ERROR);
>> + }
>> +
>> + free(paca_ptrs);
>
> Ditto.
>
> But these typos can be fixed when merging, no need to respin for this.
Also, just noticed a typo in patch subject as well..
s/emerency/emergency/
Thanks for taking care of this.
Thanks
Hari
More information about the Crash-utility
mailing list