1.. _syscalls:
2
3System Calls
4############
5User threads run with a reduced set of privileges than supervisor threads:
6certain CPU instructions may not be used, and they have access to only a
7limited part of the memory map. System calls (may) allow user threads to
8perform operations not directly available to them.
9
10When defining system calls, it is very important to ensure that access to the
11API's private data is done exclusively through system call interfaces.
12Private kernel data should never be made available to user mode threads
13directly. For example, the ``k_queue`` APIs were intentionally not made
14available as they store bookkeeping information about the queue directly
15in the queue buffers which are visible from user mode.
16
17APIs that allow the user to register callback functions that run in
18supervisor mode should never be exposed as system calls. Reserve these
19for supervisor-mode access only.
20
21This section describes how to declare new system calls and discusses a few
22implementation details relevant to them.
23
24Components
25**********
26
27All system calls have the following components:
28
29* A **C prototype** prefixed with :c:macro:`__syscall` for the API. It
30  will be declared in some header under ``include/`` or in another
31  ``SYSCALL_INCLUDE_DIRS`` directory. This prototype is never implemented
32  manually, instead it gets created by the :ref:`gen_syscalls.py` script.
33  What gets generated is an inline function which either calls the
34  implementation function directly (if called from supervisor mode) or goes
35  through privilege elevation and validation steps (if called from user
36  mode).
37
38* An **implementation function**, which is the real implementation of the
39  system call. The implementation function may assume that all parameters
40  passed in have been validated if it was invoked from user mode.
41
42* A **verification function**, which wraps the implementation function
43  and does validation of all the arguments passed in.
44
45* An **unmarshalling function**, which is an automatically generated
46  handler that must be included by user source code.
47
48C Prototype
49***********
50
51The C prototype represents how the API is invoked from either user or
52supervisor mode. For example, to initialize a semaphore:
53
54.. code-block:: c
55
56    __syscall void k_sem_init(struct k_sem *sem, unsigned int initial_count,
57                              unsigned int limit);
58
59The :c:macro:`__syscall` attribute is very special. To the C compiler, it
60simply expands to 'static inline'. However to the post-build
61:ref:`parse_syscalls.py` script, it indicates that this API is a system call.
62The :ref:`parse_syscalls.py` script does some parsing of the function prototype,
63to determine the data types of its return value and arguments, and has some
64limitations:
65
66* Array arguments must be passed in as pointers, not arrays. For example,
67  ``int foo[]`` or ``int foo[12]`` is not allowed, but should instead be
68  expressed as ``int *foo``.
69
70* Function pointers horribly confuse the limited parser. The workaround is
71  to typedef them first, and then express in the argument list in terms
72  of that typedef.
73
74* :c:macro:`__syscall` must be the first thing in the prototype.
75
76The preprocessor is intentionally not used when determining the set of system
77calls to generate. However, any generated system calls that don't actually have
78a verification function defined (because the related feature is not enabled in
79the kernel configuration) will instead point to a special verification for
80unimplemented system calls. Data type definitions for APIs should not have
81conditional visibility to the compiler.
82
83Any header file that declares system calls must include a special generated
84header at the very bottom of the header file. This header follows the
85naming convention ``syscalls/<name of header file>``. For example, at the
86bottom of ``include/sensor.h``:
87
88.. code-block:: c
89
90    #include <zephyr/syscalls/sensor.h>
91
92C prototype functions must be declared in one of the directories
93listed in the CMake variable ``SYSCALL_INCLUDE_DIRS``. This list
94always contains ``APPLICATION_SOURCE_DIR`` when
95``CONFIG_APPLICATION_DEFINED_SYSCALL`` is set, or
96``${ZEPHYR_BASE}/subsys/testsuite/ztest/include`` when
97``CONFIG_ZTEST`` is set. Additional paths can be added to the list
98through the CMake command line or in CMake code that is run before
99``find_package(Zephyr ...)`` is run. ``${ZEPHYR_BASE}/include``
100is always scanned for potential syscall prototypes.
101
102Note that not all syscalls will be included in the final binaries.
103CMake functions ``zephyr_syscall_header`` and
104``zephyr_syscall_header_ifdef`` are used to specify which header
105files contain syscall prototypes where those syscalls must be
106present in the final binaries. Note that header files inside
107directories listed in CMake variable ``SYSCALL_INCLUDE_DIRS``
108will always have their syscalls present in final binaries.
109To force all syscalls to be included in the final binaries,
110turn on :kconfig:option:`CONFIG_EMIT_ALL_SYSCALLS`.
111
112Invocation Context
113==================
114
115Source code that uses system call APIs can be made more efficient if it is
116known that all the code inside a particular C file runs exclusively in
117user mode, or exclusively in supervisor mode. The system will look for
118the definition of macros :c:macro:`__ZEPHYR_SUPERVISOR__` or
119:c:macro:`__ZEPHYR_USER__`, typically these will be added to the compiler
120flags in the build system for the related files.
121
122* If :kconfig:option:`CONFIG_USERSPACE` is not enabled, all APIs just directly call
123  the implementation function.
124
125* Otherwise, the default case is to make a runtime check to see if the
126  processor is currently running in user mode, and either make the system call
127  or directly call the implementation function as appropriate.
128
129* If :c:macro:`__ZEPHYR_SUPERVISOR__` is defined, then it is assumed that
130  all the code runs in supervisor mode and all APIs just directly call the
131  implementation function. If the code was actually running in user mode,
132  there will be a CPU exception as soon as it tries to do something it isn't
133  allowed to do.
134
135* If :c:macro:`__ZEPHYR_USER__` is defined, then it is assumed that all the
136  code runs in user mode and system calls are unconditionally made.
137
138Implementation Details
139======================
140
141Declaring an API with :c:macro:`__syscall` causes some code to be generated in
142C and header files by the :ref:`gen_syscalls.py` script, all of which can be found in
143the project out directory under ``include/generated/``:
144
145* The system call is added to the enumerated type of system call IDs,
146  which is expressed in ``include/generated/zephyr/syscall_list.h``. It is the name
147  of the API in uppercase, prefixed with ``K_SYSCALL_``.
148
149* An entry for the system call is created in the dispatch table
150  ``_k_syscall_table``, expressed in ``include/generated/zephyr/syscall_dispatch.c``
151
152  * This table only contains syscalls where their corresponding
153    prototypes are declared in header files when
154    :kconfig:option:`CONFIG_EMIT_ALL_SYSCALLS` is enabled:
155
156    * Indicated by CMake functions ``zephyr_syscall_header`` and
157      ``zephyr_syscall_header_ifdef``, or
158
159    * Under directories specified in CMake variable
160      ``SYSCALL_INCLUDE_DIRS``.
161
162* A weak verification function is declared, which is just an alias of the
163  'unimplemented system call' verifier. This is necessary since the real
164  verification function may or may not be built depending on the kernel
165  configuration. For example, if a user thread makes a sensor subsystem
166  API call, but the sensor subsystem is not enabled, the weak verifier
167  will be invoked instead.
168
169* An unmarshalling function is defined in ``include/generated/<name>_mrsh.c``
170
171The body of the API is created in the generated system header. Using the
172example of :c:func:`k_sem_init()`, this API is declared in
173``include/kernel.h``. At the bottom of ``include/kernel.h`` is::
174
175    #include <zephyr/syscalls/kernel.h>
176
177Inside this header is the body of :c:func:`k_sem_init()`::
178
179    static inline void k_sem_init(struct k_sem * sem, unsigned int initial_count, unsigned int limit)
180    {
181    #ifdef CONFIG_USERSPACE
182            if (z_syscall_trap()) {
183                    arch_syscall_invoke3(*(uintptr_t *)&sem, *(uintptr_t *)&initial_count, *(uintptr_t *)&limit, K_SYSCALL_K_SEM_INIT);
184                    return;
185            }
186            compiler_barrier();
187    #endif
188            z_impl_k_sem_init(sem, initial_count, limit);
189    }
190
191This generates an inline function that takes three arguments with void
192return value. Depending on context it will either directly call the
193implementation function or go through a system call elevation. A
194prototype for the implementation function is also automatically generated.
195
196The final layer is the invocation of the system call itself. All architectures
197implementing system calls must implement the seven inline functions
198:c:func:`_arch_syscall_invoke0` through :c:func:`_arch_syscall_invoke6`. These
199functions marshal arguments into designated CPU registers and perform the
200necessary privilege elevation. Parameters of API inline function, before being
201passed as arguments to system call, are C casted to ``uintptr_t`` which matches
202size of register.
203Exception to above is passing 64-bit parameters on 32-bit systems, in which case
20464-bit parameters are split into lower and higher part and passed as two consecutive
205arguments.
206There is always a ``uintptr_t`` type return value, which may be neglected if
207not needed.
208
209.. figure:: syscall_flow.png
210   :alt: System Call execution flow
211   :width: 80%
212   :align: center
213
214   System Call execution flow
215
216Some system calls may have more than six arguments, but number of arguments
217passed via registers is limited to six for all architectures.
218Additional arguments will need to be passed in an array in the source memory
219space, which needs to be treated as untrusted memory in the verification
220function. This code (packing, unpacking and validation) is generated
221automatically as needed in the stub above and in the unmarshalling function.
222
223System calls return ``uintptr_t`` type value that is C casted, by wrapper, to
224a return type of API prototype declaration. This means that 64-bit value may
225not be directly returned, from a system call to its wrapper, on 32-bit systems.
226To solve the problem the automatically generated wrapper function defines 64-bit
227intermediate variable, which is considered **untrusted** buffer, on its stack
228and passes pointer to that variable to the system call, as a final argument.
229Upon return from the system call the value written to that buffer will be
230returned by the wrapper function.
231The problem does not exist on 64-bit systems which are able to return 64-bit
232values directly.
233
234Implementation Function
235***********************
236
237The implementation function is what actually does the work for the API.
238Zephyr normally does little to no error checking of arguments, or does this
239kind of checking with assertions. When writing the implementation function,
240validation of any parameters is optional and should be done with assertions.
241
242All implementation functions must follow the naming convention, which is the
243name of the API prefixed with ``z_impl_``. Implementation functions may be
244declared in the same header as the API as a static inline function or
245declared in some C file. There is no prototype needed for implementation
246functions, these are automatically generated.
247
248Verification Function
249*********************
250
251The verification function runs on the kernel side when a user thread makes
252a system call. When the user thread makes a software interrupt to elevate to
253supervisor mode, the common system call entry point uses the system call ID
254provided by the user to look up the appropriate unmarshalling function for that
255system call and jump into it. This in turn calls the verification function.
256
257Verification and unmarshalling functions only run when system call APIs are
258invoked from user mode. If an API is invoked from supervisor mode, the
259implementation is simply called and there is no software trap.
260
261The purpose of the verification function is to validate all the arguments
262passed in.  This includes:
263
264* Any kernel object pointers provided. For example, the semaphore APIs must
265  ensure that the semaphore object passed in is a valid semaphore and that
266  the calling thread has permission on it.
267
268* Any memory buffers passed in from user mode. Checks must be made that the
269  calling thread has read or write permissions on the provided buffer.
270
271* Any other arguments that have a limited range of valid values.
272
273Verification functions involve a great deal of boilerplate code which has been
274made simpler by some macros in :zephyr_file:`include/zephyr/internal/syscall_handler.h`.
275Verification functions should be declared using these macros.
276
277Argument Validation
278===================
279
280Several macros exist to validate arguments:
281
282* :c:macro:`K_SYSCALL_OBJ()` Checks a memory address to assert that it is
283  a valid kernel object of the expected type, that the calling thread
284  has permissions on it, and that the object is initialized.
285
286* :c:macro:`K_SYSCALL_OBJ_INIT()` is the same as
287  :c:macro:`K_SYSCALL_OBJ()`, except that the provided object may be
288  uninitialized. This is useful for verifiers of object init functions.
289
290* :c:macro:`K_SYSCALL_OBJ_NEVER_INIT()` is the same as
291  :c:macro:`K_SYSCALL_OBJ()`, except that the provided object must be
292  uninitialized. This is not used very often, currently only for
293  :c:func:`k_thread_create()`.
294
295* :c:macro:`K_SYSCALL_MEMORY_READ()` validates a memory buffer of a particular
296  size. The calling thread must have read permissions on the entire buffer.
297
298* :c:macro:`K_SYSCALL_MEMORY_WRITE()` is the same as
299  :c:macro:`K_SYSCALL_MEMORY_READ()` but the calling thread must additionally
300  have write permissions.
301
302* :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` validates an array whose total size
303  is expressed as separate arguments for the number of elements and the
304  element size. This macro correctly accounts for multiplication overflow
305  when computing the total size. The calling thread must have read permissions
306  on the total size.
307
308* :c:macro:`K_SYSCALL_MEMORY_ARRAY_WRITE()` is the same as
309  :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` but the calling thread must
310  additionally have write permissions.
311
312* :c:macro:`K_SYSCALL_VERIFY_MSG()` does a runtime check of some boolean
313  expression which must evaluate to true otherwise the check will fail.
314  A variant :c:macro:`K_SYSCALL_VERIFY` exists which does not take
315  a message parameter, instead printing the expression tested if it
316  fails. The latter should only be used for the most obvious of tests.
317
318* :c:macro:`K_SYSCALL_DRIVER_OP()` checks at runtime if a driver
319  instance is capable of performing a particular operation.  While this
320  macro can be used by itself, it's mostly a building block for macros
321  that are automatically generated for every driver subsystem.  For
322  instance, to validate the GPIO driver, one could use the
323  :c:macro:`K_SYSCALL_DRIVER_GPIO()` macro.
324
325* :c:macro:`K_SYSCALL_SPECIFIC_DRIVER()` is a runtime check to verify that
326  a provided pointer is a valid instance of a specific device driver, that
327  the calling thread has permissions on it, and that the driver has been
328  initialized. It does this by checking the API structure pointer that
329  is stored within the driver instance and ensuring that it matches the
330  provided value, which should be the address of the specific driver's
331  API structure.
332
333If any check fails, the macros will return a nonzero value. The macro
334:c:macro:`K_OOPS()` can be used to induce a kernel oops which will kill the
335calling thread. This is done instead of returning some error condition to
336keep the APIs the same when calling from supervisor mode.
337
338.. _syscall_verification:
339
340Verifier Definition
341===================
342
343All system calls are dispatched to a verifier function with a prefixed
344``z_vrfy_`` name based on the system call.  They have exactly the same
345return type and argument types as the wrapped system call.  Their job
346is to execute the system call (generally by calling the implementation
347function) after having validated all arguments.
348
349The verifier is itself invoked by an automatically generated
350unmarshaller function which takes care of unpacking the register
351arguments from the architecture layer and casting them to the correct
352type.  This is defined in a header file that must be included from
353user code, generally somewhere after the definition of the verifier in
354a translation unit (so that it can be inlined).
355
356For example:
357
358.. code-block:: c
359
360    static int z_vrfy_k_sem_take(struct k_sem *sem, int32_t timeout)
361    {
362        K_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM));
363        return z_impl_k_sem_take(sem, timeout);
364    }
365    #include <zephyr/syscalls/k_sem_take_mrsh.c>
366
367
368Verification Memory Access Policies
369===================================
370
371Parameters passed to system calls by reference require special handling,
372because the value of these parameters can be changed at any time by any
373user thread that has access to the memory that parameter points to. If the
374kernel makes any logical decisions based on the contents of this memory, this
375can open up the kernel to attacks even if checking is done. This is a class
376of exploits known as TOCTOU (Time Of Check to Time Of Use).
377
378The proper procedure to mitigate these attacks is to make a copies in the
379verification function, and only perform parameter checks on the copies, which
380user threads will never have access to. The implementation functions get passed
381the copy and not the original data sent by the user. The
382:c:func:`k_usermode_to_copy()` and :c:func:`k_usermode_from_copy()` APIs exist for
383this purpose.
384
385There is one exception in place, with respect to large data buffers which are
386only used to provide a memory area that is either only written to, or whose
387contents are never used for any validation or control flow. Further
388discussion of this later in this section.
389
390As a first example, consider a parameter which is used as an output parameter
391for some integral value:
392
393
394.. code-block:: c
395
396    int z_vrfy_some_syscall(int *out_param)
397    {
398        int local_out_param;
399        int ret;
400
401        ret = z_impl_some_syscall(&local_out_param);
402        K_OOPS(k_usermode_to_copy(out_param, &local_out_param, sizeof(*out_param)));
403        return ret;
404    }
405
406Here we have allocated ``local_out_param`` on the stack, passed its address to
407the implementation function, and then used :c:func:`k_usermode_to_copy()` to fill
408in the memory passed in by the caller.
409
410It might be tempting to do something more concise:
411
412.. code-block:: c
413
414    int z_vrfy_some_syscall(int *out_param)
415    {
416        K_OOPS(K_SYSCALL_MEMORY_WRITE(out_param, sizeof(*out_param)));
417        return z_impl_some_syscall(out_param);
418    }
419
420However, this is unsafe if the implementation ever does any reads to this
421memory as part of its logic. For example, it could be used to store some
422counter value, and this could be meddled with by user threads that have access
423to its memory. It is by far safest for small integral values to do the copying
424as shown in the first example.
425
426Some parameters may be input/output. For instance, it's not uncommon to see APIs
427which pass in a pointer to some ``size_t`` which is a maximum allowable size,
428which is then updated by the implementation to reflect the actual number of
429bytes processed. This too should use a stack copy:
430
431.. code-block:: c
432
433    int z_vrfy_in_out_syscall(size_t *size_ptr)
434    {
435        size_t size;
436        int ret;
437
438        K_OOPS(k_usermode_from_copy(&size, size_ptr, sizeof(size));
439        ret = z_impl_in_out_syscall(&size);
440        K_OOPS(k_usermode_to_copy(size_ptr, &size, sizeof(size)));
441        return ret;
442    }
443
444Many system calls pass in structures or even linked data structures. All should
445be copied. Typically this is done by allocating copies on the stack:
446
447.. code-block:: c
448
449    struct bar {
450        ...
451    };
452
453    struct foo {
454        ...
455        struct bar *bar_left;
456        struct bar *bar_right;
457    };
458
459    int z_vrfy_must_alloc(struct foo *foo)
460    {
461        int ret;
462        struct foo foo_copy;
463        struct bar bar_right_copy;
464        struct bar bar_left_copy;
465
466        K_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo)));
467        K_OOPS(k_usermode_from_copy(&bar_right_copy, foo_copy.bar_right,
468                                sizeof(struct bar)));
469        foo_copy.bar_right = &bar_right_copy;
470        K_OOPS(k_usermode_from_copy(&bar_left_copy, foo_copy.bar_left,
471                                sizeof(struct bar)));
472        foo_copy.bar_left = &bar_left_copy;
473
474        return z_impl_must_alloc(&foo_copy);
475    }
476
477In some cases the amount of data isn't known at compile time or may be too
478large to allocate on the stack. In this scenario, it may be necessary to draw
479memory from the caller's resource pool via :c:func:`z_thread_malloc()`. This
480should always be considered last resort. Functional safety programming
481guidelines heavily discourage usage of heap and the fact that a resource pool is
482used must be clearly documented. Any issues with allocation must be
483reported, to a caller, with returning the ``-ENOMEM`` . The ``K_OOPS()``
484should never be used to verify if resource allocation has been successful.
485
486.. code-block:: c
487
488    struct bar {
489        ...
490    };
491
492    struct foo {
493        size_t count;
494        struct bar *bar_list; /* array of struct bar of size count */
495    };
496
497    int z_vrfy_must_alloc(struct foo *foo)
498    {
499        int ret;
500        struct foo foo_copy;
501        struct bar *bar_list_copy;
502        size_t bar_list_bytes;
503
504        /* Safely copy foo into foo_copy */
505        K_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo)));
506
507        /* Bounds check the count member, in the copy we made */
508        if (foo_copy.count > 32) {
509            return -EINVAL;
510        }
511
512        /* Allocate RAM for the bar_list, replace the pointer in
513         * foo_copy */
514        bar_list_bytes = foo_copy.count * sizeof(struct_bar);
515        bar_list_copy = z_thread_malloc(bar_list_bytes);
516        if (bar_list_copy == NULL) {
517            return -ENOMEM;
518        }
519        K_OOPS(k_usermode_from_copy(bar_list_copy, foo_copy.bar_list,
520                                bar_list_bytes));
521        foo_copy.bar_list = bar_list_copy;
522
523        ret = z_impl_must_alloc(&foo_copy);
524
525        /* All done with the memory, free it and return */
526        k_free(foo_copy.bar_list_copy);
527        return ret;
528    }
529
530Finally, we must consider large data buffers. These represent areas of user
531memory which either have data copied out of, or copied into. It is permitted
532to pass these pointers to the implementation function directly. The caller's
533access to the buffer still must be validated with ``K_SYSCALL_MEMORY`` APIs.
534The following constraints need to be met:
535
536 * If the buffer is used by the implementation function to write data, such
537   as data captured from some MMIO region, the implementation function must
538   only write this data, and never read it.
539
540 * If the buffer is used by the implementation function to read data, such
541   as a block of memory to write to some hardware destination, this data
542   must be read without any processing. No conditional logic can be implemented
543   due to the data buffer's contents. If such logic is required a copy must be
544   made.
545
546 * The buffer must only be used synchronously with the call. The implementation
547   must not ever save the buffer address and use it asynchronously, such as
548   when an interrupt fires.
549
550.. code-block:: c
551
552    int z_vrfy_get_data_from_kernel(void *buf, size_t size)
553    {
554        K_OOPS(K_SYSCALL_MEMORY_WRITE(buf, size));
555        return z_impl_get_data_from_kernel(buf, size);
556    }
557
558Verification Return Value Policies
559==================================
560
561When verifying system calls, it's important to note which kinds of verification
562failures should propagate a return value to the caller, and which should
563simply invoke :c:macro:`K_OOPS()` which kills the calling thread. The current
564conventions are as follows:
565
566#. For system calls that are defined but not compiled, invocations of these
567   missing system calls are routed to :c:func:`handler_no_syscall()` which
568   invokes :c:macro:`K_OOPS()`.
569
570#. Any invalid access to memory found by the set of ``K_SYSCALL_MEMORY`` APIs,
571   :c:func:`k_usermode_from_copy()`, :c:func:`k_usermode_to_copy()`
572   should trigger a :c:macro:`K_OOPS`. This happens when the caller doesn't have
573   appropriate permissions on the memory buffer or some size calculation
574   overflowed.
575
576#. Most system calls take kernel object pointers as an argument, checked either
577   with one of the ``K_SYSCALL_OBJ`` functions,  ``K_SYSCALL_DRIVER_nnnnn``, or
578   manually using :c:func:`k_object_validate()`. These can fail for a variety
579   of reasons: missing driver API, bad kernel object pointer, wrong kernel
580   object type, or improper initialization state. These issues should always
581   invoke :c:macro:`K_OOPS()`.
582
583#. Any error resulting from a failed memory heap allocation, often from
584   invoking :c:func:`z_thread_malloc()`, should propagate ``-ENOMEM`` to the
585   caller.
586
587#. General parameter checks should be done in the implementation function,
588   in most cases using ``CHECKIF()``.
589
590   * The behavior of ``CHECKIF()`` depends on the kernel configuration, but if
591     user mode is enabled, :kconfig:option:`CONFIG_RUNTIME_ERROR_CHECKS` is enforced,
592     which guarantees that these checks will be made and a return value
593     propagated.
594
595#. It is totally forbidden for any kind of kernel mode callback function to
596   be registered from user mode. APIs which simply install callbacks shall not
597   be exposed as system calls. Some driver subsystem APIs may take optional
598   function callback pointers. User mode verification functions for these APIs
599   must enforce that these are NULL and should invoke :c:macro:`K_OOPS()` if
600   not.
601
602#. Some parameter checks are enforced only from user mode. These should be
603   checked in the verification function and propagate a return value to the
604   caller if possible.
605
606There are some known exceptions to these policies currently in Zephyr:
607
608* :c:func:`k_thread_join()` and :c:func:`k_thread_abort()` are no-ops if
609  the thread object isn't initialized. This is because for threads, the
610  initialization bit pulls double-duty to indicate whether a thread is
611  running, cleared upon exit. See #23030.
612
613* :c:func:`k_thread_create()` invokes :c:macro:`K_OOPS()` for parameter
614  checks, due to a great deal of existing code ignoring the return value.
615  This will also be addressed by #23030.
616
617* :c:func:`k_thread_abort()` invokes :c:macro:`K_OOPS()` if an essential
618  thread is aborted, as the function has no return value.
619
620* Various system calls related to logging invoke :c:macro:`K_OOPS()`
621  when bad parameters are passed in as they do not propagate errors.
622
623Configuration Options
624*********************
625
626Related configuration options:
627
628* :kconfig:option:`CONFIG_USERSPACE`
629* :kconfig:option:`CONFIG_EMIT_ALL_SYSCALLS`
630
631APIs
632****
633
634Helper macros for creating system call verification functions are provided in
635:zephyr_file:`include/zephyr/internal/syscall_handler.h`:
636
637* :c:macro:`K_SYSCALL_OBJ()`
638* :c:macro:`K_SYSCALL_OBJ_INIT()`
639* :c:macro:`K_SYSCALL_OBJ_NEVER_INIT()`
640* :c:macro:`K_OOPS()`
641* :c:macro:`K_SYSCALL_MEMORY_READ()`
642* :c:macro:`K_SYSCALL_MEMORY_WRITE()`
643* :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()`
644* :c:macro:`K_SYSCALL_MEMORY_ARRAY_WRITE()`
645* :c:macro:`K_SYSCALL_VERIFY_MSG()`
646* :c:macro:`K_SYSCALL_VERIFY`
647
648Functions for invoking system calls are defined in
649:zephyr_file:`include/zephyr/syscall.h`:
650
651* :c:func:`_arch_syscall_invoke0`
652* :c:func:`_arch_syscall_invoke1`
653* :c:func:`_arch_syscall_invoke2`
654* :c:func:`_arch_syscall_invoke3`
655* :c:func:`_arch_syscall_invoke4`
656* :c:func:`_arch_syscall_invoke5`
657* :c:func:`_arch_syscall_invoke6`
658