Le 14/12/2025 à 14:02, Mukesh Kumar Chaurasiya a écrit :
From: Mukesh Kumar Chaurasiya <[email protected]>

Add a new field `exit_flags` in the pt_regs structure. This field will hold
the flags set during interrupt or syscall execution that are required during
exit to user mode.

Specifically, the `TIF_RESTOREALL` flag, stored in this field, helps the
exit routine determine if any NVGPRs were modified and need to be restored
before returning to userspace.

In the current implementation we did our best to keep this information in a local var for performance reasons. Have you assessed the performance impact of going through the stack for that ?


This addition ensures a clean and architecture-specific mechanism to track
per-syscall or per-interrupt state transitions related to register restore.

Changes:
  - Add `exit_flags` and `__pt_regs_pad` to maintain 16-byte stack alignment
  - Update asm-offsets.c and ptrace.c for offset and validation
  - Update PT_* constants in uapi header to reflect the new layout

Signed-off-by: Mukesh Kumar Chaurasiya <[email protected]>
---
  arch/powerpc/include/asm/ptrace.h      |  3 +++
  arch/powerpc/include/uapi/asm/ptrace.h | 14 +++++++++-----
  arch/powerpc/kernel/asm-offsets.c      |  1 +
  arch/powerpc/kernel/ptrace/ptrace.c    |  1 +
  4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index 94aa1de2b06e..3af8a5898fe3 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -53,6 +53,9 @@ struct pt_regs
                                unsigned long esr;
                        };
                        unsigned long result;
+                       unsigned long exit_flags;
+                       /* Maintain 16 byte interrupt stack alignment */

On powerpc/32, one 'long' is 4 bytes not 8.

+                       unsigned long __pt_regs_pad[1];
                };
        };
  #if defined(CONFIG_PPC64) || defined(CONFIG_PPC_KUAP)
diff --git a/arch/powerpc/include/uapi/asm/ptrace.h 
b/arch/powerpc/include/uapi/asm/ptrace.h
index 01e630149d48..de56b216c9c5 100644
--- a/arch/powerpc/include/uapi/asm/ptrace.h
+++ b/arch/powerpc/include/uapi/asm/ptrace.h
@@ -55,6 +55,8 @@ struct pt_regs
        unsigned long dar;              /* Fault registers */
        unsigned long dsisr;            /* on 4xx/Book-E used for ESR */
        unsigned long result;           /* Result of a system call */
+       unsigned long exit_flags;       /* System call exit flags */
+       unsigned long __pt_regs_pad[1]; /* Maintain 16 byte interrupt stack 
alignment */

On powerpc/32, one 'long' is 4 bytes not 8.

  };
#endif /* __ASSEMBLER__ */
@@ -114,10 +116,12 @@ struct pt_regs
  #define PT_DAR        41
  #define PT_DSISR 42
  #define PT_RESULT 43
-#define PT_DSCR 44
-#define PT_REGS_COUNT 44
+#define PT_EXIT_FLAGS 44
+#define PT_PAD 45
+#define PT_DSCR 46
+#define PT_REGS_COUNT 46
-#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
+#define PT_FPR0        (PT_REGS_COUNT + 4)     /* each FP reg occupies 2 slots 
in this space */
#ifndef __powerpc64__ @@ -129,7 +133,7 @@ struct pt_regs
  #define PT_FPSCR (PT_FPR0 + 32)       /* each FP reg occupies 1 slot in 
64-bit space */
-#define PT_VR0 82 /* each Vector reg occupies 2 slots in 64-bit */
+#define PT_VR0 (PT_FPSCR + 2)  /* <82> each Vector reg occupies 2 slots in 
64-bit */
  #define PT_VSCR (PT_VR0 + 32*2 + 1)
  #define PT_VRSAVE (PT_VR0 + 33*2)
@@ -137,7 +141,7 @@ struct pt_regs
  /*
   * Only store first 32 VSRs here. The second 32 VSRs in VR0-31
   */
-#define PT_VSR0 150    /* each VSR reg occupies 2 slots in 64-bit */
+#define PT_VSR0        (PT_VRSAVE + 2) /* each VSR reg occupies 2 slots in 
64-bit */
  #define PT_VSR31 (PT_VSR0 + 2*31)
  #endif /* __powerpc64__ */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index a4bc80b30410..c0bb09f1db78 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -292,6 +292,7 @@ int main(void)
        STACK_PT_REGS_OFFSET(_ESR, esr);
        STACK_PT_REGS_OFFSET(ORIG_GPR3, orig_gpr3);
        STACK_PT_REGS_OFFSET(RESULT, result);
+       STACK_PT_REGS_OFFSET(EXIT_FLAGS, exit_flags);

Where is that used ?

        STACK_PT_REGS_OFFSET(_TRAP, trap);
  #ifdef CONFIG_PPC64
        STACK_PT_REGS_OFFSET(SOFTE, softe);
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c 
b/arch/powerpc/kernel/ptrace/ptrace.c
index c6997df63287..2134b6d155ff 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -432,6 +432,7 @@ void __init pt_regs_check(void)
        CHECK_REG(PT_DAR, dar);
        CHECK_REG(PT_DSISR, dsisr);
        CHECK_REG(PT_RESULT, result);
+       CHECK_REG(PT_EXIT_FLAGS, exit_flags);
        #undef CHECK_REG
BUILD_BUG_ON(PT_REGS_COUNT != sizeof(struct user_pt_regs) / sizeof(unsigned long));


Reply via email to