Zephyr API Documentation  3.7.0
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
Architecture-specific userspace APIs

Functions

static uintptr_t arch_syscall_invoke0 (uintptr_t call_id)
 Invoke a system call with 0 arguments.
 
static uintptr_t arch_syscall_invoke1 (uintptr_t arg1, uintptr_t call_id)
 Invoke a system call with 1 argument.
 
static uintptr_t arch_syscall_invoke2 (uintptr_t arg1, uintptr_t arg2, uintptr_t call_id)
 Invoke a system call with 2 arguments.
 
static uintptr_t arch_syscall_invoke3 (uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t call_id)
 Invoke a system call with 3 arguments.
 
static uintptr_t arch_syscall_invoke4 (uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t call_id)
 Invoke a system call with 4 arguments.
 
static uintptr_t arch_syscall_invoke5 (uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t call_id)
 Invoke a system call with 5 arguments.
 
static uintptr_t arch_syscall_invoke6 (uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6, uintptr_t call_id)
 Invoke a system call with 6 arguments.
 
static bool arch_is_user_context (void)
 Indicate whether we are currently running in user mode.
 
int arch_mem_domain_max_partitions_get (void)
 Get the maximum number of partitions for a memory domain.
 
int arch_buffer_validate (const void *addr, size_t size, int write)
 Check memory region permissions.
 
size_t arch_virt_region_align (uintptr_t phys, size_t size)
 Get the optimal virtual region alignment to optimize the MMU table layout.
 
FUNC_NORETURN void arch_user_mode_enter (k_thread_entry_t user_entry, void *p1, void *p2, void *p3)
 Perform a one-way transition from supervisor to user mode.
 
FUNC_NORETURN void arch_syscall_oops (void *ssf)
 Induce a kernel oops that appears to come from a specific location.
 
size_t arch_user_string_nlen (const char *s, size_t maxsize, int *err)
 Safely take the length of a potentially bad string.
 
static bool arch_mem_coherent (void *ptr)
 Detect memory coherence type.
 
static void arch_cohere_stacks (struct k_thread *old_thread, void *old_switch_handle, struct k_thread *new_thread)
 Ensure cache coherence prior to context switch.
 

Detailed Description

Function Documentation

◆ arch_buffer_validate()

int arch_buffer_validate ( const void *  addr,
size_t  size,
int  write 
)

#include <zephyr/arch/arch_interface.h>

Check memory region permissions.

Given a memory region, return whether the current memory management hardware configuration would allow a user thread to read/write that region. Used by system calls to validate buffers coming in from userspace.

Notes: The function is guaranteed to never return validation success, if the entire buffer area is not user accessible.

The function is guaranteed to correctly validate the permissions of the supplied buffer, if the user access permissions of the entire buffer are enforced by a single, enabled memory management region.

In some architectures the validation will always return failure if the supplied memory buffer spans multiple enabled memory management regions (even if all such regions permit user access).

Warning
Buffer of size zero (0) has undefined behavior.
Parameters
addrstart address of the buffer
sizethe size of the buffer
writeIf non-zero, additionally check if the area is writable. Otherwise, just check if the memory can be read.
Returns
nonzero if the permissions don't match.

◆ arch_cohere_stacks()

static void arch_cohere_stacks ( struct k_thread old_thread,
void *  old_switch_handle,
struct k_thread new_thread 
)
inlinestatic

#include <zephyr/arch/arch_interface.h>

Ensure cache coherence prior to context switch.

Required when ARCH_HAS_COHERENCE is true. On cache-incoherent multiprocessor architectures, thread stacks are cached by default for performance reasons. They must therefore be flushed appropriately on context switch. The rules are:

  1. The region containing live data in the old stack (generally the bytes between the current stack pointer and the top of the stack memory) must be flushed to underlying storage so a new CPU that runs the same thread sees the correct data. This must happen before the assignment of the switch_handle field in the thread struct which signals the completion of context switch.
  2. Any data areas to be read from the new stack (generally the same as the live region when it was saved) should be invalidated (and NOT flushed!) in the data cache. This is because another CPU may have run or re-initialized the thread since this CPU suspended it, and any data present in cache will be stale.
