mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[kernel] Add a _very_ basic TLB shootdown mechanism
This TLB shootdown implementation is pretty janky: When the kernel unmaps a mapping, it sends an IPI to all other cores and doesn't even wait to ensure they've finished handling it. Upon getting one of these IPIs, the core just re-writes cr3 to flush all TLBs.
This commit is contained in:
@@ -117,4 +117,5 @@ ISR (0xe1, 0, isrLINT0)
|
|||||||
ISR (0xe2, 0, isrLINT1)
|
ISR (0xe2, 0, isrLINT1)
|
||||||
ISR (0xe3, 0, isrAPICError)
|
ISR (0xe3, 0, isrAPICError)
|
||||||
ISR (0xe4, 0, ipiSchedule)
|
ISR (0xe4, 0, ipiSchedule)
|
||||||
|
ISR (0xe5, 0, ipiShootdown)
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ constexpr uintptr_t apic_eoi_addr = 0xfee000b0 + mem::linear_offset;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
void isr_handler(cpu_state*);
|
void isr_handler(cpu_state*);
|
||||||
void irq_handler(cpu_state*);
|
void irq_handler(cpu_state*);
|
||||||
|
void _reload_cr3();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
@@ -187,6 +188,11 @@ isr_handler(cpu_state *regs)
|
|||||||
scheduler::get().schedule();
|
scheduler::get().schedule();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case isr::ipiShootdown:
|
||||||
|
// TODO: Real shootdown algorithm
|
||||||
|
_reload_cr3();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
util::format({message, sizeof(message)}, "Unknown interrupt 0x%lx", regs->interrupt);
|
util::format({message, sizeof(message)}, "Unknown interrupt 0x%lx", regs->interrupt);
|
||||||
kassert(false, message, regs);
|
kassert(false, message, regs);
|
||||||
|
|||||||
@@ -91,3 +91,10 @@ _current_gsbase:
|
|||||||
mov rax, [gs:CPU_DATA.self]
|
mov rax, [gs:CPU_DATA.self]
|
||||||
ret
|
ret
|
||||||
.end:
|
.end:
|
||||||
|
|
||||||
|
global _reload_cr3: function hidden (_reload_cr3.end - _reload_cr3)
|
||||||
|
_reload_cr3:
|
||||||
|
mov rax, cr3
|
||||||
|
mov cr3, rax
|
||||||
|
ret
|
||||||
|
.end:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <j6/memutils.h>
|
#include <j6/memutils.h>
|
||||||
#include <arch/memory.h>
|
#include <arch/memory.h>
|
||||||
|
|
||||||
|
#include "apic.h"
|
||||||
#include "kassert.h"
|
#include "kassert.h"
|
||||||
#include "frame_allocator.h"
|
#include "frame_allocator.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
@@ -81,7 +82,7 @@ vm_space::kernel_space()
|
|||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t
|
uintptr_t
|
||||||
vm_space::add(uintptr_t base, obj::vm_area *area, util::bitset32 flags)
|
vm_space::add(uintptr_t base, obj::vm_area *new_area, util::bitset32 flags)
|
||||||
{
|
{
|
||||||
if (!base)
|
if (!base)
|
||||||
base = min_auto_address;
|
base = min_auto_address;
|
||||||
@@ -89,23 +90,23 @@ vm_space::add(uintptr_t base, obj::vm_area *area, util::bitset32 flags)
|
|||||||
//TODO: optimize find/insert
|
//TODO: optimize find/insert
|
||||||
bool exact = flags.get(vm_flags::exact);
|
bool exact = flags.get(vm_flags::exact);
|
||||||
for (size_t i = 0; i < m_areas.count(); ++i) {
|
for (size_t i = 0; i < m_areas.count(); ++i) {
|
||||||
const vm_space::area &a = m_areas[i];
|
const vm_space::area &cur = m_areas[i];
|
||||||
uintptr_t aend = a.base + a.area->size();
|
uintptr_t cur_end = cur.base + cur.area->size();
|
||||||
if (base >= aend)
|
if (base >= cur_end)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uintptr_t end = base + area->size();
|
uintptr_t end = base + new_area->size();
|
||||||
if (end <= a.base)
|
if (end <= cur.base)
|
||||||
break;
|
break;
|
||||||
else if (exact)
|
else if (exact)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
base = aend;
|
base = cur_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_areas.sorted_insert({base, area});
|
m_areas.sorted_insert({base, new_area});
|
||||||
area->add_to(this);
|
new_area->add_to(this);
|
||||||
area->handle_retain();
|
new_area->handle_retain();
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,6 +268,9 @@ vm_space::clear(const obj::vm_area &vma, uintptr_t offset, size_t count, bool fr
|
|||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_cpu().apic->send_ipi_broadcast(
|
||||||
|
lapic::ipi_fixed, false, isr::ipiShootdown);
|
||||||
|
|
||||||
if (free && free_count)
|
if (free && free_count)
|
||||||
fa.free(free_start, free_count);
|
fa.free(free_start, free_count);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user