powerpc: Change system_call_exception calling convention
authorRohan McLure <rmclure@linux.ibm.com>
Wed, 21 Sep 2022 06:56:00 +0000 (16:56 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 28 Sep 2022 09:22:09 +0000 (19:22 +1000)
Change system_call_exception arguments to pass a pointer to a stack
frame container caller state, as well as the original r0, which
determines the number of the syscall. This has been observed to yield
improved performance to passing them by registers, circumventing the
need to allocate a stack frame.

Signed-off-by: Rohan McLure <rmclure@linux.ibm.com>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Retain clearing of high bits of args for compat tasks]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220921065605.1051927-21-rmclure@linux.ibm.com
arch/powerpc/include/asm/interrupt.h
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/interrupt_64.S
arch/powerpc/kernel/syscall.c

index 84a1cdc..0d3405b 100644 (file)
@@ -665,8 +665,7 @@ static inline void interrupt_cond_local_irq_enable(struct pt_regs *regs)
                local_irq_enable();
 }
 
-long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8,
-                          unsigned long r0, struct pt_regs *regs);
+long system_call_exception(struct pt_regs *regs, unsigned long r0);
 notrace unsigned long syscall_exit_prepare(unsigned long r3, struct pt_regs *regs, long scv);
 notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs);
 notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs);
index e3d43b6..55fcc70 100644 (file)
@@ -122,9 +122,9 @@ transfer_to_syscall:
        SAVE_NVGPRS(r1)
        kuep_lock
 
-       /* Calling convention has r9 = orig r0, r10 = regs */
-       addi    r10,r1,STACK_FRAME_OVERHEAD
-       mr      r9,r0
+       /* Calling convention has r3 = regs, r4 = orig r0 */
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       mr      r4,r0
        bl      system_call_exception
 
 ret_from_syscall:
index 931f984..90dbd6a 100644 (file)
@@ -60,7 +60,7 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
        ld      r2,PACATOC(r13)
        mfcr    r12
        li      r11,0
-       /* Can we avoid saving r3-r8 in common case? */
+       /* Save syscall parameters in r3-r8 */
        SAVE_GPRS(3, 8, r1)
        /* Zero r9-r12, this should only be required when restoring all GPRs */
        std     r11,GPR9(r1)
@@ -77,9 +77,11 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
        std     r11,_TRAP(r1)
        std     r12,_CCR(r1)
        std     r3,ORIG_GPR3(r1)
-       addi    r10,r1,STACK_FRAME_OVERHEAD
+       /* Calling convention has r3 = regs, r4 = orig r0 */
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       mr      r4,r0
        ld      r11,exception_marker@toc(r2)
-       std     r11,-16(r10)            /* "regshere" marker */
+       std     r11,-16(r3)             /* "regshere" marker */
 
 BEGIN_FTR_SECTION
        HMT_MEDIUM
@@ -94,8 +96,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
         * but this is the best we can do.
         */
 
-       /* Calling convention has r9 = orig r0, r10 = regs */
-       mr      r9,r0
        bl      system_call_exception
 
 .Lsyscall_vectored_\name\()_exit:
@@ -227,7 +227,7 @@ END_BTB_FLUSH_SECTION
        ld      r2,PACATOC(r13)
        mfcr    r12
        li      r11,0
-       /* Can we avoid saving r3-r8 in common case? */
+       /* Save syscall parameters in r3-r8 */
        SAVE_GPRS(3, 8, r1)
        /* Zero r9-r12, this should only be required when restoring all GPRs */
        std     r11,GPR9(r1)
@@ -250,9 +250,11 @@ END_BTB_FLUSH_SECTION
        std     r11,_TRAP(r1)
        std     r12,_CCR(r1)
        std     r3,ORIG_GPR3(r1)
-       addi    r10,r1,STACK_FRAME_OVERHEAD
+       /* Calling convention has r3 = regs, r4 = orig r0 */
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       mr      r4,r0
        ld      r11,exception_marker@toc(r2)
-       std     r11,-16(r10)            /* "regshere" marker */
+       std     r11,-16(r3)             /* "regshere" marker */
 
 #ifdef CONFIG_PPC_BOOK3S
        li      r11,1
@@ -273,8 +275,6 @@ END_BTB_FLUSH_SECTION
        wrteei  1
 #endif
 
-       /* Calling convention has r9 = orig r0, r10 = regs */
-       mr      r9,r0
        bl      system_call_exception
 
 .Lsyscall_exit:
index 9875486..2c002cb 100644 (file)
 
 
 /* Has to run notrace because it is entered not completely "reconciled" */
-notrace long system_call_exception(long r3, long r4, long r5,
-                                  long r6, long r7, long r8,
-                                  unsigned long r0, struct pt_regs *regs)
+notrace long system_call_exception(struct pt_regs *regs, unsigned long r0)
 {
+       unsigned long r3, r4, r5, r6, r7, r8;
        long ret;
        syscall_fn f;
 
@@ -136,12 +135,6 @@ notrace long system_call_exception(long r3, long r4, long r5,
                r0 = do_syscall_trace_enter(regs);
                if (unlikely(r0 >= NR_syscalls))
                        return regs->gpr[3];
-               r3 = regs->gpr[3];
-               r4 = regs->gpr[4];
-               r5 = regs->gpr[5];
-               r6 = regs->gpr[6];
-               r7 = regs->gpr[7];
-               r8 = regs->gpr[8];
 
        } else if (unlikely(r0 >= NR_syscalls)) {
                if (unlikely(trap_is_unsupported_scv(regs))) {
@@ -152,6 +145,13 @@ notrace long system_call_exception(long r3, long r4, long r5,
                return -ENOSYS;
        }
 
+       r3 = regs->gpr[3];
+       r4 = regs->gpr[4];
+       r5 = regs->gpr[5];
+       r6 = regs->gpr[6];
+       r7 = regs->gpr[7];
+       r8 = regs->gpr[8];
+
        /* May be faster to do array_index_nospec? */
        barrier_nospec();