Note
The kernel will call this function during interrupt exit when a new thread has been chosen to run, and also immediately before entering arch_switch() to effect a code-driven context switch. In the latter case, it is very likely that more data will be written to the old_thread stack region after this function returns but before the completion of the switch. Simply flushing naively here is not sufficient on many architectures and coordination with the arch_switch() implementation is likely required.
Parameters
old_threadThe old thread to be flushed before being allowed to run on other CPUs.
old_switch_handleThe switch handle to be stored into old_thread (it will not be valid until the cache is flushed so is not present yet). This will be NULL if inside z_swap() (because the arch_switch() has not saved it yet).
new_threadThe new thread to be invalidated before it runs locally.

◆ arch_is_user_context()

static bool arch_is_user_context ( void  )
inlinestatic

#include <zephyr/arch/arch_interface.h>

Indicate whether we are currently running in user mode.

Returns
True if the CPU is currently running with user permissions

◆ arch_mem_coherent()

static bool arch_mem_coherent ( void *  ptr)
inlinestatic

#include <zephyr/arch/arch_interface.h>

Detect memory coherence type.

Required when ARCH_HAS_COHERENCE is true. This function returns true if the byte pointed to lies within an architecture-defined "coherence region" (typically implemented with uncached memory) and can safely be used in multiprocessor code without explicit flush or invalidate operations.

Note
The result is for only the single byte at the specified address, this API is not required to check region boundaries or to expect aligned pointers. The expectation is that the code above will have queried the appropriate address(es).

◆ arch_mem_domain_max_partitions_get()

int arch_mem_domain_max_partitions_get ( void  )

#include <zephyr/arch/arch_interface.h>

Get the maximum number of partitions for a memory domain.

Returns
Max number of partitions, or -1 if there is no limit

◆ arch_syscall_invoke0()

static uintptr_t arch_syscall_invoke0 ( uintptr_t  call_id)
inlinestatic

#include <zephyr/arch/arch_interface.h>

Invoke a system call with 0 arguments.

No general-purpose register state other than return value may be preserved when transitioning from supervisor mode back down to user mode for security reasons.

It is required that all arguments be stored in registers when elevating privileges from user to supervisor mode.

Processing of the syscall takes place on a separate kernel stack. Interrupts should be enabled when invoking the system call marshallers from the dispatch table. Thread preemption may occur when handling system calls.

Call IDs are untrusted and must be bounds-checked, as the value is used to index the system call dispatch table, containing function pointers to the specific system call code.

Parameters
call_idSystem call ID
Returns
Return value of the system call. Void system calls return 0 here.

◆ arch_syscall_invoke1()

static uintptr_t arch_syscall_invoke1 ( uintptr_t  arg1,
uintptr_t  call_id 
)
inlinestatic

#include <zephyr/arch/arch_interface.h>

Invoke a system call with 1 argument.

See also
arch_syscall_invoke0()
Parameters
arg1First argument to the system call.
call_idSystem call ID, will be bounds-checked and used to reference kernel-side dispatch table
Returns
Return value of the system call. Void system calls return 0 here.

◆ arch_syscall_invoke2()

static uintptr_t arch_syscall_invoke2 ( uintptr_t  arg1,
uintptr_t  arg2,
uintptr_t  call_id 
)
inlinestatic

#include <zephyr/arch/arch_interface.h>

Invoke a system call with 2 arguments.

See also
arch_syscall_invoke0()
Parameters
arg1First argument to the system call.
arg2Second argument to the system call.
call_idSystem call ID, will be bounds-checked and used to reference kernel-side dispatch table
Returns
Return value of the system call. Void system calls return 0 here.

◆ arch_syscall_invoke3()

static uintptr_t arch_syscall_invoke3 ( uintptr_t  arg1,
uintptr_t  arg2,
uintptr_t  arg3,
uintptr_t  call_id 
)
inlinestatic

#include <zephyr/arch/arch_interface.h>

Invoke a system call with 3 arguments.

See also
arch_syscall_invoke0()
Parameters
arg1First argument to the system call.
arg2Second argument to the system call.
arg3Third argument to the system call.
call_idSystem call ID, will be bounds-checked and used to reference kernel-side dispatch table
Returns
Return value of the system call. Void system calls return 0 here.

◆ arch_syscall_invoke4()

static uintptr_t arch_syscall_invoke4 ( uintptr_t  arg1,
uintptr_t  arg2,
uintptr_t  arg3,
uintptr_t  arg4,
uintptr_t  call_id 
)
inlinestatic

#include <zephyr/arch/arch_interface.h>

Invoke a system call with 4 arguments.

