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::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::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;