tests/subsys/llext: Add syscall tests

Check if syscalls can be accessed from both kernel and userspace, and if
optimised away ones indeed point to NULL.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
This commit is contained in:
Ederson de Souza
2024-03-22 16:47:49 -07:00
committed by Anas Nashif
parent 8a2262431f
commit df916387f1
5 changed files with 77 additions and 1 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ target_include_directories(app PRIVATE
if(NOT LOADER_BUILD_ONLY)
# generate extension targets foreach extension given by name
foreach(ext_name hello_world logging relative_jump object)
foreach(ext_name hello_world logging relative_jump object syscalls)
set(ext_src ${PROJECT_SOURCE_DIR}/src/${ext_name}_ext.c)
set(ext_bin ${ZEPHYR_BINARY_DIR}/${ext_name}.llext)
set(ext_inc ${ZEPHYR_BINARY_DIR}/include/generated/${ext_name}.inc)
+2
View File
@@ -4,3 +4,5 @@ CONFIG_LOG=y
CONFIG_LLEXT=y
CONFIG_LLEXT_HEAP_SIZE=16
CONFIG_LLEXT_LOG_LEVEL_DBG=y
CONFIG_APPLICATION_DEFINED_SYSCALL=y
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2024 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* This code demonstrates syscall support.
*/
#include <zephyr/llext/symbol.h>
#include <zephyr/sys/printk.h>
#include "syscalls_ext.h"
void test_entry(void)
{
int input = 41;
printk("Input: %d Expected output: %d Actual output: %d\n",
input, input + 1, ext_syscall_ok(input));
}
LL_EXTENSION_SYMBOL(test_entry);
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2024 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/sys/util.h>
__syscall int ext_syscall_ok(int a);
/*
* This is a syscall that is intentionally not implemented. The build
* syscall machinery will still pick it up and generate a stub for it,
* that should be optmised away. For extensions, the symbol will end up
* pointing to NULL. This is tested in the test_ext_syscall_fail test.
*/
__syscall void ext_syscall_fail(void);
#include <syscalls/syscalls_ext.h>
@@ -11,6 +11,8 @@
#include <zephyr/logging/log.h>
#include <zephyr/sys/libc-hooks.h>
#include "syscalls_ext.h"
LOG_MODULE_REGISTER(test_llext_simple);
@@ -43,6 +45,19 @@ void llext_entry(void *arg0, void *arg1, void *arg2)
}
#endif /* CONFIG_USERSPACE */
int z_impl_ext_syscall_ok(int a)
{
return a + 1;
}
#ifdef CONFIG_USERSPACE
static inline int z_vrfy_ext_syscall_ok(int a)
{
return z_impl_ext_syscall_ok(a);
}
#include <syscalls/ext_syscall_ok_mrsh.c>
#endif /* CONFIG_USERSPACE */
void load_call_unload(struct llext_test *test_case)
{
struct llext_buf_loader buf_loader =
@@ -158,6 +173,11 @@ static LLEXT_CONST uint8_t object_ext[] __aligned(4) = {
#include "object.inc"
};
LLEXT_LOAD_UNLOAD(object, true)
static LLEXT_CONST uint8_t syscalls_ext[] __aligned(4) = {
#include "syscalls.inc"
};
LLEXT_LOAD_UNLOAD(syscalls, true)
#endif /* ! LOADER_BUILD_ONLY */
/*
@@ -171,5 +191,17 @@ ZTEST(llext, test_printk_exported)
zassert_equal(printk_fn, printk, "printk should be an exported symbol");
}
/*
* Ensure ext_syscall_fail is exported - as it is picked up by the syscall
* build machinery - but points to NULL as it is not implemented.
*/
ZTEST(llext, test_ext_syscall_fail)
{
const void * const esf_fn = llext_find_sym(NULL,
"z_impl_ext_syscall_fail");
zassert_is_null(*(uintptr_t **)esf_fn, NULL,
"ext_syscall_fail should be NULL");
}
ZTEST_SUITE(llext, NULL, NULL, NULL, NULL, NULL);