Commit 88043cc6 authored by Philippe Gerum's avatar Philippe Gerum
Browse files

arm64/ipipe: implement fast system call logic

The fast system call logic routes requests directly to the head domain
without going through the pipeline for clients supporting the feature,
such as Xenomai.
parent c55bdaec
......@@ -54,3 +54,5 @@
#endif
#define NR_syscalls (__NR_syscalls)
#define __ARM_ipipe_syscall 0x10000000
......@@ -646,11 +646,6 @@ ret_from_exception:
tst x0, #_TIP_HEAD
b.eq ret_to_user_noirq
kernel_exit 0, ret = 0
ipipe_fast_sysret:
disable_irq
ldr x1, [tsk, #TI_FLAGS]
enable_step_tsk x1, x2
kernel_exit 0, ret = 1
#endif /* CONFIG_IPIPE */
/*
* This is the fast syscall return path. We do as little as possible here,
......@@ -723,18 +718,50 @@ el0_svc_naked: // compat entry point
enable_dbg_and_irq
#ifdef CONFIG_IPIPE
ldr x16, [tsk, #TI_IPIPE]
tst scno, __ARM_ipipe_syscall
b.eq fastcall_bypass
tst x16, #_TIP_HEAD
b.eq fastcall_bypass
mov x0, sp
bl __ipipe_syscall_root
get_thread_info tsk
bl ipipe_fastcall_hook
cmp w0, #0
b.lt no_fastcall
ldr x16, [tsk, #TI_IPIPE]
tst x16, #_TIP_HEAD
b.ne fastcall_exit
bl __ipipe_root_sync
fastcall_tail:
ldr x0, [sp, #S_X0]
blt ipipe_fast_sysret
bgt ret_fast_syscall
/*
* Save/restore needed during syscalls. Restore syscall arguments from
* the values already saved on stack during kernel_entry.
*/
ldr x1, [sp, #S_X1]
b ret_fast_syscall
fastcall_exit:
tst x16, #_TIP_MAYDAY
b.eq fastcall_notail
mov x0, sp
bl __ipipe_call_mayday
fastcall_notail:
ldr x0, [sp, #S_X0]
disable_irq
ldr x1, [tsk, #TI_FLAGS]
enable_step_tsk x1, x2
kernel_exit 0, ret = 1
no_fastcall:
ldr x16, [tsk, #TI_IPIPE]
fastcall_bypass:
tst x16, #_TIP_NOTIFY
b.ne syscall_pipeline
tst scno, __ARM_ipipe_syscall
b.eq regular_syscall
syscall_pipeline:
mov x0, sp
bl __ipipe_notify_syscall
ldr x16, [tsk, #TI_IPIPE]
tst x16, #_TIP_HEAD
b.ne fastcall_notail
cmp w0, #0
b.ne fastcall_tail
regular_syscall:
ldp x0, x1, [sp, #S_X0]
ldp x2, x3, [sp, #S_X2]
ldp x4, x5, [sp, #S_X4]
ldp x6, x7, [sp, #S_X6]
......
......@@ -307,50 +307,6 @@ asmlinkage int __ipipe_check_root_interruptible(void)
return __ipipe_root_p && !irqs_disabled();
}
asmlinkage int __ipipe_syscall_root(struct pt_regs *regs)
{
struct task_struct *const task = current;
struct ipipe_percpu_domain_data *p;
int ret;
#ifdef CONFIG_IPIPE_DEBUG_INTERNAL
WARN_ON_ONCE(hard_irqs_disabled());
#endif
/*
* This routine either returns:
* 0 -- if the syscall is to be passed to Linux;
* <0 -- if the syscall should not be passed to Linux, and no
* tail work should be performed;
* >0 -- if the syscall should not be passed to Linux but the
* tail work has to be performed (for handling signals etc).
*/
if (!__ipipe_syscall_watched_p(task, regs->syscallno))
return 0;
ret = __ipipe_notify_syscall(regs);
hard_local_irq_disable();
if (ipipe_test_thread_flag(TIP_MAYDAY)) {
ipipe_clear_thread_flag(TIP_MAYDAY);
__ipipe_notify_trap(IPIPE_TRAP_MAYDAY, regs);
}
if (!__ipipe_root_p)
ret = -1;
else {
p = ipipe_this_cpu_root_context();
if (__ipipe_ipending_p(p))
__ipipe_sync_stage();
}
hard_local_irq_enable();
return ret;
}
void __ipipe_exit_irq(struct pt_regs *regs)
{
/*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment