Patch "powerpc: update ppc_save_regs to save current r1 in pt_regs" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    powerpc: update ppc_save_regs to save current r1 in pt_regs

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     powerpc-update-ppc_save_regs-to-save-current-r1-in-p.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit fbedf5f57c6b22bf218d6ef0a5bcbc6bdd8c01b8
Author: Aditya Gupta <adityag@xxxxxxxxxxxxx>
Date:   Thu Jun 15 14:40:47 2023 +0530

    powerpc: update ppc_save_regs to save current r1 in pt_regs
    
    [ Upstream commit b684c09f09e7a6af3794d4233ef785819e72db79 ]
    
    ppc_save_regs() skips one stack frame while saving the CPU register states.
    Instead of saving current R1, it pulls the previous stack frame pointer.
    
    When vmcores caused by direct panic call (such as `echo c >
    /proc/sysrq-trigger`), are debugged with gdb, gdb fails to show the
    backtrace correctly. On further analysis, it was found that it was because
    of mismatch between r1 and NIP.
    
    GDB uses NIP to get current function symbol and uses corresponding debug
    info of that function to unwind previous frames, but due to the
    mismatching r1 and NIP, the unwinding does not work, and it fails to
    unwind to the 2nd frame and hence does not show the backtrace.
    
    GDB backtrace with vmcore of kernel without this patch:
    
    ---------
    (gdb) bt
     #0  0xc0000000002a53e8 in crash_setup_regs (oldregs=<optimized out>,
        newregs=0xc000000004f8f8d8) at ./arch/powerpc/include/asm/kexec.h:69
     #1  __crash_kexec (regs=<optimized out>) at kernel/kexec_core.c:974
     #2  0x0000000000000063 in ?? ()
     #3  0xc000000003579320 in ?? ()
    ---------
    
    Further analysis revealed that the mismatch occurred because
    "ppc_save_regs" was saving the previous stack's SP instead of the current
    r1. This patch fixes this by storing current r1 in the saved pt_regs.
    
    GDB backtrace with vmcore of patched kernel:
    
    --------
    (gdb) bt
     #0  0xc0000000002a53e8 in crash_setup_regs (oldregs=0x0, newregs=0xc00000000670b8d8)
        at ./arch/powerpc/include/asm/kexec.h:69
     #1  __crash_kexec (regs=regs@entry=0x0) at kernel/kexec_core.c:974
     #2  0xc000000000168918 in panic (fmt=fmt@entry=0xc000000001654a60 "sysrq triggered crash\n")
        at kernel/panic.c:358
     #3  0xc000000000b735f8 in sysrq_handle_crash (key=<optimized out>) at drivers/tty/sysrq.c:155
     #4  0xc000000000b742cc in __handle_sysrq (key=key@entry=99, check_mask=check_mask@entry=false)
        at drivers/tty/sysrq.c:602
     #5  0xc000000000b7506c in write_sysrq_trigger (file=<optimized out>, buf=<optimized out>,
        count=2, ppos=<optimized out>) at drivers/tty/sysrq.c:1163
     #6  0xc00000000069a7bc in pde_write (ppos=<optimized out>, count=<optimized out>,
        buf=<optimized out>, file=<optimized out>, pde=0xc00000000362cb40) at fs/proc/inode.c:340
     #7  proc_reg_write (file=<optimized out>, buf=<optimized out>, count=<optimized out>,
        ppos=<optimized out>) at fs/proc/inode.c:352
     #8  0xc0000000005b3bbc in vfs_write (file=file@entry=0xc000000006aa6b00,
        buf=buf@entry=0x61f498b4f60 <error: Cannot access memory at address 0x61f498b4f60>,
        count=count@entry=2, pos=pos@entry=0xc00000000670bda0) at fs/read_write.c:582
     #9  0xc0000000005b4264 in ksys_write (fd=<optimized out>,
        buf=0x61f498b4f60 <error: Cannot access memory at address 0x61f498b4f60>, count=2)
        at fs/read_write.c:637
     #10 0xc00000000002ea2c in system_call_exception (regs=0xc00000000670be80, r0=<optimized out>)
        at arch/powerpc/kernel/syscall.c:171
     #11 0xc00000000000c270 in system_call_vectored_common ()
        at arch/powerpc/kernel/interrupt_64.S:192
    --------
    
    Nick adds:
      So this now saves regs as though it was an interrupt taken in the
      caller, at the instruction after the call to ppc_save_regs, whereas
      previously the NIP was there, but R1 came from the caller's caller and
      that mismatch is what causes gdb's dwarf unwinder to go haywire.
    
    Signed-off-by: Aditya Gupta <adityag@xxxxxxxxxxxxx>
    Fixes: d16a58f8854b1 ("powerpc: Improve ppc_save_regs()")
    Reivewed-by: Nicholas Piggin <npiggin@xxxxxxxxx>
    Signed-off-by: Michael Ellerman <mpe@xxxxxxxxxxxxxx>
    Link: https://msgid.link/20230615091047.90433-1-adityag@xxxxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S
index 6e86f3bf46735..235ae24284519 100644
--- a/arch/powerpc/kernel/ppc_save_regs.S
+++ b/arch/powerpc/kernel/ppc_save_regs.S
@@ -31,10 +31,10 @@ _GLOBAL(ppc_save_regs)
 	lbz	r0,PACAIRQSOFTMASK(r13)
 	PPC_STL	r0,SOFTE(r3)
 #endif
-	/* go up one stack frame for SP */
-	PPC_LL	r4,0(r1)
-	PPC_STL	r4,GPR1(r3)
+	/* store current SP */
+	PPC_STL	r1,GPR1(r3)
 	/* get caller's LR */
+	PPC_LL	r4,0(r1)
 	PPC_LL	r0,LRSAVE(r4)
 	PPC_STL	r0,_LINK(r3)
 	mflr	r0



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux