diff options
| author | Fabian Imhof <fabian.imhof@ost.ch> | 2025-04-30 12:53:44 +0000 |
|---|---|---|
| committer | Fabian Imhof <fabian.imhof@ost.ch> | 2025-04-30 12:53:44 +0000 |
| commit | f0627d43909a8c19f41f3699757918c0185b5f1a (patch) | |
| tree | fdfaf4274c67386b7ec3c92170090b9f4a1b68e3 /arch/x86_64 | |
| parent | ecdfbc3e1458923f619f0d4b8a841a6e96a6678a (diff) | |
| download | teachos-f0627d43909a8c19f41f3699757918c0185b5f1a.tar.xz teachos-f0627d43909a8c19f41f3699757918c0185b5f1a.zip | |
fix cs register after sysretq
Diffstat (limited to 'arch/x86_64')
| -rw-r--r-- | arch/x86_64/src/context_switching/main.cpp | 16 |
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); |
