diff --git a/arch/x86/core/intel64.cmake b/arch/x86/core/intel64.cmake index a50a1732681..cd37d5c497e 100644 --- a/arch/x86/core/intel64.cmake +++ b/arch/x86/core/intel64.cmake @@ -17,5 +17,5 @@ zephyr_library_sources( ) zephyr_library_sources_ifdef(CONFIG_USERSPACE intel64/userspace.S) - +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE intel64/tls.c) zephyr_library_sources_ifdef(CONFIG_DEBUG_COREDUMP intel64/coredump.c) diff --git a/arch/x86/core/intel64/locore.S b/arch/x86/core/intel64/locore.S index ff6c3a4abf3..a71c31338ab 100644 --- a/arch/x86/core/intel64/locore.S +++ b/arch/x86/core/intel64/locore.S @@ -261,6 +261,11 @@ enter_code64: /* Enter C domain now that we have a stack set up, never to return */ movq %rbp, %rdi +#ifdef CONFIG_STACK_CANARIES_TLS + pushq %rsp + call z_x86_early_tls_update_gdt + popq %rsp +#endif call z_x86_cpu_init /* 64 bit OS entry point, used by EFI support. UEFI diff --git a/arch/x86/core/intel64/tls.c b/arch/x86/core/intel64/tls.c new file mode 100644 index 00000000000..e932518b945 --- /dev/null +++ b/arch/x86/core/intel64/tls.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +FUNC_NO_STACK_PROTECTOR +void z_x86_early_tls_update_gdt(char *stack_ptr) +{ + uintptr_t *self_ptr; + uint32_t fs_base = X86_FS_BASE; + + /* + * Since we are populating things backwards, store + * the pointer to the TLS area at top of stack. + */ + stack_ptr -= sizeof(uintptr_t); + self_ptr = (void *)stack_ptr; + *self_ptr = POINTER_TO_UINT(stack_ptr); + + __asm__ volatile( + "movl %0, %%ecx;\n\t" + "movq %1, %%rax;\n\t" + "movq %1, %%rdx;\n\t" + "shrq $32, %%rdx;\n\t" + "wrmsr;\n\t" + : + : "r"(fs_base), "r"(POINTER_TO_UINT(self_ptr))); +}