pmap tlb shootdowns

This commit is contained in:
2026-10-15 00:33:23 +02:00
parent d84232c394
commit 12e8331752
9 changed files with 189 additions and 13 deletions
+29 -13
View File
@@ -3,12 +3,11 @@
#include <zinnia/cmdline.h>
#include <zinnia/compiler.h>
#include <zinnia/percpu.h>
#include <zinnia/pmap.h>
#include <zinnia/utils.h>
#include <zinnia/vma.h>
#include <arch/percpu.h>
extern uint8_t __ld_percpu_start[];
extern uint8_t __ld_percpu_end[];
static _Atomic(size_t) num_cpus = 1;
static size_t max_cpus = SIZE_MAX;
@@ -25,20 +24,33 @@ struct percpu percpu_bsp = {
};
struct percpu* percpu_new() {
const size_t size = __ld_percpu_end - __ld_percpu_start;
const size_t num_pages = ALIGN_UP(size, arch_mem_page_size()) / arch_mem_page_size();
// TODO: Map pages past the end of the kernel.
// TODO: Document how allocations work.
phys_t mem;
if (mem_phys_alloc(num_pages, 0, &mem))
const size_t pgsz = arch_mem_page_size();
const size_t stride = percpu_stride();
const size_t id = atomic_load(&num_cpus, ATOMIC_RELAXED);
if (id >= (UINTPTR_MAX - (uintptr_t)__ld_percpu_start) / stride)
return nullptr;
struct percpu* cpu = HHDM_PTR(mem);
phys_t mem;
if (mem_phys_alloc(stride / pgsz, 0, &mem))
return nullptr;
const uintptr_t base = (uintptr_t)percpu_cpu(id);
for (size_t offset = 0; offset < stride; offset += pgsz) {
if (pmap_map(&kernel_vma.pmap, base + offset, mem + offset, PTE_READ | PTE_WRITE, CACHE_ANY)) {
while (offset) {
offset -= pgsz;
pmap_unmap(&kernel_vma.pmap, base + offset);
}
mem_phys_free(mem, stride / pgsz);
return nullptr;
}
}
struct percpu* cpu = (struct percpu*)base;
cpu->self = cpu;
cpu->id = atomic_fetch_add(&num_cpus, 1, ATOMIC_RELAXED);
cpu->id = id;
cpu->online = false;
atomic_store(&num_cpus, id + 1, ATOMIC_RELEASE);
return cpu;
}
@@ -46,6 +58,10 @@ size_t percpu_max_cpus() {
return max_cpus;
}
size_t percpu_count() {
return atomic_load(&num_cpus, ATOMIC_RELAXED);
}
struct percpu* percpu_get() {
return arch_percpu_get();
}