You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.9 KiB
130 lines
3.9 KiB
/* |
|
* 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
|
|
|