Pārlūkot izejas kodu

Kernel/aarch64: Implement Thread Local Storage

This commit adds Processor::set_thread_specific_data, and this function
is used to factor out architecture specific implementation of setting
the thread specific data. This function is implemented for
aarch64 and x86_64, and the callsites are changed to use this function
instead.
Timon Kruiper 2 gadi atpakaļ
vecāks
revīzija
cfd73e5d9f

+ 5 - 0
Kernel/Arch/aarch64/ASM_wrapper.h

@@ -37,6 +37,11 @@ inline void set_sp_el1(FlatPtr sp_el1)
     asm("msr sp_el1, %[value]" ::[value] "r"(sp_el1));
 }
 
+inline void set_tpidr_el0(FlatPtr tpidr_el0)
+{
+    asm("msr tpidr_el0, %[value]" ::[value] "r"(tpidr_el0));
+}
+
 inline void flush()
 {
     asm("dsb ish");

+ 7 - 0
Kernel/Arch/aarch64/Processor.cpp

@@ -454,6 +454,8 @@ extern "C" void enter_thread_context(Thread* from_thread, Thread* to_thread)
 
     to_thread->set_cpu(Processor::current().id());
 
+    Processor::set_thread_specific_data(to_thread->thread_specific_data());
+
     auto in_critical = to_thread->saved_critical();
     VERIFY(in_critical > 0);
     Processor::restore_critical(in_critical);
@@ -466,4 +468,9 @@ StringView Processor::platform_string()
     return "aarch64"sv;
 }
 
+void Processor::set_thread_specific_data(VirtualAddress thread_specific_data)
+{
+    Aarch64::Asm::set_tpidr_el0(thread_specific_data.get());
+}
+
 }

+ 2 - 0
Kernel/Arch/aarch64/Processor.h

@@ -279,6 +279,8 @@ public:
 
     static StringView platform_string();
 
+    static void set_thread_specific_data(VirtualAddress thread_specific_data);
+
 private:
     Processor(Processor const&) = delete;
 

+ 7 - 2
Kernel/Arch/x86_64/Processor.cpp

@@ -1543,8 +1543,7 @@ extern "C" void enter_thread_context(Thread* from_thread, Thread* to_thread)
     }
 
     auto& processor = Processor::current();
-    MSR fs_base_msr(MSR_FS_BASE);
-    fs_base_msr.set(to_thread->thread_specific_data().get());
+    Processor::set_thread_specific_data(to_thread->thread_specific_data());
 
     if (from_regs.cr3 != to_regs.cr3)
         write_cr3(to_regs.cr3);
@@ -1887,4 +1886,10 @@ UNMAP_AFTER_INIT void Processor::initialize_context_switching(Thread& initial_th
     VERIFY_NOT_REACHED();
 }
 
+void Processor::set_thread_specific_data(VirtualAddress thread_specific_data)
+{
+    MSR fs_base_msr(MSR_FS_BASE);
+    fs_base_msr.set(thread_specific_data.get());
+}
+
 }

+ 2 - 0
Kernel/Arch/x86_64/Processor.h

@@ -419,6 +419,8 @@ public:
     static ErrorOr<Vector<FlatPtr, 32>> capture_stack_trace(Thread& thread, size_t max_frames = 0);
 
     static StringView platform_string();
+
+    static void set_thread_specific_data(VirtualAddress thread_specific_data);
 };
 
 }

+ 1 - 4
Kernel/Syscalls/mmap.cpp

@@ -566,10 +566,7 @@ ErrorOr<FlatPtr> Process::sys$allocate_tls(Userspace<char const*> initial_data,
 
         TRY(main_thread->make_thread_specific_region({}));
 
-#if ARCH(X86_64)
-        MSR fs_base_msr(MSR_FS_BASE);
-        fs_base_msr.set(main_thread->thread_specific_data().get());
-#endif
+        Processor::set_thread_specific_data(main_thread->thread_specific_data());
 
         return m_master_tls_region.unsafe_ptr()->vaddr().get();
     });