[RFC PATCH] powerpc: show registers when unwinding interrupt frames
Christophe Leroy
christophe.leroy at csgroup.eu
Sat Nov 7 21:49:27 AEDT 2020
Le 07/11/2020 à 03:33, Nicholas Piggin a écrit :
> It's often useful to know the register state for interrupts in
> the stack frame. In the below example (with this patch applied),
> the important information is the state of the page fault.
>
> A blatant case like this probably rather should have the page
> fault regs passed down to the warning, but quite often there are
> less obvious cases where an interrupt shows up that might give
> some more clues.
I like it.
I was wondering about interrupts that do not save NV registers, but that seems to be handled:
[ 0.455489] --- interrupt: 301 at cmpxchg_futex_value_locked+0x2c/0x58
[ 0.461886] NIP: c0089c08 LR: c0755df0 CTR: c02e59a4
[ 0.466889] REGS: c9023db0 TRAP: 0301 Not tainted (5.10.0-rc2-s3k-dev-01371-gfb45a2414e96-dirty)
[ 0.475815] MSR: 00009032 <EE,ME,IR,DR,RI> CR: 28000244 XER: 00000000
[ 0.482450] DAR: 00000000 DSISR: c0000000
[ 0.482450] GPR00: c0755dc8 c9023e68 c2100000 c9023e78 00000000 00000000 00000000 00000000
[ 0.482450] GPR08: 00001032 00000000 80000000 00000003 42000242
[ 0.500988] NIP [c0089c08] cmpxchg_futex_value_locked+0x2c/0x58
[ 0.506842] LR [c0755df0] futex_init+0x74/0xd0
[ 0.511194] --- interrupt: 301
Christophe
>
> The downside is longer and more complex bug output.
>
> Bug: Write fault blocked by AMR!
> WARNING: CPU: 0 PID: 72 at arch/powerpc/include/asm/book3s/64/kup-radix.h:164 __do_page_fault+0x880/0xa90
> Modules linked in:
> CPU: 0 PID: 72 Comm: systemd-gpt-aut Not tainted
> NIP: c00000000006e2f0 LR: c00000000006e2ec CTR: 0000000000000000
> REGS: c00000000a4f3420 TRAP: 0700
> MSR: 8000000000021033 <SF,ME,IR,DR,RI,LE> CR: 28002840 XER: 20040000
> CFAR: c000000000128be0 IRQMASK: 3
> GPR00: c00000000006e2ec c00000000a4f36c0 c0000000014f0700 0000000000000020
> GPR04: 0000000000000001 c000000001290f50 0000000000000001 c000000001290f80
> GPR08: c000000001612b08 0000000000000000 0000000000000000 00000000ffffe0f7
> GPR12: 0000000048002840 c0000000016e0000 c00c000000021c80 c000000000fd6f60
> GPR16: 0000000000000000 c00000000a104698 0000000000000003 c0000000087f0000
> GPR20: 0000000000000100 c0000000070330b8 0000000000000000 0000000000000004
> GPR24: 0000000002000000 0000000000000300 0000000002000000 c00000000a5b0c00
> GPR28: 0000000000000000 000000000a000000 00007fffb2a90038 c00000000a4f3820
> NIP [c00000000006e2f0] __do_page_fault+0x880/0xa90
> LR [c00000000006e2ec] __do_page_fault+0x87c/0xa90
> Call Trace:
> [c00000000a4f36c0] [c00000000006e2ec] __do_page_fault+0x87c/0xa90 (unreliable)
> [c00000000a4f3780] [c000000000e1c034] do_page_fault+0x34/0x90
> [c00000000a4f37b0] [c000000000008908] data_access_common_virt+0x158/0x1b0
> --- interrupt: 300 at __copy_tofrom_user_base+0x9c/0x5a4
> NIP: c00000000009b028 LR: c000000000802978 CTR: 0000000000000800
> REGS: c00000000a4f3820 TRAP: 0300
> MSR: 800000000280b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE> CR: 24004840 XER: 00000000
> CFAR: c00000000009aff4 DAR: 00007fffb2a90038 DSISR: 0a000000 IRQMASK: 0
> GPR00: 0000000000000000 c00000000a4f3ac0 c0000000014f0700 00007fffb2a90028
> GPR04: c000000008720010 0000000000010000 0000000000000000 0000000000000000
> GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000001
> GPR12: 0000000000004000 c0000000016e0000 c00c000000021c80 c000000000fd6f60
> GPR16: 0000000000000000 c00000000a104698 0000000000000003 c0000000087f0000
> GPR20: 0000000000000100 c0000000070330b8 0000000000000000 0000000000000004
> GPR24: c00000000a4f3c80 c000000008720000 0000000000010000 0000000000000000
> GPR28: 0000000000010000 0000000008720000 0000000000010000 c000000001515b98
> NIP [c00000000009b028] __copy_tofrom_user_base+0x9c/0x5a4
> LR [c000000000802978] copyout+0x68/0xc0
> --- interrupt: 300
> [c00000000a4f3af0] [c0000000008074b8] copy_page_to_iter+0x188/0x540
> [c00000000a4f3b50] [c00000000035c678] generic_file_buffered_read+0x358/0xd80
> [c00000000a4f3c40] [c0000000004c1e90] blkdev_read_iter+0x50/0x80
> [c00000000a4f3c60] [c00000000045733c] new_sync_read+0x12c/0x1c0
> [c00000000a4f3d00] [c00000000045a1f0] vfs_read+0x1d0/0x240
> [c00000000a4f3d50] [c00000000045a7f4] ksys_read+0x84/0x140
> [c00000000a4f3da0] [c000000000033a60] system_call_exception+0x100/0x280
> [c00000000a4f3e10] [c00000000000c508] system_call_common+0xf8/0x2f8
> Instruction dump:
> eae10078 3be0000b 4bfff890 60420000 792917e1 4182ff18 3c82ffab 3884a5e0
> 3c62ffab 3863a6e8 480ba891 60000000 <0fe00000> 3be0000b 4bfff860 e93c0938
>
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
> ---
> arch/powerpc/kernel/process.c | 20 ++++++++++++++------
> 1 file changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
> index ea36a29c8b01..799f00b32f74 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -1475,12 +1475,10 @@ static void print_msr_bits(unsigned long val)
> #define LAST_VOLATILE 12
> #endif
>
> -void show_regs(struct pt_regs * regs)
> +static void __show_regs(struct pt_regs *regs)
> {
> int i, trap;
>
> - show_regs_print_info(KERN_DEFAULT);
> -
> printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
> regs->nip, regs->link, regs->ctr);
> printk("REGS: %px TRAP: %04lx %s (%s)\n",
> @@ -1522,6 +1520,12 @@ void show_regs(struct pt_regs * regs)
> printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip);
> printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link);
> }
> +}
> +
> +void show_regs(struct pt_regs *regs)
> +{
> + show_regs_print_info(KERN_DEFAULT);
> + __show_regs(regs);
> show_stack(current, (unsigned long *) regs->gpr[1], KERN_DEFAULT);
> if (!user_mode(regs))
> show_instructions(regs);
> @@ -2192,10 +2196,14 @@ void show_stack(struct task_struct *tsk, unsigned long *stack,
> && stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
> struct pt_regs *regs = (struct pt_regs *)
> (sp + STACK_FRAME_OVERHEAD);
> +
> lr = regs->link;
> - printk("%s--- interrupt: %lx at %pS\n LR = %pS\n",
> - loglvl, regs->trap,
> - (void *)regs->nip, (void *)lr);
> + printk("%s--- interrupt: %lx at %pS\n",
> + loglvl, regs->trap, (void *)regs->nip);
> + __show_regs(regs);
> + printk("%s--- interrupt: %lx\n",
> + loglvl, regs->trap);
> +
> firstframe = 1;
> }
>
>
More information about the Linuxppc-dev
mailing list