Michal Suchánek's on September 23, 2019 10:47 pm: > On Sun, Sep 15, 2019 at 11:28:09AM +1000, Nicholas Piggin wrote: >> 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 <npig...@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. > ... >> -#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 */ > ... >> 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