Introduce ipi_self_from_nmi().

It allows safe IPI sending to current CPU from NMI context.

Unlike other ipi_*() functions this waits for delivery to leave LAPIC in
a state safe for interrupted code.

MFC after:	2 weeks
Sponsored by:	iXsystems, Inc.
This commit is contained in:
mav 2020-07-24 20:52:09 +00:00
parent 2e63bf9b20
commit fe00b63050
2 changed files with 16 additions and 0 deletions

View File

@ -97,6 +97,7 @@ void ipi_bitmap_handler(struct trapframe frame);
void ipi_cpu(int cpu, u_int ipi);
int ipi_nmi_handler(void);
void ipi_selected(cpuset_t cpus, u_int ipi);
void ipi_self_from_nmi(u_int vector);
void set_interrupt_apic_ids(void);
void smp_cache_flush(smp_invl_cb_t curcpu_cb);
void smp_masked_invlpg(cpuset_t mask, vm_offset_t addr, struct pmap *pmap,

View File

@ -1398,6 +1398,21 @@ ipi_all_but_self(u_int ipi)
lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS);
}
void
ipi_self_from_nmi(u_int vector)
{
lapic_ipi_vectored(vector, APIC_IPI_DEST_SELF);
/* Wait for IPI to finish. */
if (!lapic_ipi_wait(50000)) {
if (KERNEL_PANICKED())
return;
else
panic("APIC: IPI is stuck");
}
}
int
ipi_nmi_handler(void)
{