See also
arch_syscall_invoke0()
Parameters
arg1First argument to the system call.
arg2Second argument to the system call.
arg3Third argument to the system call.
arg4Fourth argument to the system call.
call_idSystem call ID, will be bounds-checked and used to reference kernel-side dispatch table
Returns
Return value of the system call. Void system calls return 0 here.

◆ arch_syscall_invoke5()

static uintptr_t arch_syscall_invoke5 ( uintptr_t  arg1,
uintptr_t  arg2,
uintptr_t  arg3,
uintptr_t  arg4,
uintptr_t  arg5,
uintptr_t  call_id 
)
inlinestatic

#include <zephyr/arch/arch_interface.h>

Invoke a system call with 5 arguments.

See also
arch_syscall_invoke0()
Parameters
arg1First argument to the system call.
arg2Second argument to the system call.
arg3Third argument to the system call.
arg4Fourth argument to the system call.
arg5Fifth argument to the system call.
call_idSystem call ID, will be bounds-checked and used to reference kernel-side dispatch table
Returns
Return value of the system call. Void system calls return 0 here.

◆ arch_syscall_invoke6()

static uintptr_t arch_syscall_invoke6 ( uintptr_t  arg1,
uintptr_t  arg2,
uintptr_t  arg3,
uintptr_t  arg4,
uintptr_t  arg5,
uintptr_t  arg6,
uintptr_t  call_id 
)
inlinestatic

#include <zephyr/arch/arch_interface.h>

Invoke a system call with 6 arguments.

See also
arch_syscall_invoke0()
Parameters
arg1First argument to the system call.
arg2Second argument to the system call.
arg3Third argument to the system call.
arg4Fourth argument to the system call.
arg5Fifth argument to the system call.
arg6Sixth argument to the system call.
call_idSystem call ID, will be bounds-checked and used to reference kernel-side dispatch table
Returns
Return value of the system call. Void system calls return 0 here.

◆ arch_syscall_oops()

FUNC_NORETURN void arch_syscall_oops ( void *  ssf)

#include <zephyr/arch/arch_interface.h>

Induce a kernel oops that appears to come from a specific location.

Normally, k_oops() generates an exception that appears to come from the call site of the k_oops() itself.

However, when validating arguments to a system call, if there are problems we want the oops to appear to come from where the system call was invoked and not inside the validation function.

Parameters
ssfSystem call stack frame pointer. This gets passed as an argument to _k_syscall_handler_t functions and its contents are completely architecture specific.

◆ arch_user_mode_enter()

FUNC_NORETURN void arch_user_mode_enter ( k_thread_entry_t  user_entry,
void *  p1,
void *  p2,
void *  p3 
)

#include <zephyr/arch/arch_interface.h>

Perform a one-way transition from supervisor to user mode.

Implementations of this function must do the following:

  • Reset the thread's stack pointer to a suitable initial value. We do not need any prior context since this is a one-way operation.
  • Set up any kernel stack region for the CPU to use during privilege elevation
  • Put the CPU in whatever its equivalent of user mode is
  • Transfer execution to arch_new_thread() passing along all the supplied arguments, in user mode.
Parameters
user_entryEntry point to start executing as a user thread
p11st parameter to user thread
p22nd parameter to user thread
p33rd parameter to user thread

◆ arch_user_string_nlen()

size_t arch_user_string_nlen ( const char *  s,
size_t  maxsize,
int *  err 
)

#include <zephyr/arch/arch_interface.h>

Safely take the length of a potentially bad string.

This must not fault, instead the err parameter must have -1 written to it. This function otherwise should work exactly like libc strnlen(). On success err should be set to 0.

Parameters
sString to measure
maxsizeMax length of the string
errError value to write
Returns
Length of the string, not counting NULL byte, up to maxsize

◆ arch_virt_region_align()

size_t arch_virt_region_align ( uintptr_t  phys,
size_t  size 
)

#include <zephyr/arch/arch_interface.h>

Get the optimal virtual region alignment to optimize the MMU table layout.

Some MMU HW requires some region to be aligned to some of the intermediate block alignment in order to reduce table usage. This call returns the optimal virtual address alignment in order to permit such optimization in the following MMU mapping call.

Parameters
[in]physPhysical address of region to be mapped, aligned to CONFIG_MMU_PAGE_SIZE
[in]sizeSize of region to be mapped, aligned to CONFIG_MMU_PAGE_SIZE
Returns
Alignment to apply on the virtual address of this region