From 7981d8b03c48afd0ff7c80dab1b8bed27c55c3da Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 22 Aug 2025 22:14:40 -0400 Subject: kernel/amd64: ipi: Make halt IPI more direct This commit assigns the halt IPI its own vector so that it may be dispatched fast without needing to go through the IPI path as it is typically used only in very sensitive situations. Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/ipi.c | 3 +- sys/arch/amd64/amd64/machdep.c | 70 ++++++++---------------------------------- sys/arch/amd64/amd64/vector.S | 6 ++++ 3 files changed, 20 insertions(+), 59 deletions(-) (limited to 'sys/arch/amd64') diff --git a/sys/arch/amd64/amd64/ipi.c b/sys/arch/amd64/amd64/ipi.c index e367552..bf263d3 100644 --- a/sys/arch/amd64/amd64/ipi.c +++ b/sys/arch/amd64/amd64/ipi.c @@ -41,6 +41,7 @@ #include void ipi_isr(void); +void halt_isr(void); void __ipi_handle_common(void); @@ -48,7 +49,6 @@ void __ipi_handle_common(void); #define pr_error(...) pr_trace(__VA_ARGS__) #define COOKIE 0x7E0A -#define IPI_VECTOR 0x21 #define MAX_IPI 32 /* For the global state of the subsystem */ @@ -186,5 +186,6 @@ md_ipi_init(void) { /* Initialize the IPI vectors */ idt_set_desc(IPI_VECTOR, IDT_INT_GATE, ISR(ipi_isr), 0); + idt_set_desc(HALT_VECTOR, IDT_INT_GATE, ISR(halt_isr), 0); cookie = COOKIE; } diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 2976a51..60c37bf 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -86,18 +86,10 @@ void syscall_isr(void); void pin_isr_load(void); struct cpu_info g_bsp_ci = {0}; -static struct cpu_ipi *halt_ipi; static struct cpu_ipi *tlb_ipi; static struct spinlock ipi_lock = {0}; static bool bsp_init = false; -static int -cpu_halt_handler(struct cpu_ipi *ipi) -{ - __ASMV("cli; hlt"); - __builtin_unreachable(); -} - static int tlb_shootdown_handler(struct cpu_ipi *ipi) { @@ -223,13 +215,6 @@ init_ipis(void) } spinlock_acquire(&ipi_lock); - error = md_ipi_alloc(&halt_ipi); - if (error < 0) { - pr_error("md_ipi_alloc: returned %d\n", error); - panic("failed to init halt IPI\n"); - } - - halt_ipi->handler = cpu_halt_handler; error = md_ipi_alloc(&tlb_ipi); if (error < 0) { pr_error("md_ipi_alloc: returned %d\n", error); @@ -243,8 +228,6 @@ init_ipis(void) * so that they are standard and usable * throughout the rest of the sytem. */ - if (halt_ipi->id != IPI_HALT) - panic("expected IPI_HALT for halt IPI\n"); if (tlb_ipi->id != IPI_TLB) panic("expected IPI_TLB for TLB IPI\n"); @@ -461,31 +444,14 @@ md_backtrace(void) void cpu_halt_all(void) { - struct cpu_info *ci, *curcpu; - uint32_t ncpu = cpu_count(); - - /* - * If we have no current 'cpu_info' structure set, - * we can't send IPIs, so just assume only the current - * processor is the only one active, clear interrupts - * then halt it. - */ - __ASMV("cli"); - if ((curcpu = this_cpu()) == NULL) { - __ASMV("hlt"); - } + lapic_send_ipi( + 0, + IPI_SHORTHAND_ALL, + HALT_VECTOR + ); - for (int i = 0; i < ncpu; ++i) { - ci = cpu_get(i); - if (ci->id == curcpu->id) { - continue; - } - - md_ipi_send(ci, IPI_HALT); - } - - __ASMV("hlt"); - for (;;); + __ASMV("cli; hlt"); + __builtin_unreachable(); } /* @@ -495,23 +461,11 @@ cpu_halt_all(void) void cpu_halt_others(void) { - struct cpu_info *curcpu, *ci; - uint32_t ncpu = cpu_count(); - - if (rdmsr(IA32_GS_BASE) == 0 || ncpu <= 1) { - return; - } - - curcpu = this_cpu(); - - for (int i = 0; i < ncpu; ++i) { - if ((ci = cpu_get(i)) == NULL) - continue; - if (ci->id == curcpu->id) - continue; - - md_ipi_send(ci, IPI_HALT); - } + lapic_send_ipi( + 0, + IPI_SHORTHAND_OTHERS, + HALT_VECTOR + ); } void diff --git a/sys/arch/amd64/amd64/vector.S b/sys/arch/amd64/amd64/vector.S index 69173d7..62bed1b 100644 --- a/sys/arch/amd64/amd64/vector.S +++ b/sys/arch/amd64/amd64/vector.S @@ -144,6 +144,12 @@ INTRENTRY(ipi_isr, ipi_trampoline) call ipi_trampoline retq + .globl halt_isr +INTRENTRY(halt_isr, halt_trampoline) +halt_trampoline: + cli + hlt + ipi_trampoline: call __ipi_handle_common retq -- cgit v1.2.3