10d1fb0a4SAlex Dewar // SPDX-License-Identifier: GPL-2.0
2e32dacb9SJeff Dike /*
3ba180fd4SJeff Dike * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4e32dacb9SJeff Dike */
5e32dacb9SJeff Dike
637185b33SAl Viro #include <linux/kernel.h>
737185b33SAl Viro #include <linux/ptrace.h>
8c50b4659SMickaël Salaün #include <linux/seccomp.h>
937185b33SAl Viro #include <kern_util.h>
1037185b33SAl Viro #include <sysdep/ptrace.h>
11e04c989eSMickaël Salaün #include <sysdep/ptrace_user.h>
1237185b33SAl Viro #include <sysdep/syscalls.h>
13f185063bSJohannes Berg #include <linux/time-internal.h>
14e6da5df0SJohannes Berg #include <asm/unistd.h>
15e32dacb9SJeff Dike
handle_syscall(struct uml_pt_regs * r)1677bf4400SJeff Dike void handle_syscall(struct uml_pt_regs *r)
17e32dacb9SJeff Dike {
18e32dacb9SJeff Dike struct pt_regs *regs = container_of(r, struct pt_regs, regs);
19e32dacb9SJeff Dike int syscall;
20e32dacb9SJeff Dike
2106503870SJohannes Berg /*
2206503870SJohannes Berg * If we have infinite CPU resources, then make every syscall also a
2306503870SJohannes Berg * preemption point, since we don't have any other preemption in this
2406503870SJohannes Berg * case, and kernel threads would basically never run until userspace
2506503870SJohannes Berg * went to sleep, even if said userspace interacts with the kernel in
2606503870SJohannes Berg * various ways.
2706503870SJohannes Berg */
2888ce6424SJohannes Berg if (time_travel_mode == TT_MODE_INFCPU ||
2988ce6424SJohannes Berg time_travel_mode == TT_MODE_EXTERNAL)
3006503870SJohannes Berg schedule();
3106503870SJohannes Berg
32e04c989eSMickaël Salaün /* Initialize the syscall number and default return value. */
33e04c989eSMickaël Salaün UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
34e04c989eSMickaël Salaün PT_REGS_SET_SYSCALL_RETURN(regs, -ENOSYS);
35e04c989eSMickaël Salaün
3626703c63SKees Cook if (syscall_trace_enter(regs))
37972939e2SMickaël Salaün goto out;
38c50b4659SMickaël Salaün
3926703c63SKees Cook /* Do the seccomp check after ptrace; failures should be fast. */
40fefad9efSChristian Brauner if (secure_computing() == -1)
41972939e2SMickaël Salaün goto out;
42e32dacb9SJeff Dike
43e04c989eSMickaël Salaün syscall = UPT_SYSCALL_NR(r);
44*49f731f1SMasahiro Yamada if (syscall >= 0 && syscall < __NR_syscalls)
45e04c989eSMickaël Salaün PT_REGS_SET_SYSCALL_RETURN(regs,
46e04c989eSMickaël Salaün EXECUTE_SYSCALL(syscall, regs));
47e32dacb9SJeff Dike
48972939e2SMickaël Salaün out:
491bfa2317SAl Viro syscall_trace_leave(regs);
50e32dacb9SJeff Dike }
51