From 52f9aaa823322eedbd30bd37d40fe0f8a50ed6db Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Fri, 2 Jul 2021 14:02:36 +0200 Subject: [PATCH] Kernel: Use the GS segment for the per-CPU struct Right now we're using the FS segment for our per-CPU struct. On x86_64 there's an instruction to switch between a kernel and usermode GS segment (swapgs) which we could use. This patch doesn't update the rest of the code to use swapgs but it prepares for that by using the GS segment instead of the FS segment. --- Kernel/Arch/x86/ASM_wrapper.h | 12 +++++----- Kernel/Arch/x86/Processor.h | 16 ++++++------- Kernel/Arch/x86/common/Interrupts.cpp | 4 ++-- Kernel/Arch/x86/common/Processor.cpp | 30 ++++++++++++------------- Kernel/Arch/x86/i386/InterruptEntry.cpp | 2 +- Kernel/Arch/x86/i386/Processor.cpp | 2 +- Kernel/Syscall.cpp | 2 +- Kernel/Thread.cpp | 4 ++-- 8 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Kernel/Arch/x86/ASM_wrapper.h b/Kernel/Arch/x86/ASM_wrapper.h index cd5782a6922..09ff8eeb34f 100644 --- a/Kernel/Arch/x86/ASM_wrapper.h +++ b/Kernel/Arch/x86/ASM_wrapper.h @@ -62,25 +62,25 @@ ALWAYS_INLINE u16 get_gs() } #endif -ALWAYS_INLINE u32 read_fs_u32(u32 offset) +ALWAYS_INLINE u32 read_gs_u32(u32 offset) { u32 val; asm volatile( - "movl %%fs:%a[off], %k[val]" + "movl %%gs:%a[off], %k[val]" : [val] "=r"(val) : [off] "ir"(offset)); return val; } -ALWAYS_INLINE FlatPtr read_fs_ptr(u32 offset) +ALWAYS_INLINE FlatPtr read_gs_ptr(u32 offset) { - return read_fs_u32(offset); + return read_gs_u32(offset); } -ALWAYS_INLINE void write_fs_u32(u32 offset, u32 val) +ALWAYS_INLINE void write_gs_u32(u32 offset, u32 val) { asm volatile( - "movl %k[val], %%fs:%a[off]" ::[off] "ir"(offset), [val] "ir"(val) + "movl %k[val], %%gs:%a[off]" ::[off] "ir"(offset), [val] "ir"(val) : "memory"); } diff --git a/Kernel/Arch/x86/Processor.h b/Kernel/Arch/x86/Processor.h index ed6323a52dc..468584b2ef6 100644 --- a/Kernel/Arch/x86/Processor.h +++ b/Kernel/Arch/x86/Processor.h @@ -21,7 +21,7 @@ namespace Kernel { #if ARCH(X86_64) # define MSR_FS_BASE 0xc0000100 -# define MSR_GS_BASE 0xc0000102 +# define MSR_GS_BASE 0xc0000101 #endif class Thread; @@ -241,16 +241,16 @@ public: ALWAYS_INLINE static Processor& current() { - return *(Processor*)read_fs_ptr(__builtin_offsetof(Processor, m_self)); + return *(Processor*)read_gs_ptr(__builtin_offsetof(Processor, m_self)); } ALWAYS_INLINE static bool is_initialized() { return #if ARCH(I386) - get_fs() == GDT_SELECTOR_PROC && + get_gs() == GDT_SELECTOR_PROC && #endif - read_fs_u32(__builtin_offsetof(Processor, m_self)) != 0; + read_gs_u32(__builtin_offsetof(Processor, m_self)) != 0; } ALWAYS_INLINE void set_scheduler_data(SchedulerPerProcessorData& scheduler_data) @@ -286,19 +286,19 @@ public: // to another processor, which would lead us to get the wrong thread. // To avoid having to disable interrupts, we can just read the field // directly in an atomic fashion, similar to Processor::current. - return (Thread*)read_fs_ptr(__builtin_offsetof(Processor, m_current_thread)); + return (Thread*)read_gs_ptr(__builtin_offsetof(Processor, m_current_thread)); } ALWAYS_INLINE static void set_current_thread(Thread& current_thread) { // See comment in Processor::current_thread - write_fs_u32(__builtin_offsetof(Processor, m_current_thread), FlatPtr(¤t_thread)); + write_gs_u32(__builtin_offsetof(Processor, m_current_thread), FlatPtr(¤t_thread)); } ALWAYS_INLINE static Thread* idle_thread() { // See comment in Processor::current_thread - return (Thread*)read_fs_ptr(__builtin_offsetof(Processor, m_idle_thread)); + return (Thread*)read_gs_ptr(__builtin_offsetof(Processor, m_idle_thread)); } ALWAYS_INLINE u32 get_id() const @@ -314,7 +314,7 @@ public: ALWAYS_INLINE static u32 id() { // See comment in Processor::current_thread - return read_fs_ptr(__builtin_offsetof(Processor, m_cpu)); + return read_gs_ptr(__builtin_offsetof(Processor, m_cpu)); } ALWAYS_INLINE static bool is_bootstrap_processor() diff --git a/Kernel/Arch/x86/common/Interrupts.cpp b/Kernel/Arch/x86/common/Interrupts.cpp index 6f1ea326605..bf131cc91a2 100644 --- a/Kernel/Arch/x86/common/Interrupts.cpp +++ b/Kernel/Arch/x86/common/Interrupts.cpp @@ -58,7 +58,7 @@ static EntropySource s_entropy_source_interrupts { EntropySource::Static::Interr " mov %ax, %ds\n" \ " mov %ax, %es\n" \ " mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n" \ - " mov %ax, %fs\n" \ + " mov %ax, %gs\n" \ " pushl %esp \n" /* set TrapFrame::regs */ \ " subl $" __STRINGIFY(TRAP_FRAME_SIZE - 4) ", %esp \n" \ " pushl %esp \n" \ @@ -84,7 +84,7 @@ static EntropySource s_entropy_source_interrupts { EntropySource::Static::Interr " mov %ax, %ds\n" \ " mov %ax, %es\n" \ " mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n" \ - " mov %ax, %fs\n" \ + " mov %ax, %gs\n" \ " pushl %esp \n" /* set TrapFrame::regs */ \ " subl $" __STRINGIFY(TRAP_FRAME_SIZE - 4) ", %esp \n" \ " pushl %esp \n" \ diff --git a/Kernel/Arch/x86/common/Processor.cpp b/Kernel/Arch/x86/common/Processor.cpp index 089f2e54f43..652aa051443 100644 --- a/Kernel/Arch/x86/common/Processor.cpp +++ b/Kernel/Arch/x86/common/Processor.cpp @@ -1092,17 +1092,17 @@ UNMAP_AFTER_INIT void Processor::gdt_init() tls_descriptor.type = 2; write_gdt_entry(GDT_SELECTOR_TLS, tls_descriptor); // tls3 - Descriptor fs_descriptor {}; - fs_descriptor.set_base(VirtualAddress { this }); - fs_descriptor.set_limit(sizeof(Processor) - 1); - fs_descriptor.dpl = 0; - fs_descriptor.segment_present = 1; - fs_descriptor.granularity = 0; - fs_descriptor.operation_size64 = 0; - fs_descriptor.operation_size32 = 1; - fs_descriptor.descriptor_type = 1; - fs_descriptor.type = 2; - write_gdt_entry(GDT_SELECTOR_PROC, fs_descriptor); // fs0 + Descriptor gs_descriptor {}; + gs_descriptor.set_base(VirtualAddress { this }); + gs_descriptor.set_limit(sizeof(Processor) - 1); + gs_descriptor.dpl = 0; + gs_descriptor.segment_present = 1; + gs_descriptor.granularity = 0; + gs_descriptor.operation_size64 = 0; + gs_descriptor.operation_size32 = 1; + gs_descriptor.descriptor_type = 1; + gs_descriptor.type = 2; + write_gdt_entry(GDT_SELECTOR_PROC, gs_descriptor); // gs0 #endif Descriptor tss_descriptor {}; @@ -1127,16 +1127,16 @@ UNMAP_AFTER_INIT void Processor::gdt_init() load_task_register(GDT_SELECTOR_TSS); #if ARCH(X86_64) - MSR fs_base(MSR_FS_BASE); - fs_base.set((size_t)this & 0xffffffff, (size_t)this >> 32); + MSR gs_base(MSR_GS_BASE); + gs_base.set((size_t)this & 0xffffffff, (size_t)this >> 32); #else asm volatile( "mov %%ax, %%ds\n" "mov %%ax, %%es\n" - "mov %%ax, %%gs\n" + "mov %%ax, %%fs\n" "mov %%ax, %%ss\n" ::"a"(GDT_SELECTOR_DATA0) : "memory"); - set_fs(GDT_SELECTOR_PROC); + set_gs(GDT_SELECTOR_PROC); #endif #if ARCH(I386) diff --git a/Kernel/Arch/x86/i386/InterruptEntry.cpp b/Kernel/Arch/x86/i386/InterruptEntry.cpp index 0df2fd65331..156d0f71ade 100644 --- a/Kernel/Arch/x86/i386/InterruptEntry.cpp +++ b/Kernel/Arch/x86/i386/InterruptEntry.cpp @@ -21,7 +21,7 @@ asm( " mov %ax, %ds\n" " mov %ax, %es\n" " mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n" - " mov %ax, %fs\n" + " mov %ax, %gs\n" " pushl %esp \n" // set TrapFrame::regs " subl $" __STRINGIFY(TRAP_FRAME_SIZE - 4) ", %esp \n" " movl %esp, %ebx \n" // save pointer to TrapFrame diff --git a/Kernel/Arch/x86/i386/Processor.cpp b/Kernel/Arch/x86/i386/Processor.cpp index d69911d867f..f167edac6a0 100644 --- a/Kernel/Arch/x86/i386/Processor.cpp +++ b/Kernel/Arch/x86/i386/Processor.cpp @@ -174,7 +174,7 @@ FlatPtr Processor::init_context(Thread& thread, bool leave_crit) regs.es = GDT_SELECTOR_DATA0; regs.gs = GDT_SELECTOR_DATA0; regs.ss = GDT_SELECTOR_DATA0; - regs.fs = GDT_SELECTOR_PROC; + regs.gs = GDT_SELECTOR_PROC; return stack_top; } diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 74075d8542a..33aced3fa9b 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -38,7 +38,7 @@ NEVER_INLINE void syscall_asm_entry_dummy() " mov %ax, %ds\n" " mov %ax, %es\n" " mov $" __STRINGIFY(GDT_SELECTOR_PROC) ", %ax\n" - " mov %ax, %fs\n" + " mov %ax, %gs\n" " cld\n" " xor %esi, %esi\n" " xor %edi, %edi\n" diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index e11244ea8dd..296d73a1939 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -102,9 +102,9 @@ Thread::Thread(NonnullRefPtr process, NonnullOwnPtr kernel_stac m_regs.cs = GDT_SELECTOR_CODE0; m_regs.ds = GDT_SELECTOR_DATA0; m_regs.es = GDT_SELECTOR_DATA0; - m_regs.fs = GDT_SELECTOR_PROC; + m_regs.fs = 0; m_regs.ss = GDT_SELECTOR_DATA0; - m_regs.gs = 0; + m_regs.gs = GDT_SELECTOR_PROC; } else { m_regs.cs = GDT_SELECTOR_CODE3 | 3; m_regs.ds = GDT_SELECTOR_DATA3 | 3;