aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorFabian Imhof <fabian.imhof@ost.ch>2025-04-30 12:53:44 +0000
committerFabian Imhof <fabian.imhof@ost.ch>2025-04-30 12:53:44 +0000
commitf0627d43909a8c19f41f3699757918c0185b5f1a (patch)
treefdfaf4274c67386b7ec3c92170090b9f4a1b68e3 /arch
parentecdfbc3e1458923f619f0d4b8a841a6e96a6678a (diff)
downloadteachos-f0627d43909a8c19f41f3699757918c0185b5f1a.tar.xz
teachos-f0627d43909a8c19f41f3699757918c0185b5f1a.zip
fix cs register after sysretq
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/src/context_switching/main.cpp16
1 files changed, 6 insertions, 10 deletions
diff --git a/arch/x86_64/src/context_switching/main.cpp b/arch/x86_64/src/context_switching/main.cpp
index 2a2a188..8d1c019 100644
--- a/arch/x86_64/src/context_switching/main.cpp
+++ b/arch/x86_64/src/context_switching/main.cpp
@@ -42,7 +42,7 @@ namespace teachos::arch::context_switching
: "memory");
asm volatile("syscall");
- video::vga::text::write("Successfully made a SYSCALL and returned back with SYSRETQ!",
+ video::vga::text::write("Successfully made a SYSCALL and returned with SYSRETQ!",
video::vga::text::common_attributes::green_on_black);
}
@@ -70,16 +70,12 @@ namespace teachos::arch::context_switching
{
uint64_t const syscall_function = reinterpret_cast<uint64_t>(syscall_handler);
kernel::cpu::write_msr(IA32_LSTAR_ADDRESS, syscall_function);
- kernel::cpu::write_msr(IA32_FMASK_ADDRESS, 1 << 9U); // Disable interrupt flag during syscall
-
- // @MTO: This produces following values:
- // After SYSCALL: CS = 0x10, SS = 0x18
- // After SYSRETQ: CS = 0x43, SS = 0x3b
- //
- // We probably need to modify our GDT, because the cs+8 = ss is an issue we cannot solve.
- // Also, CS = 0x43 is weird. I expected it to be 0x33.
+ kernel::cpu::write_msr(IA32_FMASK_ADDRESS, 1 << 9U); // Disable interrupt flag during syscall.
+
uint64_t kernel_cs = KERNEL_CODE_SEGMENT_SELECTOR;
- uint64_t user_cs = USER_CODE_SEGMENT_SELECTOR;
+ // We want to provide the user code segment, but the instruction calculates + 0x10 to fill the
+ // cs register (See https://www.felixcloutier.com/x86/sysret).
+ uint64_t user_cs = USER_CODE_SEGMENT_SELECTOR - 0x10;
uint64_t star_value = (kernel_cs << 32) | (user_cs << 48);
kernel::cpu::write_msr(IA32_STAR_ADDRESS, star_value);