Line data Source code
1 0 : /*
2 : * Copyright (c) 2017, Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 :
8 : #ifndef ZEPHYR_INCLUDE_SYSCALL_H_
9 : #define ZEPHYR_INCLUDE_SYSCALL_H_
10 :
11 : #include <zephyr/syscall_list.h>
12 : #include <zephyr/arch/syscall.h>
13 : #include <stdbool.h>
14 :
15 : #ifndef _ASMLANGUAGE
16 : #include <zephyr/types.h>
17 : #include <zephyr/linker/sections.h>
18 :
19 : #ifdef __cplusplus
20 : extern "C" {
21 : #endif
22 :
23 : /*
24 : * System Call Declaration macros
25 : *
26 : * These macros are used in public header files to declare system calls.
27 : * They generate inline functions which have different implementations
28 : * depending on the current compilation context:
29 : *
30 : * - Kernel-only code, or CONFIG_USERSPACE disabled, these inlines will
31 : * directly call the implementation
32 : * - User-only code, these inlines will marshal parameters and elevate
33 : * privileges
34 : * - Mixed or indeterminate code, these inlines will do a runtime check
35 : * to determine what course of action is needed.
36 : *
37 : * All system calls require a verifier function and an implementation
38 : * function. These must follow a naming convention. For a system call
39 : * named k_foo():
40 : *
41 : * - The handler function will be named z_vrfy_k_foo(). Handler
42 : * functions have the same type signature as the wrapped call,
43 : * verify arguments passed up from userspace, and call the
44 : * implementation function. See documentation for that typedef for
45 : * more information. - The implementation function will be named
46 : * z_impl_k_foo(). This is the actual implementation of the system
47 : * call.
48 : */
49 :
50 : /**
51 : * @typedef _k_syscall_handler_t
52 : * @brief System call handler function type
53 : *
54 : * These are kernel-side skeleton functions for system calls. They are
55 : * necessary to sanitize the arguments passed into the system call:
56 : *
57 : * - Any kernel object or device pointers are validated with _SYSCALL_IS_OBJ()
58 : * - Any memory buffers passed in are checked to ensure that the calling thread
59 : * actually has access to them
60 : * - Many kernel calls do no sanity checking of parameters other than
61 : * assertions. The handler must check all of these conditions using
62 : * _SYSCALL_ASSERT()
63 : * - If the system call has more than 6 arguments, then arg6 will be a pointer
64 : * to some struct containing arguments 6+. The struct itself needs to be
65 : * validated like any other buffer passed in from userspace, and its members
66 : * individually validated (if necessary) and then passed to the real
67 : * implementation like normal arguments
68 : *
69 : * Even if the system call implementation has no return value, these always
70 : * return something, even 0, to prevent register leakage to userspace.
71 : *
72 : * Once everything has been validated, the real implementation will be executed.
73 : *
74 : * @param arg1 system call argument 1
75 : * @param arg2 system call argument 2
76 : * @param arg3 system call argument 3
77 : * @param arg4 system call argument 4
78 : * @param arg5 system call argument 5
79 : * @param arg6 system call argument 6
80 : * @param ssf System call stack frame pointer. Used to generate kernel oops
81 : * via _arch_syscall_oops_at(). Contents are arch-specific.
82 : * @return system call return value, or 0 if the system call implementation
83 : * return void
84 : *
85 : */
86 : typedef uintptr_t (*_k_syscall_handler_t)(uintptr_t arg1, uintptr_t arg2,
87 : uintptr_t arg3, uintptr_t arg4,
88 : uintptr_t arg5, uintptr_t arg6,
89 : void *ssf);
90 :
91 : /* True if a syscall function must trap to the kernel, usually a
92 : * compile-time decision.
93 : */
94 : static ALWAYS_INLINE bool z_syscall_trap(void)
95 : {
96 : bool ret = false;
97 : #ifdef CONFIG_USERSPACE
98 : #if defined(__ZEPHYR_SUPERVISOR__)
99 : ret = false;
100 : #elif defined(__ZEPHYR_USER__)
101 : ret = true;
102 : #else
103 : ret = arch_is_user_context();
104 : #endif
105 : #endif
106 : return ret;
107 : }
108 :
109 : /**
110 : * Indicate whether the CPU is currently in user mode
111 : *
112 : * @return true if the CPU is currently running with user permissions
113 : */
114 : __pinned_func
115 1 : static inline bool k_is_user_context(void)
116 : {
117 : #ifdef CONFIG_USERSPACE
118 : return arch_is_user_context();
119 : #else
120 : return false;
121 : #endif
122 : }
123 :
124 : #ifdef __cplusplus
125 : }
126 : #endif
127 :
128 : #endif /* _ASMLANGUAGE */
129 :
130 : #endif
|