From b5cc70d7532938c675205c291d632fd2bcfef37c Mon Sep 17 00:00:00 2001 From: Julia Vassiliki Date: Fri, 13 Feb 2026 10:56:08 +1100 Subject: [PATCH] libsel4: make thread-local ipc buffer optional At the moment, the seL4 microkit does not setup TLS variable support. The workaround has been to `#define __thread` (blank) before including `` in ``, which causes issues if `` is included *after* ``, often with obscure linker errors to `__emutls_**` symbols. Instead we add a libsel4 config option that allows us to build it with __thread copied out. We introduce an LIBSEL4_THREAD_LOCAL macro in a similar way to the existing LIBSEL4_INLINE macro. Signed-off-by: Julia Vassiliki --- libsel4/CMakeLists.txt | 9 +++++++++ libsel4/include/sel4/functions.h | 4 ++-- libsel4/include/sel4/macros.h | 6 ++++++ libsel4/src/sel4_bootinfo.c | 4 ++-- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libsel4/CMakeLists.txt b/libsel4/CMakeLists.txt index 56f572058..3ff854a73 100644 --- a/libsel4/CMakeLists.txt +++ b/libsel4/CMakeLists.txt @@ -44,6 +44,15 @@ config_string( UNQUOTE ) +config_option( + LibSel4UseThreadLocals + LIB_SEL4_USE_THREAD_LOCALS + "mark the __sel4_ipc_buffer variable as thread local using '__thread'. \ + This requires thread local storage support and is useful if multiple \ + threads share the same virtual address space." + DEFAULT ON +) + if(LibSel4StubsUseIPCBufferOnly) set(buffer "--buffer") endif() diff --git a/libsel4/include/sel4/functions.h b/libsel4/include/sel4/functions.h index cd6c14452..f435c37fa 100644 --- a/libsel4/include/sel4/functions.h +++ b/libsel4/include/sel4/functions.h @@ -10,10 +10,10 @@ #include #include -extern __thread seL4_IPCBuffer *__sel4_ipc_buffer; +extern LIBSEL4_THREAD_LOCAL seL4_IPCBuffer *__sel4_ipc_buffer; #ifdef CONFIG_KERNEL_INVOCATION_REPORT_ERROR_IPC -extern __thread char __sel4_print_error; +extern LIBSEL4_THREAD_LOCAL char __sel4_print_error; LIBSEL4_INLINE_FUNC char *seL4_GetDebugError(void) { diff --git a/libsel4/include/sel4/macros.h b/libsel4/include/sel4/macros.h index 2ccc281f6..a9f4f3477 100644 --- a/libsel4/include/sel4/macros.h +++ b/libsel4/include/sel4/macros.h @@ -42,6 +42,12 @@ #endif +#if defined(CONFIG_LIB_SEL4_USE_THREAD_LOCALS) +#define LIBSEL4_THREAD_LOCAL __thread +#else +#define LIBSEL4_THREAD_LOCAL +#endif + /* _Static_assert() is a c11 feature. Since the kernel is currently compiled * with c99, we have to emulate it. */ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) diff --git a/libsel4/src/sel4_bootinfo.c b/libsel4/src/sel4_bootinfo.c index afee42729..5cd81d057 100644 --- a/libsel4/src/sel4_bootinfo.c +++ b/libsel4/src/sel4_bootinfo.c @@ -7,11 +7,11 @@ #include #ifdef CONFIG_KERNEL_INVOCATION_REPORT_ERROR_IPC -__thread char __sel4_print_error = CONFIG_LIB_SEL4_PRINT_INVOCATION_ERRORS; +LIBSEL4_THREAD_LOCAL char __sel4_print_error = CONFIG_LIB_SEL4_PRINT_INVOCATION_ERRORS; #endif /** Userland per-thread IPC buffer address **/ -__thread seL4_IPCBuffer *__sel4_ipc_buffer; +LIBSEL4_THREAD_LOCAL seL4_IPCBuffer *__sel4_ipc_buffer; /** Consider moving bootinfo into libsel4_startup */ seL4_BootInfo *bootinfo;