diff options
author | Ian Moffett <ian@osmora.org> | 2024-07-10 20:59:37 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-07-10 21:02:56 -0400 |
commit | 67f9d3c5e58f1a958a2b1b7a102a71e3ce252fc4 (patch) | |
tree | 108fbc812dd0acd00005e025faf2be9831f95100 /sys/arch | |
parent | d243e9b36fe2bf8e9551cc6677aaa2747604fcfa (diff) |
kernel/amd64: reboot: Halt all with REBOOT_HALT
This commit changes how reboot() handles REBOOT_HALT. Now instead of one
core being halted, all cores will be halted through an IPI to a halt
vector.
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 24 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/reboot.c | 9 |
2 files changed, 26 insertions, 7 deletions
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 03b10f0..2185028 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -38,6 +38,7 @@ #include <machine/cpuid.h> #include <machine/lapic.h> #include <machine/uart.h> +#include <machine/intr.h> #if defined(__SPECTRE_IBRS) #define SPECTRE_IBRS __SPECTRE_IBRS @@ -45,6 +46,8 @@ #define SPECTRE_IBRS 0 #endif +static uint8_t halt_vector = 0; + int ibrs_enable(void); void syscall_isr(void); @@ -54,9 +57,21 @@ static struct gdtr bsp_gdtr = { .offset = (uintptr_t)&g_gdt_data[0] }; +__attribute__((__interrupt__)) +static void +cpu_halt_isr(void *p) +{ + __ASMV("cli; hlt"); + __builtin_unreachable(); +} + static void setup_vectors(void) { + if (halt_vector == 0) { + halt_vector = intr_alloc_vector("cpu-halt", IPL_HIGH); + } + idt_set_desc(0x0, IDT_TRAP_GATE, ISR(arith_err), 0); idt_set_desc(0x2, IDT_TRAP_GATE, ISR(nmi), 0); idt_set_desc(0x3, IDT_TRAP_GATE, ISR(breakpoint_handler), 0); @@ -70,6 +85,7 @@ setup_vectors(void) idt_set_desc(0xD, IDT_TRAP_GATE, ISR(general_prot), 0); idt_set_desc(0xE, IDT_TRAP_GATE, ISR(page_fault), 0); idt_set_desc(0x80, IDT_USER_INT_GATE, ISR(syscall_isr), 0); + idt_set_desc(halt_vector, IDT_INT_GATE, ISR(cpu_halt_isr), 0); } static inline void @@ -93,6 +109,14 @@ try_mitigate_spectre(void) } void +cpu_halt_all(void) +{ + /* Send IPI to all cores */ + lapic_send_ipi(0, IPI_SHORTHAND_ALL, halt_vector); + for (;;); +} + +void serial_init(void) { uart_init(); diff --git a/sys/arch/amd64/amd64/reboot.c b/sys/arch/amd64/amd64/reboot.c index da1b46a..02126d3 100644 --- a/sys/arch/amd64/amd64/reboot.c +++ b/sys/arch/amd64/amd64/reboot.c @@ -31,18 +31,13 @@ #include <sys/param.h> #include <sys/cdefs.h> #include <machine/pio.h> - -__always_inline static inline void -cpu_halt(void) -{ - __ASMV("cli; hlt"); -} +#include <machine/cpu.h> void cpu_reboot(int method) { if (ISSET(method, REBOOT_HALT)) { - cpu_halt(); + cpu_halt_all(); } /* Pulse the reset line until the machine goes down */ |