asmlinkage void el0_svc_handler(struct pt_regs
*
regs)
{
sve_user_discard();
el0_svc_common(regs, regs
-
>regs[
8
], __NR_syscalls, sys_call_table);
}
static void el0_svc_common(struct pt_regs
*
regs,
int
scno,
int
sc_nr,
const syscall_fn_t syscall_table[])
{
unsigned
long
flags
=
current_thread_info()
-
>flags;
regs
-
>orig_x0
=
regs
-
>regs[
0
];
regs
-
>syscallno
=
scno;
...
invoke_syscall(regs, scno, sc_nr, syscall_table);
...
}
static
long
__invoke_syscall(struct pt_regs
*
regs, syscall_fn_t syscall_fn)
{
return
syscall_fn(regs);
}
static void invoke_syscall(struct pt_regs
*
regs, unsigned
int
scno,
unsigned
int
sc_nr,
const syscall_fn_t syscall_table[])
{
long
ret;
if
(scno < sc_nr) {
syscall_fn_t syscall_fn;
syscall_fn
=
syscall_table[array_index_nospec(scno, sc_nr)];
ret
=
__invoke_syscall(regs, syscall_fn);
}
else
{
ret
=
do_ni_syscall(regs, scno);
}
regs
-
>regs[
0
]
=
ret;
}