[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