|
miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
|
TLB shootdown and panic-halt IPI infrastructure. More...
Classes | |
| struct | ipi_barrier_t |
Functions | |
| static void | ipi_barrier_ack (ipi_barrier_t *b) |
| Atomically decrement the barrier's ack_count. | |
| static void | ipi_barrier_wait (ipi_barrier_t *b) |
| Spin until barrier->ack_count reaches 0. | |
| void | ipi_tlb_shootdown (uint64_t virt) |
| Broadcast TLB-shootdown IPI and wait for all CPUs to flush. | |
| void | tlb_shootdown_isr (uint32_t src_cpu) |
| ISR for TLB_SHOOTDOWN_VECTOR_BASE + N on remote CPUs (one per possible initiator CPU N — see tlb_shootdown_wrapper0..7 in isr.asm). | |
| void | ipi_panic_halt (void) |
| Broadcast halt IPI to all APs on kernel panic. | |
| void | panic_halt_isr (void *frame) |
| ISR for PANIC_HALT_VECTOR (52) on APs. | |
Variables | |
| ipi_barrier_t | g_tlb_barriers [MAX_CPUS] |
TLB shootdown and panic-halt IPI infrastructure.
Implements two IPI paths:
|
inlinestatic |
Atomically decrement the barrier's ack_count.
| b | Barrier to acknowledge. Called by ISR handlers BEFORE lapic_eoi(). |


|
inlinestatic |
Spin until barrier->ack_count reaches 0.
| b | Barrier to wait on. Called by the IPI initiator after broadcasting. |


| void ipi_panic_halt | ( | void | ) |
Broadcast halt IPI to all APs on kernel panic.
Sends PANIC_HALT_VECTOR (52) to every CPU except the calling BSP via lapic_send_ipi. Waits up to one LAPIC timer period (lapic_bsp_timer_icr/2 CCR ticks) for APs to halt, then returns to allow the BSP to print the panic message and execute cli;hlt. Called from handle_exception().


| void ipi_tlb_shootdown | ( | uint64_t | virt | ) |
Broadcast TLB-shootdown IPI and wait for all CPUs to flush.
| virt | Virtual address to invalidate on all CPUs. |
Uses g_tlb_barriers[cpu_local()->cpu_id] — the calling CPU's own slot, so this is safe to call concurrently from multiple CPUs with no lock. Sets that barrier's virt = @virt and ack_count = smp_cpu_count - 1, then broadcasts TLB_SHOOTDOWN_VECTOR_BASE + cpu_id to all CPUs except self via lapic_send_ipi. Spins in ipi_barrier_wait() until all handlers have called ipi_barrier_ack(). Caller (sys_munmap) must have already called invlpg locally.
Context: Safe to call with interrupts disabled (e.g. from a page-fault handler resolving CoW — page_fault_exception() deliberately does NOT sti for this reason, unlike the SYSCALL entry path). Each CPU only ever initiates from its own barrier slot, so the initiator needs no lock and no incoming interrupts to make progress. A CPU that is itself the TARGET of a concurrent shootdown while its own interrupts are disabled just delays that peer's wait until this CPU's current IF=0 section finishes and returns (bounded, since none of these sections block) — no deadlock.


| void panic_halt_isr | ( | void * | frame | ) |
ISR for PANIC_HALT_VECTOR (52) on APs.
| frame | Pointer to the interrupt frame (unused). |
Executes cli; hlt. Does NOT send EOI – the halted CPU never needs the LAPIC unblocked for subsequent interrupts.


| void tlb_shootdown_isr | ( | uint32_t | src_cpu | ) |
ISR for TLB_SHOOTDOWN_VECTOR_BASE + N on remote CPUs (one per possible initiator CPU N — see tlb_shootdown_wrapper0..7 in isr.asm).
| src_cpu | The initiating CPU's cpu_id, baked into the calling wrapper. |
Executes invlpg(g_tlb_barriers[src_cpu].virt), then calls ipi_barrier_ack(&g_tlb_barriers[src_cpu]) (decrement-before-EOI guarantees the initiator sees ack_count==0 only after the TLB flush is complete), then calls lapic_eoi_asm().


|
extern |