[RFC PATCH 23/27] powerpc/64: system call implement the bulk of the logic in C
Nicholas Piggin
npiggin at gmail.com
Wed Oct 2 13:10:56 AEST 2019
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 <npiggin at 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
More information about the Linuxppc-dev
mailing list