Branch data Line data Source code
1 : : /* 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 <syscall_list.h> 12 : : #include <arch/syscall.h> 13 : : #include <stdbool.h> 14 : : 15 : : #ifndef _ASMLANGUAGE 16 : : #include <zephyr/types.h> 17 : : #include <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 : 152519 : static inline bool k_is_user_context(void) 116 : : { 117 : : #ifdef CONFIG_USERSPACE 118 : : return arch_is_user_context(); 119 : : #else 120 : 152519 : return false; 121 : : #endif 122 : : } 123 : : 124 : : #ifdef __cplusplus 125 : : } 126 : : #endif 127 : : 128 : : #endif /* _ASMLANGUAGE */ 129 : : 130 : : #endif