From 3874e0ed1e19ca5f2a95011f9f9c07132d7c0a5e Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 2 May 2026 18:10:10 +0300 Subject: [PATCH] Kernel: Pass current cpu index as a GDT limit I had no idea LSL was an instruction. This cleans up code to get the current cpu by a lot and does not require extra segment usage :D --- kernel/include/kernel/API/SharedPage.h | 2 +- kernel/include/kernel/GDT.h | 16 ++++++++++++---- kernel/include/kernel/Thread.h | 2 -- kernel/kernel/GDT.cpp | 2 ++ kernel/kernel/Process.cpp | 2 -- kernel/kernel/Processor.cpp | 3 +-- kernel/kernel/Thread.cpp | 17 +---------------- userspace/libraries/LibC/sched.cpp | 11 +++-------- userspace/libraries/LibC/time.cpp | 10 +++------- 9 files changed, 23 insertions(+), 42 deletions(-) diff --git a/kernel/include/kernel/API/SharedPage.h b/kernel/include/kernel/API/SharedPage.h index 1685f445..1fb38511 100644 --- a/kernel/include/kernel/API/SharedPage.h +++ b/kernel/include/kernel/API/SharedPage.h @@ -12,7 +12,7 @@ namespace Kernel::API struct SharedPage { - uint8_t __sequence[0x100]; + uint16_t gdt_cpu_offset; uint32_t features; diff --git a/kernel/include/kernel/GDT.h b/kernel/include/kernel/GDT.h index bdb42c4f..8e3e9229 100644 --- a/kernel/include/kernel/GDT.h +++ b/kernel/include/kernel/GDT.h @@ -133,6 +133,12 @@ namespace Kernel void set_gsbase(uintptr_t addr); #endif + static uint16_t cpu_index_offset() { return m_cpu_index_offset; } + void set_cpu_index(uint8_t index) + { + write_entry(m_cpu_index_offset, 0, index, 0xF2, 0x4); + } + private: GDT() = default; @@ -151,11 +157,13 @@ namespace Kernel private: #if ARCH(x86_64) - BAN::Array m_gdt; // null, kernel code, kernel data, user code (32 bit), user data, user code (64 bit), tss low, tss high - static constexpr uint16_t m_tss_offset = 0x30; + BAN::Array m_gdt; // null, kernel code, kernel data, user code (32 bit), user data, user code (64 bit), cpu-index, tss low, tss high + static constexpr uint16_t m_cpu_index_offset = 0x30; + static constexpr uint16_t m_tss_offset = 0x38; #elif ARCH(i686) - BAN::Array m_gdt; // null, kernel code, kernel data, user code, user data, processor data, fsbase, gsbase, tss - static constexpr uint16_t m_tss_offset = 0x40; + BAN::Array m_gdt; // null, kernel code, kernel data, user code, user data, processor data, fsbase, gsbase, cpu-index, tss + static constexpr uint16_t m_cpu_index_offset = 0x40; + static constexpr uint16_t m_tss_offset = 0x48; #endif TaskStateSegment m_tss; const GDTR m_gdtr { diff --git a/kernel/include/kernel/Thread.h b/kernel/include/kernel/Thread.h index dee14e44..845ebe03 100644 --- a/kernel/include/kernel/Thread.h +++ b/kernel/include/kernel/Thread.h @@ -178,9 +178,7 @@ namespace Kernel bool m_is_userspace { false }; bool m_delete_process { false }; - bool m_has_custom_fsbase { false }; vaddr_t m_fsbase { 0 }; - bool m_has_custom_gsbase { false }; vaddr_t m_gsbase { 0 }; SchedulerQueue::Node* m_scheduler_node { nullptr }; diff --git a/kernel/kernel/GDT.cpp b/kernel/kernel/GDT.cpp index a83f1980..3bada69a 100644 --- a/kernel/kernel/GDT.cpp +++ b/kernel/kernel/GDT.cpp @@ -32,6 +32,8 @@ namespace Kernel gdt->write_entry(0x38, 0x00000000, 0x00000, 0xF2, 0xC); // gsbase #endif + gdt->write_entry(m_cpu_index_offset, 0, 0, 0, 0); + gdt->write_tss(); return gdt; diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 4689cf61..38381957 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -3314,7 +3314,6 @@ namespace Kernel BAN::ErrorOr Process::sys_set_fsbase(void* addr) { auto& thread = Thread::current(); - thread.m_has_custom_fsbase = true; thread.set_fsbase(reinterpret_cast(addr)); Processor::load_fsbase(); return 0; @@ -3328,7 +3327,6 @@ namespace Kernel BAN::ErrorOr Process::sys_set_gsbase(void* addr) { auto& thread = Thread::current(); - thread.m_has_custom_gsbase = true; thread.set_gsbase(reinterpret_cast(addr)); Processor::load_gsbase(); return 0; diff --git a/kernel/kernel/Processor.cpp b/kernel/kernel/Processor.cpp index 17e34a3a..2001af0d 100644 --- a/kernel/kernel/Processor.cpp +++ b/kernel/kernel/Processor.cpp @@ -217,8 +217,7 @@ namespace Kernel memset(reinterpret_cast(s_shared_page_vaddr), 0, PAGE_SIZE); auto& shared_page = *reinterpret_cast(s_shared_page_vaddr); - for (size_t i = 0; i <= 0xFF; i++) - shared_page.__sequence[i] = i; + shared_page.gdt_cpu_offset = GDT::cpu_index_offset(); shared_page.features = 0; ASSERT(Processor::count() + sizeof(Kernel::API::SharedPage) <= PAGE_SIZE); diff --git a/kernel/kernel/Thread.cpp b/kernel/kernel/Thread.cpp index 3da3c6fa..43b23849 100644 --- a/kernel/kernel/Thread.cpp +++ b/kernel/kernel/Thread.cpp @@ -303,22 +303,7 @@ namespace Kernel { if (!is_userspace() || !has_process()) return; - -#if ARCH(x86_64) - if (m_has_custom_gsbase) - return; -#elif ARCH(i686) - if (m_has_custom_fsbase) - return; -#endif - - const vaddr_t vaddr = process().shared_page_vaddr() + Processor::current_index(); - -#if ARCH(x86_64) - set_gsbase(vaddr); -#elif ARCH(i686) - set_fsbase(vaddr); -#endif + Processor::gdt().set_cpu_index(Processor::current_index()); } BAN::ErrorOr Thread::pthread_create(entry_t entry, void* arg) diff --git a/userspace/libraries/LibC/sched.cpp b/userspace/libraries/LibC/sched.cpp index 736ca6c4..08e6ad2e 100644 --- a/userspace/libraries/LibC/sched.cpp +++ b/userspace/libraries/LibC/sched.cpp @@ -27,12 +27,7 @@ int sched_getcpu(void) { if (g_shared_page == nullptr) return -1; - - uint8_t cpu; -#if defined(__x86_64__) - asm volatile("movb %%gs:0, %0" : "=r"(cpu)); -#elif defined(__i686__) - asm volatile("movb %%fs:0, %0" : "=q"(cpu)); -#endif - return cpu; + uint16_t limit; + asm volatile("lsl %1, %0" : "=r"(limit) : "r"(g_shared_page->gdt_cpu_offset)); + return limit; } diff --git a/userspace/libraries/LibC/time.cpp b/userspace/libraries/LibC/time.cpp index da200205..1c4b53a5 100644 --- a/userspace/libraries/LibC/time.cpp +++ b/userspace/libraries/LibC/time.cpp @@ -30,13 +30,9 @@ int clock_gettime(clockid_t clock_id, struct timespec* tp) const auto get_cpu = []() -> uint8_t { - uint8_t cpu; -#if defined(__x86_64__) - asm volatile("movb %%gs:0, %0" : "=r"(cpu)); -#elif defined(__i686__) - asm volatile("movb %%fs:0, %0" : "=q"(cpu)); -#endif - return cpu; + uint16_t limit; + asm volatile("lsl %1, %0" : "=r"(limit) : "r"(g_shared_page->gdt_cpu_offset)); + return limit; }; for (;;)