summaryrefslogtreecommitdiff
path: root/Kernel/Arch
diff options
context:
space:
mode:
authorTimon Kruiper <timonkruiper@gmail.com>2023-02-21 21:21:03 +0100
committerIdan Horowitz <idan.horowitz@gmail.com>2023-04-06 21:19:58 +0300
commit6a8581855d4e32ba0da328cd89642d0154484b96 (patch)
tree68c4cb84488db9c6fe60188b8c612f2ab6e20036 /Kernel/Arch
parent188a52db01eed9a5e169eb61ca35fc82f2142cf1 (diff)
downloadserenity-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.cpp2
-rw-r--r--Kernel/Arch/aarch64/Processor.cpp14
-rw-r--r--Kernel/Arch/aarch64/Processor.h2
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;