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