| /* |
| * Copyright (c) 2017, Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| |
| #ifndef ZEPHYR_INCLUDE_SYSCALL_H_ |
| #define ZEPHYR_INCLUDE_SYSCALL_H_ |
| |
| #include <zephyr/syscall_list.h> |
| #include <zephyr/arch/syscall.h> |
| #include <stdbool.h> |
| |
| #ifndef _ASMLANGUAGE |
| #include <zephyr/types.h> |
| #include <zephyr/linker/sections.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /* |
| * System Call Declaration macros |
| * |
| * These macros are used in public header files to declare system calls. |
| * They generate inline functions which have different implementations |
| * depending on the current compilation context: |
| * |
| * - Kernel-only code, or CONFIG_USERSPACE disabled, these inlines will |
| * directly call the implementation |
| * - User-only code, these inlines will marshal parameters and elevate |
| * privileges |
| * - Mixed or indeterminate code, these inlines will do a runtime check |
| * to determine what course of action is needed. |
| * |
| * All system calls require a verifier function and an implementation |
| * function. These must follow a naming convention. For a system call |
| * named k_foo(): |
| * |
| * - The handler function will be named z_vrfy_k_foo(). Handler |
| * functions have the same type signature as the wrapped call, |
| * verify arguments passed up from userspace, and call the |
| * implementation function. See documentation for that typedef for |
| * more information. - The implementation function will be named |
| * z_impl_k_foo(). This is the actual implementation of the system |
| * call. |
| */ |
| |
| /** |
| * @typedef _k_syscall_handler_t |
| * @brief System call handler function type |
| * |
| * These are kernel-side skeleton functions for system calls. They are |
| * necessary to sanitize the arguments passed into the system call: |
| * |
| * - Any kernel object or device pointers are validated with _SYSCALL_IS_OBJ() |
| * - Any memory buffers passed in are checked to ensure that the calling thread |
| * actually has access to them |
| * - Many kernel calls do no sanity checking of parameters other than |
| * assertions. The handler must check all of these conditions using |
| * _SYSCALL_ASSERT() |
| * - If the system call has more than 6 arguments, then arg6 will be a pointer |
| * to some struct containing arguments 6+. The struct itself needs to be |
| * validated like any other buffer passed in from userspace, and its members |
| * individually validated (if necessary) and then passed to the real |
| * implementation like normal arguments |
| * |
| * Even if the system call implementation has no return value, these always |
| * return something, even 0, to prevent register leakage to userspace. |
| * |
| * Once everything has been validated, the real implementation will be executed. |
| * |
| * @param arg1 system call argument 1 |
| * @param arg2 system call argument 2 |
| * @param arg3 system call argument 3 |
| * @param arg4 system call argument 4 |
| * @param arg5 system call argument 5 |
| * @param arg6 system call argument 6 |
| * @param ssf System call stack frame pointer. Used to generate kernel oops |
| * via _arch_syscall_oops_at(). Contents are arch-specific. |
| * @return system call return value, or 0 if the system call implementation |
| * return void |
| * |
| */ |
| typedef uintptr_t (*_k_syscall_handler_t)(uintptr_t arg1, uintptr_t arg2, |
| uintptr_t arg3, uintptr_t arg4, |
| uintptr_t arg5, uintptr_t arg6, |
| void *ssf); |
| |
| /* True if a syscall function must trap to the kernel, usually a |
| * compile-time decision. |
| */ |
| static ALWAYS_INLINE bool z_syscall_trap(void) |
| { |
| bool ret = false; |
| #ifdef CONFIG_USERSPACE |
| #if defined(__ZEPHYR_SUPERVISOR__) |
| ret = false; |
| #elif defined(__ZEPHYR_USER__) |
| ret = true; |
| #else |
| ret = arch_is_user_context(); |
| #endif |
| #endif |
| return ret; |
| } |
| |
| /** |
| * Indicate whether the CPU is currently in user mode |
| * |
| * @return true if the CPU is currently running with user permissions |
| */ |
| __pinned_func |
| static inline bool k_is_user_context(void) |
| { |
| #ifdef CONFIG_USERSPACE |
| return arch_is_user_context(); |
| #else |
| return false; |
| #endif |
| } |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* _ASMLANGUAGE */ |
| |
| #endif |