From 7353c7f95d7d07d647ff5ff07d7f77bb8c733b62 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Thu, 6 Feb 2020 13:39:03 -0800 Subject: [PATCH] kernel/userspace: Move syscall_frame field to thread struct The syscall exception frame was stored on the CPU struct during syscall execution, but that's not right. System calls might "feel like" exceptions, but they're actually perfectly normal kernel mode code and can be preempted and migrated between CPUs at any time. Put the field on the thread struct. Signed-off-by: Andy Ross --- include/kernel.h | 3 +++ include/kernel_structs.h | 5 ----- include/syscall_handler.h | 2 +- kernel/userspace.c | 4 ++-- scripts/gen_syscalls.py | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/include/kernel.h b/include/kernel.h index 8faf04c5a1c..196a94e78a2 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -597,8 +597,11 @@ struct k_thread { struct _mem_domain_info mem_domain_info; /** Base address of thread stack */ k_thread_stack_t *stack_obj; + /** current syscall frame pointer */ + void *syscall_frame; #endif /* CONFIG_USERSPACE */ + #if defined(CONFIG_USE_SWITCH) /* When using __switch() a few previously arch-specific items * become part of the core OS diff --git a/include/kernel_structs.h b/include/kernel_structs.h index 198876bb804..1970faa6e16 100644 --- a/include/kernel_structs.h +++ b/include/kernel_structs.h @@ -110,11 +110,6 @@ struct _cpu { /* one assigned idle thread per CPU */ struct k_thread *idle_thread; -#ifdef CONFIG_USERSPACE - /* current syscall frame pointer */ - void *syscall_frame; -#endif - #if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && (CONFIG_NUM_COOP_PRIORITIES > 0) /* Coop thread preempted by current metairq, or NULL */ struct k_thread *metairq_preempted; diff --git a/include/syscall_handler.h b/include/syscall_handler.h index f2e17906b70..4a0ec651a1e 100644 --- a/include/syscall_handler.h +++ b/include/syscall_handler.h @@ -259,7 +259,7 @@ extern int z_user_string_copy(char *dst, const char *src, size_t maxlen); #define Z_OOPS(expr) \ do { \ if (expr) { \ - arch_syscall_oops(_current_cpu->syscall_frame); \ + arch_syscall_oops(_current->syscall_frame); \ } \ } while (false) diff --git a/kernel/userspace.c b/kernel/userspace.c index 88d60715974..c54a22898f1 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -760,7 +760,7 @@ static uintptr_t handler_bad_syscall(uintptr_t bad_id, uintptr_t arg2, void *ssf) { LOG_ERR("Bad system call id %" PRIuPTR " invoked", bad_id); - arch_syscall_oops(_current_cpu->syscall_frame); + arch_syscall_oops(_current->syscall_frame); CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ } @@ -769,7 +769,7 @@ static uintptr_t handler_no_syscall(uintptr_t arg1, uintptr_t arg2, uintptr_t arg5, uintptr_t arg6, void *ssf) { LOG_ERR("Unimplemented system call"); - arch_syscall_oops(_current_cpu->syscall_frame); + arch_syscall_oops(_current->syscall_frame); CODE_UNREACHABLE; /* LCOV_EXCL_LINE */ } diff --git a/scripts/gen_syscalls.py b/scripts/gen_syscalls.py index 2e75bd511e6..ae7e250a8e5 100755 --- a/scripts/gen_syscalls.py +++ b/scripts/gen_syscalls.py @@ -255,7 +255,7 @@ def marshall_defs(func_name, func_type, args): else: mrsh += "\t\t" + "uintptr_t arg3, uintptr_t arg4, void *more, void *ssf)\n" mrsh += "{\n" - mrsh += "\t" + "_current_cpu->syscall_frame = ssf;\n" + mrsh += "\t" + "_current->syscall_frame = ssf;\n" for unused_arg in range(nmrsh, 6): mrsh += "\t(void) arg%d;\t/* unused */\n" % unused_arg