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(a)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