123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- /*
- * Copyright (c) 2017, Intel Corporation
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #ifndef ZEPHYR_INCLUDE_SYSCALL_H_
- #define ZEPHYR_INCLUDE_SYSCALL_H_
- #include <syscall_list.h>
- #include <arch/syscall.h>
- #include <stdbool.h>
- #ifndef _ASMLANGUAGE
- #include <zephyr/types.h>
- #include <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
|