Re: [RFC PATCH 23/27] powerpc/64: system call implement the bulk of the logic in C
From: Nicholas Piggin <npiggin@gmail.com>
Date: 2019-10-02 03:13:02
Michal Suchánek's on September 23, 2019 10:47 pm:
On Sun, Sep 15, 2019 at 11:28:09AM +1000, Nicholas Piggin wrote:quoted
System call entry and particularly exit code is beyond the limit of what is reasonable to implement in asm. This conversion moves all conditional branches out of the asm code, except for the case that all GPRs should be restored at exit. Null syscall test is about 5% faster after this patch, because the exit work is handled under local_irq_disable, and the hard mask and pending interrupt replay is handled after that, which avoids games with MSR. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> v3: - Fix !KUAP build [mpe] - Fix BookE build/boot [mpe] - Don't trace irqs with MSR[RI]=0 - Don't allow syscall_exit_prepare to be ftraced, because function graph tracing which traces exits barfs after the IRQ state is prepared for kernel exit. - Fix BE syscall table to use normal function descriptors now that they are called from C. - Comment syscall_exit_prepare....quoted
-#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC_SPLPAR) -BEGIN_FW_FTR_SECTION - /* see if there are any DTL entries to process */ - ld r10,PACALPPACAPTR(r13) /* get ptr to VPA */ - ld r11,PACA_DTL_RIDX(r13) /* get log read index */ - addi r10,r10,LPPACA_DTLIDX - LDX_BE r10,0,r10 /* get log write index */ - cmpd r11,r10 - beq+ 33f - bl accumulate_stolen_time - REST_GPR(0,r1) - REST_4GPRS(3,r1) - REST_2GPRS(7,r1) - addi r9,r1,STACK_FRAME_OVERHEAD -33: -END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) -#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE && CONFIG_PPC_SPLPAR */...quoted
diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c new file mode 100644 index 000000000000..1d2529824588 --- /dev/null +++ b/arch/powerpc/kernel/syscall_64.c@@ -0,0 +1,195 @@ +#include <linux/err.h> +#include <asm/book3s/64/kup-radix.h> +#include <asm/cputime.h> +#include <asm/hw_irq.h> +#include <asm/kprobes.h> +#include <asm/paca.h> +#include <asm/ptrace.h> +#include <asm/reg.h> +#include <asm/signal.h> +#include <asm/switch_to.h> +#include <asm/syscall.h> +#include <asm/time.h> + +extern void __noreturn tabort_syscall(void); + +typedef long (*syscall_fn)(long, long, long, long, long, long); + +long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8, unsigned long r0, struct pt_regs *regs) +{ + unsigned long ti_flags; + syscall_fn f; + + BUG_ON(!(regs->msr & MSR_PR)); + + if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && + unlikely(regs->msr & MSR_TS_T)) + tabort_syscall(); + + account_cpu_user_entry(); + +#ifdef CONFIG_PPC_SPLPAR + if (IS_ENABLED(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && + firmware_has_feature(FW_FEATURE_SPLPAR)) { + struct lppaca *lp = get_lppaca(); + + if (unlikely(local_paca->dtl_ridx != lp->dtl_idx))sparse complains about this, and in time.c this it converted like this: if (unlikely(local_paca->dtl_ridx != be64_to_cpu(lp->dtl_idx))) The removed code has a LDX_BE there so there should be some conversion involved, right?
Ah yes, thanks good catch. Thanks, Nick