diff options
author | Ian Moffett <ian@osmora.org> | 2024-05-23 19:50:57 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-05-23 19:50:57 -0400 |
commit | 9c978c882984e879f6f418733fe95a16310f1373 (patch) | |
tree | df2c59d29831d7d4a9c005aec1ed5fbd8de3b6ff /sys/arch/amd64 | |
parent | b63337fbcf9f471399caa8a420fd35a1c2db98db (diff) |
kernel/amd64: pmap: Add support for TLB shootdowns
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/pmap.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index 8af6d39..468cca4 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -31,7 +31,12 @@ #include <vm/vm.h> #include <vm/physseg.h> #include <sys/cdefs.h> +#include <sys/cpu.h> +#include <sys/intr.h> #include <machine/tlb.h> +#include <machine/lapic.h> +#include <machine/sysvec.h> +#include <machine/idt.h> #include <assert.h> #include <string.h> @@ -52,6 +57,45 @@ #define PTE_GLOBAL __BIT(8) #define PTE_NX __BIT(63) /* Execute-disable */ +__attr(interrupt) static void +tlb_shootdown_isr(void *sf) +{ + struct cpu_info *ci = this_cpu(); + struct intr_info *intr_info = ci->tlb_shootdown; + + /* Setup interrupt information if needed */ + if (ci->tlb_shootdown == NULL) { + intr_info = intr_info_alloc("TLB-Shootdown", "LAPIC-IPI"); + intr_info->affinity = ci->id; + + ci->tlb_shootdown = intr_info; + intr_register(intr_info); + } + + ++intr_info->count; + tlb_flush(ci->tlb_flush_ptr); + + ci->tlb_flush_ptr = 0; + lapic_send_eoi(); +} + +static void +tlb_shootdown(vaddr_t flush_va) +{ + struct cpu_info *curcpu, *ci = NULL; + size_t idx = 0; + + curcpu = this_cpu(); + while ((ci = cpu_get(idx++)) != NULL) { + if (ci->id == curcpu->id) + continue; + + ci->tlb_flush_ptr = flush_va; + } + + lapic_send_ipi(0, IPI_SHORTHAND_OTHERS, SYSVEC_TLB); +} + /* * Convert pmap prot flags to PTE flags. */ @@ -160,6 +204,17 @@ pmap_modify_tbl(struct vm_ctx *ctx, struct vas vas, vaddr_t va, size_t val) /* Map our page */ tbl[pmap_get_level_index(1, va)] = val; + + /* + * Do TLB shootdown if CPUs are listed. + * + * XXX: Some might not be listed during early + * startup. + */ + if (cpu_get(0) != NULL) { + tlb_shootdown(va); + } + tlb_flush(va); done: return status; @@ -261,5 +316,8 @@ pmap_read_vas(void) int pmap_init(struct vm_ctx *ctx) { + idt_set_desc(SYSVEC_TLB, IDT_INT_GATE_FLAGS, + (uintptr_t)tlb_shootdown_isr, 0); + return 0; } |