1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 06:17:35 +00:00

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.
This commit is contained in:
Timon Kruiper 2023-02-21 21:21:03 +01:00 committed by Idan Horowitz
parent 188a52db01
commit 6a8581855d
3 changed files with 16 additions and 2 deletions

View file

@ -49,12 +49,14 @@ LockRefPtr<PageDirectory> PageDirectory::find_current()
void activate_kernel_page_directory(PageDirectory const& page_directory) void activate_kernel_page_directory(PageDirectory const& page_directory)
{ {
Aarch64::Asm::set_ttbr0_el1(page_directory.ttbr0()); Aarch64::Asm::set_ttbr0_el1(page_directory.ttbr0());
Processor::flush_entire_tlb_local();
} }
void activate_page_directory(PageDirectory const& page_directory, Thread* current_thread) void activate_page_directory(PageDirectory const& page_directory, Thread* current_thread)
{ {
current_thread->regs().ttbr0_el1 = page_directory.ttbr0(); current_thread->regs().ttbr0_el1 = page_directory.ttbr0();
Aarch64::Asm::set_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() UNMAP_AFTER_INIT NonnullLockRefPtr<PageDirectory> PageDirectory::must_create_kernel_page_directory()

View file

@ -113,7 +113,15 @@ void Processor::flush_tlb_local(VirtualAddress, size_t)
{ {
// FIXME: Figure out how to flush a single page // FIXME: Figure out how to flush a single page
asm volatile("dsb ishst"); 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("dsb ish");
asm volatile("isb"); 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& from_regs = from_thread->regs();
auto& to_regs = to_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); Aarch64::Asm::set_ttbr0_el1(to_regs.ttbr0_el1);
Processor::flush_entire_tlb_local();
}
to_thread->set_cpu(Processor::current().id()); to_thread->set_cpu(Processor::current().id());

View file

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