diff options
author | Timon Kruiper <timonkruiper@gmail.com> | 2023-02-21 21:21:03 +0100 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2023-04-06 21:19:58 +0300 |
commit | 6a8581855d4e32ba0da328cd89642d0154484b96 (patch) | |
tree | 68c4cb84488db9c6fe60188b8c612f2ab6e20036 /Kernel/Arch | |
parent | 188a52db01eed9a5e169eb61ca35fc82f2142cf1 (diff) | |
download | serenity-6a8581855d4e32ba0da328cd89642d0154484b96.zip |
Kernel/aarch64: Flush entire TLB cache when changing TTBR0_EL1
Setting the page table base register (ttbr0_el1) is not enough, and will
not flush the TLB caches, in contrary with x86_64 where setting the CR3
register will actually flush the caches. This commit adds the necessary
code to properly flush the TLB caches when context switching. This
commit also changes Processor::flush_tlb_local to use the vmalle1
variant, as previously we would be flushing the tlb's of all the cores
in the inner-shareable domain.
Diffstat (limited to 'Kernel/Arch')
-rw-r--r-- | Kernel/Arch/aarch64/PageDirectory.cpp | 2 | ||||
-rw-r--r-- | Kernel/Arch/aarch64/Processor.cpp | 14 | ||||
-rw-r--r-- | Kernel/Arch/aarch64/Processor.h | 2 |
3 files changed, 16 insertions, 2 deletions
diff --git a/Kernel/Arch/aarch64/PageDirectory.cpp b/Kernel/Arch/aarch64/PageDirectory.cpp index 69c25d1eaf..814323783e 100644 --- a/Kernel/Arch/aarch64/PageDirectory.cpp +++ b/Kernel/Arch/aarch64/PageDirectory.cpp @@ -49,12 +49,14 @@ LockRefPtr<PageDirectory> PageDirectory::find_current() void activate_kernel_page_directory(PageDirectory const& page_directory) { Aarch64::Asm::set_ttbr0_el1(page_directory.ttbr0()); + Processor::flush_entire_tlb_local(); } void activate_page_directory(PageDirectory const& page_directory, Thread* current_thread) { current_thread->regs().ttbr0_el1 = page_directory.ttbr0(); Aarch64::Asm::set_ttbr0_el1(page_directory.ttbr0()); + Processor::flush_entire_tlb_local(); } UNMAP_AFTER_INIT NonnullLockRefPtr<PageDirectory> PageDirectory::must_create_kernel_page_directory() diff --git a/Kernel/Arch/aarch64/Processor.cpp b/Kernel/Arch/aarch64/Processor.cpp index 1e049990eb..7545a42d2d 100644 --- a/Kernel/Arch/aarch64/Processor.cpp +++ b/Kernel/Arch/aarch64/Processor.cpp @@ -113,7 +113,15 @@ void Processor::flush_tlb_local(VirtualAddress, size_t) { // FIXME: Figure out how to flush a single page asm volatile("dsb ishst"); - asm volatile("tlbi vmalle1is"); + asm volatile("tlbi vmalle1"); + asm volatile("dsb ish"); + asm volatile("isb"); +} + +void Processor::flush_entire_tlb_local() +{ + asm volatile("dsb ishst"); + asm volatile("tlbi vmalle1"); asm volatile("dsb ish"); asm volatile("isb"); } @@ -529,8 +537,10 @@ extern "C" void enter_thread_context(Thread* from_thread, Thread* to_thread) auto& from_regs = from_thread->regs(); auto& to_regs = to_thread->regs(); - if (from_regs.ttbr0_el1 != to_regs.ttbr0_el1) + if (from_regs.ttbr0_el1 != to_regs.ttbr0_el1) { Aarch64::Asm::set_ttbr0_el1(to_regs.ttbr0_el1); + Processor::flush_entire_tlb_local(); + } to_thread->set_cpu(Processor::current().id()); diff --git a/Kernel/Arch/aarch64/Processor.h b/Kernel/Arch/aarch64/Processor.h index b63a21a232..d51b063394 100644 --- a/Kernel/Arch/aarch64/Processor.h +++ b/Kernel/Arch/aarch64/Processor.h @@ -273,6 +273,8 @@ public: static void set_thread_specific_data(VirtualAddress thread_specific_data); + static void flush_entire_tlb_local(); + private: Processor(Processor const&) = delete; |