pmap tlb shootdowns
This commit is contained in:
+29
-13
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user