miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
Loading...
Searching...
No Matches
IPI – Inter-Processor Interrupts

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]

Detailed Description

TLB shootdown and panic-halt IPI infrastructure.

Implements two IPI paths:

  • TLB shootdown (vectors TLB_SHOOTDOWN_VECTOR_BASE..+MAX_CPUS-1): vmm_unmap_page() / vmm_map_page() call ipi_tlb_shootdown() to ensure all CPUs flush the invalidated mapping before the caller continues.
  • Panic halt (vector 52): kernel_panic() calls ipi_panic_halt() to halt all APs before the BSP prints the panic message and halts.

Function Documentation

◆ ipi_barrier_ack()

void ipi_barrier_ack ( ipi_barrier_t * b)
inlinestatic

Atomically decrement the barrier's ack_count.

Parameters
bBarrier to acknowledge. Called by ISR handlers BEFORE lapic_eoi().
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipi_barrier_wait()

void ipi_barrier_wait ( ipi_barrier_t * b)
inlinestatic

Spin until barrier->ack_count reaches 0.

Parameters
bBarrier to wait on. Called by the IPI initiator after broadcasting.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipi_panic_halt()

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().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ipi_tlb_shootdown()

void ipi_tlb_shootdown ( uint64_t virt)

Broadcast TLB-shootdown IPI and wait for all CPUs to flush.

Parameters
virtVirtual 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.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ panic_halt_isr()

void panic_halt_isr ( void * frame)

ISR for PANIC_HALT_VECTOR (52) on APs.

Parameters
framePointer to the interrupt frame (unused).

Executes cli; hlt. Does NOT send EOI – the halted CPU never needs the LAPIC unblocked for subsequent interrupts.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tlb_shootdown_isr()

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).

Parameters
src_cpuThe 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().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ g_tlb_barriers

ipi_barrier_t g_tlb_barriers[MAX_CPUS]
extern