From 187eba4eca3ea46d8c26419168e525242338dae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Sun, 27 Apr 2025 13:18:49 +0000 Subject: Simplify syscall setup --- .../arch/context_switching/syscall_handler.hpp | 1 + .../include/arch/kernel/cpu/segment_register.hpp | 1 + arch/x86_64/src/context_switching/main.cpp | 40 +++++++--------------- .../src/context_switching/syscall_handler.cpp | 1 - arch/x86_64/src/kernel/cpu/segment_register.cpp | 1 - 5 files changed, 14 insertions(+), 30 deletions(-) diff --git a/arch/x86_64/include/arch/context_switching/syscall_handler.hpp b/arch/x86_64/include/arch/context_switching/syscall_handler.hpp index 8583051..5a46924 100644 --- a/arch/x86_64/include/arch/context_switching/syscall_handler.hpp +++ b/arch/x86_64/include/arch/context_switching/syscall_handler.hpp @@ -3,6 +3,7 @@ namespace teachos::arch::context_switching { + [[gnu::naked]] auto syscall_handler() -> void; } #endif \ No newline at end of file diff --git a/arch/x86_64/include/arch/kernel/cpu/segment_register.hpp b/arch/x86_64/include/arch/kernel/cpu/segment_register.hpp index 6a2ca3e..36ada23 100644 --- a/arch/x86_64/include/arch/kernel/cpu/segment_register.hpp +++ b/arch/x86_64/include/arch/kernel/cpu/segment_register.hpp @@ -86,6 +86,7 @@ namespace teachos::arch::kernel::cpu * @param code_segment Code Segment that should be loaded into the CS register. * @param address Function that we want to call in the new context created by the given Code Segment. */ + [[gnu::naked]] auto set_code_segment_register(context_switching::interrupt_descriptor_table::segment_selector data_segment, context_switching::interrupt_descriptor_table::segment_selector code_segment, uint64_t address) -> void; diff --git a/arch/x86_64/src/context_switching/main.cpp b/arch/x86_64/src/context_switching/main.cpp index 85cefe5..155d150 100644 --- a/arch/x86_64/src/context_switching/main.cpp +++ b/arch/x86_64/src/context_switching/main.cpp @@ -6,6 +6,7 @@ #include "arch/kernel/cpu/call.hpp" #include "arch/kernel/cpu/control_register.hpp" #include "arch/kernel/cpu/if.hpp" +#include "arch/kernel/cpu/msr.hpp" #include "arch/kernel/cpu/segment_register.hpp" #include "arch/kernel/cpu/tr.hpp" #include "arch/video/vga/text.hpp" @@ -14,6 +15,10 @@ namespace teachos::arch::context_switching { namespace { + auto constexpr IA32_STAR_ADDRESS = 0xC0000081; + auto constexpr IA32_LSTAR_ADDRESS = 0xC0000082; + auto constexpr IA32_FMASK_ADDRESS = 0xC0000084; + constexpr interrupt_descriptor_table::segment_selector KERNEL_CODE_SEGMENT_SELECTOR{ 1U, interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_KERNEL}; constexpr kernel::cpu::far_pointer KERNEL_CODE_POINTER{&kernel::cpu::reload_data_segment_registers, @@ -74,34 +79,13 @@ namespace teachos::arch::context_switching auto setup_syscall() -> void { - uint64_t handler = reinterpret_cast(syscall_handler); - asm volatile( - /* Write syscall_handler pointer in IA32_LSTAR MSR */ - "mov $0xC0000082, %%ecx\n" /* IA32_LSTAR MSR */ - "mov %[syscall_handler], %%rax" - "mov %[syscall_handler], %%rdx" - "shr $32, %%rdx\n" - "wrmsr\n" - - /* Write RFLAGS Mask in IA32_LSTAR MSR */ - "mov $0xC0000084, %%ecx\n" /* IA32_FMASK MSR */ - "mov $0x0, %%rax\n" /* RFLAGS Mask lower 32 bits */ - "mov $0x0, %%rdx\n" /* RFLAGS Mask upper 32 bits */ - "wrmsr\n" - - /* Write kernel code segment offset in IA32_STAR MSR */ - "mov $0xC0000081, %%ecx\n" /* IA32_STAR MSR */ - "mov $0x10, %%rax\n" /* kernel code segment offset lower 32 bits */ - "mov $0x0, %%rdx\n" /* kernel code segment offset upper 32 bits */ - "wrmsr\n" - - /* Set SCE bit in MSR_EFER (enabling syscall instruction)*/ - "mov $0xC0000080, %%ecx\n" - "rdmsr\n" - "or $0x1, %%eax\n" - "wrmsr" - : /* no output from call */ - : [syscall_handler] "r"(handler)); + uint64_t const syscall_function = reinterpret_cast(syscall_handler); + uint64_t const segment_selector = *reinterpret_cast(&KERNEL_CODE_SEGMENT_SELECTOR); + + kernel::cpu::write_msr(IA32_LSTAR_ADDRESS, syscall_function); + kernel::cpu::write_msr(IA32_FMASK_ADDRESS, 0U); + kernel::cpu::write_msr(IA32_STAR_ADDRESS, segment_selector); + kernel::cpu::set_efer_bit(kernel::cpu::efer_flags::SCE); } } // namespace teachos::arch::context_switching diff --git a/arch/x86_64/src/context_switching/syscall_handler.cpp b/arch/x86_64/src/context_switching/syscall_handler.cpp index 1bc4ef9..283d297 100644 --- a/arch/x86_64/src/context_switching/syscall_handler.cpp +++ b/arch/x86_64/src/context_switching/syscall_handler.cpp @@ -4,7 +4,6 @@ namespace teachos::arch::context_switching { - [[gnu::naked]] auto syscall_handler() -> void { uint64_t dummy{}; diff --git a/arch/x86_64/src/kernel/cpu/segment_register.cpp b/arch/x86_64/src/kernel/cpu/segment_register.cpp index b59cd1b..b08c9c4 100644 --- a/arch/x86_64/src/kernel/cpu/segment_register.cpp +++ b/arch/x86_64/src/kernel/cpu/segment_register.cpp @@ -78,7 +78,6 @@ namespace teachos::arch::kernel::cpu validate_code_segment_register(code_segment); } - [[gnu::naked]] auto set_code_segment_register(context_switching::interrupt_descriptor_table::segment_selector data_segment, context_switching::interrupt_descriptor_table::segment_selector code_segment, uint64_t address) -> void -- cgit v1.2.3