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 :zephyr_file:`include/zephyr/drivers/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:zephyr_file:`include/zephyr/kernel.h`. At the bottom of 174:zephyr_file:`include/zephyr/kernel.h` is:: 175 176 #include <zephyr/syscalls/kernel.h> 177 178Inside this header is the body of :c:func:`k_sem_init()`:: 179 180 static inline void k_sem_init(struct k_sem * sem, unsigned int initial_count, unsigned int limit) 181 { 182 #ifdef CONFIG_USERSPACE 183 if (z_syscall_trap()) { 184 arch_syscall_invoke3(*(uintptr_t *)&sem, *(uintptr_t *)&initial_count, *(uintptr_t *)&limit, K_SYSCALL_K_SEM_INIT); 185 return; 186 } 187 compiler_barrier(); 188 #endif 189 z_impl_k_sem_init(sem, initial_count, limit); 190 } 191 192This generates an inline function that takes three arguments with void 193return value. Depending on context it will either directly call the 194implementation function or go through a system call elevation. A 195prototype for the implementation function is also automatically generated. 196 197The final layer is the invocation of the system call itself. All architectures 198implementing system calls must implement the seven inline functions 199:c:func:`_arch_syscall_invoke0` through :c:func:`_arch_syscall_invoke6`. These 200functions marshal arguments into designated CPU registers and perform the 201necessary privilege elevation. Parameters of API inline function, before being 202passed as arguments to system call, are C casted to ``uintptr_t`` which matches 203size of register. 204Exception to above is passing 64-bit parameters on 32-bit systems, in which case 20564-bit parameters are split into lower and higher part and passed as two consecutive 206arguments. 207There is always a ``uintptr_t`` type return value, which may be neglected if 208not needed. 209 210.. figure:: syscall_flow.png 211 :alt: System Call execution flow 212 :width: 80% 213 :align: center 214 215 System Call execution flow 216 217Some system calls may have more than six arguments, but number of arguments 218passed via registers is limited to six for all architectures. 219Additional arguments will need to be passed in an array in the source memory 220space, which needs to be treated as untrusted memory in the verification 221function. This code (packing, unpacking and validation) is generated 222automatically as needed in the stub above and in the unmarshalling function. 223 224System calls return ``uintptr_t`` type value that is C casted, by wrapper, to 225a return type of API prototype declaration. This means that 64-bit value may 226not be directly returned, from a system call to its wrapper, on 32-bit systems. 227To solve the problem the automatically generated wrapper function defines 64-bit 228intermediate variable, which is considered **untrusted** buffer, on its stack 229and passes pointer to that variable to the system call, as a final argument. 230Upon return from the system call the value written to that buffer will be 231returned by the wrapper function. 232The problem does not exist on 64-bit systems which are able to return 64-bit 233values directly. 234 235Implementation Function 236*********************** 237 238The implementation function is what actually does the work for the API. 239Zephyr normally does little to no error checking of arguments, or does this 240kind of checking with assertions. When writing the implementation function, 241validation of any parameters is optional and should be done with assertions. 242 243All implementation functions must follow the naming convention, which is the 244name of the API prefixed with ``z_impl_``. Implementation functions may be 245declared in the same header as the API as a static inline function or 246declared in some C file. There is no prototype needed for implementation 247functions, these are automatically generated. 248 249Verification Function 250********************* 251 252The verification function runs on the kernel side when a user thread makes 253a system call. When the user thread makes a software interrupt to elevate to 254supervisor mode, the common system call entry point uses the system call ID 255provided by the user to look up the appropriate unmarshalling function for that 256system call and jump into it. This in turn calls the verification function. 257 258Verification and unmarshalling functions only run when system call APIs are 259invoked from user mode. If an API is invoked from supervisor mode, the 260implementation is simply called and there is no software trap. 261 262The purpose of the verification function is to validate all the arguments 263passed in. This includes: 264 265* Any kernel object pointers provided. For example, the semaphore APIs must 266 ensure that the semaphore object passed in is a valid semaphore and that 267 the calling thread has permission on it. 268 269* Any memory buffers passed in from user mode. Checks must be made that the 270 calling thread has read or write permissions on the provided buffer. 271 272* Any other arguments that have a limited range of valid values. 273 274Verification functions involve a great deal of boilerplate code which has been 275made simpler by some macros in :zephyr_file:`include/zephyr/internal/syscall_handler.h`. 276Verification functions should be declared using these macros. 277 278Argument Validation 279=================== 280 281Several macros exist to validate arguments: 282 283* :c:macro:`K_SYSCALL_OBJ()` Checks a memory address to assert that it is 284 a valid kernel object of the expected type, that the calling thread 285 has permissions on it, and that the object is initialized. 286 287* :c:macro:`K_SYSCALL_OBJ_INIT()` is the same as 288 :c:macro:`K_SYSCALL_OBJ()`, except that the provided object may be 289 uninitialized. This is useful for verifiers of object init functions. 290 291* :c:macro:`K_SYSCALL_OBJ_NEVER_INIT()` is the same as 292 :c:macro:`K_SYSCALL_OBJ()`, except that the provided object must be 293 uninitialized. This is not used very often, currently only for 294 :c:func:`k_thread_create()`. 295 296* :c:macro:`K_SYSCALL_MEMORY_READ()` validates a memory buffer of a particular 297 size. The calling thread must have read permissions on the entire buffer. 298 299* :c:macro:`K_SYSCALL_MEMORY_WRITE()` is the same as 300 :c:macro:`K_SYSCALL_MEMORY_READ()` but the calling thread must additionally 301 have write permissions. 302 303* :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` validates an array whose total size 304 is expressed as separate arguments for the number of elements and the 305 element size. This macro correctly accounts for multiplication overflow 306 when computing the total size. The calling thread must have read permissions 307 on the total size. 308 309* :c:macro:`K_SYSCALL_MEMORY_ARRAY_WRITE()` is the same as 310 :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` but the calling thread must 311 additionally have write permissions. 312 313* :c:macro:`K_SYSCALL_VERIFY_MSG()` does a runtime check of some boolean 314 expression which must evaluate to true otherwise the check will fail. 315 A variant :c:macro:`K_SYSCALL_VERIFY` exists which does not take 316 a message parameter, instead printing the expression tested if it 317 fails. The latter should only be used for the most obvious of tests. 318 319* :c:macro:`K_SYSCALL_DRIVER_OP()` checks at runtime if a driver 320 instance is capable of performing a particular operation. While this 321 macro can be used by itself, it's mostly a building block for macros 322 that are automatically generated for every driver subsystem. For 323 instance, to validate the GPIO driver, one could use the 324 :c:macro:`K_SYSCALL_DRIVER_GPIO()` macro. 325 326* :c:macro:`K_SYSCALL_SPECIFIC_DRIVER()` is a runtime check to verify that 327 a provided pointer is a valid instance of a specific device driver, that 328 the calling thread has permissions on it, and that the driver has been 329 initialized. It does this by checking the API structure pointer that 330 is stored within the driver instance and ensuring that it matches the 331 provided value, which should be the address of the specific driver's 332 API structure. 333 334If any check fails, the macros will return a nonzero value. The macro 335:c:macro:`K_OOPS()` can be used to induce a kernel oops which will kill the 336calling thread. This is done instead of returning some error condition to 337keep the APIs the same when calling from supervisor mode. 338 339.. _syscall_verification: 340 341Verifier Definition 342=================== 343 344All system calls are dispatched to a verifier function with a prefixed 345``z_vrfy_`` name based on the system call. They have exactly the same 346return type and argument types as the wrapped system call. Their job 347is to execute the system call (generally by calling the implementation 348function) after having validated all arguments. 349 350The verifier is itself invoked by an automatically generated 351unmarshaller function which takes care of unpacking the register 352arguments from the architecture layer and casting them to the correct 353type. This is defined in a header file that must be included from 354user code, generally somewhere after the definition of the verifier in 355a translation unit (so that it can be inlined). 356 357For example: 358 359.. code-block:: c 360 361 static int z_vrfy_k_sem_take(struct k_sem *sem, int32_t timeout) 362 { 363 K_OOPS(K_SYSCALL_OBJ(sem, K_OBJ_SEM)); 364 return z_impl_k_sem_take(sem, timeout); 365 } 366 #include <zephyr/syscalls/k_sem_take_mrsh.c> 367 368 369Verification Memory Access Policies 370=================================== 371 372Parameters passed to system calls by reference require special handling, 373because the value of these parameters can be changed at any time by any 374user thread that has access to the memory that parameter points to. If the 375kernel makes any logical decisions based on the contents of this memory, this 376can open up the kernel to attacks even if checking is done. This is a class 377of exploits known as TOCTOU (Time Of Check to Time Of Use). 378 379The proper procedure to mitigate these attacks is to make a copies in the 380verification function, and only perform parameter checks on the copies, which 381user threads will never have access to. The implementation functions get passed 382the copy and not the original data sent by the user. The 383:c:func:`k_usermode_to_copy()` and :c:func:`k_usermode_from_copy()` APIs exist for 384this purpose. 385 386There is one exception in place, with respect to large data buffers which are 387only used to provide a memory area that is either only written to, or whose 388contents are never used for any validation or control flow. Further 389discussion of this later in this section. 390 391As a first example, consider a parameter which is used as an output parameter 392for some integral value: 393 394 395.. code-block:: c 396 397 int z_vrfy_some_syscall(int *out_param) 398 { 399 int local_out_param; 400 int ret; 401 402 ret = z_impl_some_syscall(&local_out_param); 403 K_OOPS(k_usermode_to_copy(out_param, &local_out_param, sizeof(*out_param))); 404 return ret; 405 } 406 407Here we have allocated ``local_out_param`` on the stack, passed its address to 408the implementation function, and then used :c:func:`k_usermode_to_copy()` to fill 409in the memory passed in by the caller. 410 411It might be tempting to do something more concise: 412 413.. code-block:: c 414 415 int z_vrfy_some_syscall(int *out_param) 416 { 417 K_OOPS(K_SYSCALL_MEMORY_WRITE(out_param, sizeof(*out_param))); 418 return z_impl_some_syscall(out_param); 419 } 420 421However, this is unsafe if the implementation ever does any reads to this 422memory as part of its logic. For example, it could be used to store some 423counter value, and this could be meddled with by user threads that have access 424to its memory. It is by far safest for small integral values to do the copying 425as shown in the first example. 426 427Some parameters may be input/output. For instance, it's not uncommon to see APIs 428which pass in a pointer to some ``size_t`` which is a maximum allowable size, 429which is then updated by the implementation to reflect the actual number of 430bytes processed. This too should use a stack copy: 431 432.. code-block:: c 433 434 int z_vrfy_in_out_syscall(size_t *size_ptr) 435 { 436 size_t size; 437 int ret; 438 439 K_OOPS(k_usermode_from_copy(&size, size_ptr, sizeof(size)); 440 ret = z_impl_in_out_syscall(&size); 441 K_OOPS(k_usermode_to_copy(size_ptr, &size, sizeof(size))); 442 return ret; 443 } 444 445Many system calls pass in structures or even linked data structures. All should 446be copied. Typically this is done by allocating copies on the stack: 447 448.. code-block:: c 449 450 struct bar { 451 ... 452 }; 453 454 struct foo { 455 ... 456 struct bar *bar_left; 457 struct bar *bar_right; 458 }; 459 460 int z_vrfy_must_alloc(struct foo *foo) 461 { 462 int ret; 463 struct foo foo_copy; 464 struct bar bar_right_copy; 465 struct bar bar_left_copy; 466 467 K_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo))); 468 K_OOPS(k_usermode_from_copy(&bar_right_copy, foo_copy.bar_right, 469 sizeof(struct bar))); 470 foo_copy.bar_right = &bar_right_copy; 471 K_OOPS(k_usermode_from_copy(&bar_left_copy, foo_copy.bar_left, 472 sizeof(struct bar))); 473 foo_copy.bar_left = &bar_left_copy; 474 475 return z_impl_must_alloc(&foo_copy); 476 } 477 478In some cases the amount of data isn't known at compile time or may be too 479large to allocate on the stack. In this scenario, it may be necessary to draw 480memory from the caller's resource pool via :c:func:`z_thread_malloc()`. This 481should always be considered last resort. Functional safety programming 482guidelines heavily discourage usage of heap and the fact that a resource pool is 483used must be clearly documented. Any issues with allocation must be 484reported, to a caller, with returning the ``-ENOMEM`` . The ``K_OOPS()`` 485should never be used to verify if resource allocation has been successful. 486 487.. code-block:: c 488 489 struct bar { 490 ... 491 }; 492 493 struct foo { 494 size_t count; 495 struct bar *bar_list; /* array of struct bar of size count */ 496 }; 497 498 int z_vrfy_must_alloc(struct foo *foo) 499 { 500 int ret; 501 struct foo foo_copy; 502 struct bar *bar_list_copy; 503 size_t bar_list_bytes; 504 505 /* Safely copy foo into foo_copy */ 506 K_OOPS(k_usermode_from_copy(&foo_copy, foo, sizeof(*foo))); 507 508 /* Bounds check the count member, in the copy we made */ 509 if (foo_copy.count > 32) { 510 return -EINVAL; 511 } 512 513 /* Allocate RAM for the bar_list, replace the pointer in 514 * foo_copy */ 515 bar_list_bytes = foo_copy.count * sizeof(struct_bar); 516 bar_list_copy = z_thread_malloc(bar_list_bytes); 517 if (bar_list_copy == NULL) { 518 return -ENOMEM; 519 } 520 K_OOPS(k_usermode_from_copy(bar_list_copy, foo_copy.bar_list, 521 bar_list_bytes)); 522 foo_copy.bar_list = bar_list_copy; 523 524 ret = z_impl_must_alloc(&foo_copy); 525 526 /* All done with the memory, free it and return */ 527 k_free(foo_copy.bar_list_copy); 528 return ret; 529 } 530 531Finally, we must consider large data buffers. These represent areas of user 532memory which either have data copied out of, or copied into. It is permitted 533to pass these pointers to the implementation function directly. The caller's 534access to the buffer still must be validated with ``K_SYSCALL_MEMORY`` APIs. 535The following constraints need to be met: 536 537 * If the buffer is used by the implementation function to write data, such 538 as data captured from some MMIO region, the implementation function must 539 only write this data, and never read it. 540 541 * If the buffer is used by the implementation function to read data, such 542 as a block of memory to write to some hardware destination, this data 543 must be read without any processing. No conditional logic can be implemented 544 due to the data buffer's contents. If such logic is required a copy must be 545 made. 546 547 * The buffer must only be used synchronously with the call. The implementation 548 must not ever save the buffer address and use it asynchronously, such as 549 when an interrupt fires. 550 551.. code-block:: c 552 553 int z_vrfy_get_data_from_kernel(void *buf, size_t size) 554 { 555 K_OOPS(K_SYSCALL_MEMORY_WRITE(buf, size)); 556 return z_impl_get_data_from_kernel(buf, size); 557 } 558 559Verification Return Value Policies 560================================== 561 562When verifying system calls, it's important to note which kinds of verification 563failures should propagate a return value to the caller, and which should 564simply invoke :c:macro:`K_OOPS()` which kills the calling thread. The current 565conventions are as follows: 566 567#. For system calls that are defined but not compiled, invocations of these 568 missing system calls are routed to :c:func:`handler_no_syscall()` which 569 invokes :c:macro:`K_OOPS()`. 570 571#. Any invalid access to memory found by the set of ``K_SYSCALL_MEMORY`` APIs, 572 :c:func:`k_usermode_from_copy()`, :c:func:`k_usermode_to_copy()` 573 should trigger a :c:macro:`K_OOPS`. This happens when the caller doesn't have 574 appropriate permissions on the memory buffer or some size calculation 575 overflowed. 576 577#. Most system calls take kernel object pointers as an argument, checked either 578 with one of the ``K_SYSCALL_OBJ`` functions, ``K_SYSCALL_DRIVER_nnnnn``, or 579 manually using :c:func:`k_object_validate()`. These can fail for a variety 580 of reasons: missing driver API, bad kernel object pointer, wrong kernel 581 object type, or improper initialization state. These issues should always 582 invoke :c:macro:`K_OOPS()`. 583 584#. Any error resulting from a failed memory heap allocation, often from 585 invoking :c:func:`z_thread_malloc()`, should propagate ``-ENOMEM`` to the 586 caller. 587 588#. General parameter checks should be done in the implementation function, 589 in most cases using ``CHECKIF()``. 590 591 * The behavior of ``CHECKIF()`` depends on the kernel configuration, but if 592 user mode is enabled, :kconfig:option:`CONFIG_RUNTIME_ERROR_CHECKS` is enforced, 593 which guarantees that these checks will be made and a return value 594 propagated. 595 596#. It is totally forbidden for any kind of kernel mode callback function to 597 be registered from user mode. APIs which simply install callbacks shall not 598 be exposed as system calls. Some driver subsystem APIs may take optional 599 function callback pointers. User mode verification functions for these APIs 600 must enforce that these are NULL and should invoke :c:macro:`K_OOPS()` if 601 not. 602 603#. Some parameter checks are enforced only from user mode. These should be 604 checked in the verification function and propagate a return value to the 605 caller if possible. 606 607There are some known exceptions to these policies currently in Zephyr: 608 609* :c:func:`k_thread_join()` and :c:func:`k_thread_abort()` are no-ops if 610 the thread object isn't initialized. This is because for threads, the 611 initialization bit pulls double-duty to indicate whether a thread is 612 running, cleared upon exit. See #23030. 613 614* :c:func:`k_thread_create()` invokes :c:macro:`K_OOPS()` for parameter 615 checks, due to a great deal of existing code ignoring the return value. 616 This will also be addressed by #23030. 617 618* :c:func:`k_thread_abort()` invokes :c:macro:`K_OOPS()` if an essential 619 thread is aborted, as the function has no return value. 620 621* Various system calls related to logging invoke :c:macro:`K_OOPS()` 622 when bad parameters are passed in as they do not propagate errors. 623 624Configuration Options 625********************* 626 627Related configuration options: 628 629* :kconfig:option:`CONFIG_USERSPACE` 630* :kconfig:option:`CONFIG_EMIT_ALL_SYSCALLS` 631 632APIs 633**** 634 635Helper macros for creating system call verification functions are provided in 636:zephyr_file:`include/zephyr/internal/syscall_handler.h`: 637 638* :c:macro:`K_SYSCALL_OBJ()` 639* :c:macro:`K_SYSCALL_OBJ_INIT()` 640* :c:macro:`K_SYSCALL_OBJ_NEVER_INIT()` 641* :c:macro:`K_OOPS()` 642* :c:macro:`K_SYSCALL_MEMORY_READ()` 643* :c:macro:`K_SYSCALL_MEMORY_WRITE()` 644* :c:macro:`K_SYSCALL_MEMORY_ARRAY_READ()` 645* :c:macro:`K_SYSCALL_MEMORY_ARRAY_WRITE()` 646* :c:macro:`K_SYSCALL_VERIFY_MSG()` 647* :c:macro:`K_SYSCALL_VERIFY` 648 649Functions for invoking system calls are defined in 650:zephyr_file:`include/zephyr/syscall.h`: 651 652* :c:func:`_arch_syscall_invoke0` 653* :c:func:`_arch_syscall_invoke1` 654* :c:func:`_arch_syscall_invoke2` 655* :c:func:`_arch_syscall_invoke3` 656* :c:func:`_arch_syscall_invoke4` 657* :c:func:`_arch_syscall_invoke5` 658* :c:func:`_arch_syscall_invoke6` 659