diff options
author | attilio <attilio@FreeBSD.org> | 2009-08-15 18:37:06 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2009-08-15 18:37:06 +0000 |
commit | 38b19229005fffeb77983ebf0cc00d252f9a8e77 (patch) | |
tree | 71424c55279c7e788ec3fb8f09bf6f81e1fbdffe /sys/i386 | |
parent | 51d21560af7d29a8d1d075f654ee21d89656a677 (diff) | |
download | FreeBSD-src-38b19229005fffeb77983ebf0cc00d252f9a8e77.zip FreeBSD-src-38b19229005fffeb77983ebf0cc00d252f9a8e77.tar.gz |
Port recent IPI enhachements to en:
* Introduce the ipi_nmi_handler() function for the Xen infrastructure
* Fixup adeguately the ipi sender functions
Approved by: re (kib)
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/xen/mp_machdep.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index bae07d4..9253366 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -118,6 +118,7 @@ volatile int smp_tlb_wait; typedef void call_data_func_t(uintptr_t , uintptr_t); static u_int logical_cpus; +static volatile cpumask_t ipi_nmi_pending; /* used to hold the AP's until we are ready to release them */ static struct mtx ap_boot_mtx; @@ -1109,6 +1110,14 @@ ipi_selected(cpumask_t cpus, u_int ipi) ipi = IPI_BITMAP_VECTOR; } + /* + * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit + * of help in order to understand what is the source. + * Set the mask of receiving CPUs for this purpose. + */ + if (ipi == IPI_STOP_HARD) + atomic_set_int(&ipi_nmi_pending, cpus); + CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); while ((cpu = ffs(cpus)) != 0) { cpu--; @@ -1140,10 +1149,39 @@ ipi_selected(cpumask_t cpus, u_int ipi) void ipi_all_but_self(u_int ipi) { + + /* + * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit + * of help in order to understand what is the source. + * Set the mask of receiving CPUs for this purpose. + */ + if (ipi == IPI_STOP_HARD) + atomic_set_int(&ipi_nmi_pending, PCPU_GET(other_cpus)); + CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); ipi_selected(PCPU_GET(other_cpus), ipi); } +int +ipi_nmi_handler() +{ + cpumask_t cpumask; + + /* + * As long as there is not a simple way to know about a NMI's + * source, if the bitmask for the current CPU is present in + * the global pending bitword an IPI_STOP_HARD has been issued + * and should be handled. + */ + cpumask = PCPU_GET(cpumask); + if ((ipi_nmi_pending & cpumask) == 0) + return (1); + + atomic_clear_int(&ipi_nmi_pending, cpumask); + cpustop_handler(); + return (0); +} + /* * Handle an IPI_STOP by saving our current context and spinning until we * are resumed. |