svn commit: r196256 - head/sys/i386/xen

Attilio Rao attilio at FreeBSD.org
Sat Aug 15 18:37:07 UTC 2009


Author: attilio
Date: Sat Aug 15 18:37:06 2009
New Revision: 196256
URL: http://svn.freebsd.org/changeset/base/196256

Log:
  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)

Modified:
  head/sys/i386/xen/mp_machdep.c

Modified: head/sys/i386/xen/mp_machdep.c
==============================================================================
--- head/sys/i386/xen/mp_machdep.c	Sat Aug 15 18:03:34 2009	(r196255)
+++ head/sys/i386/xen/mp_machdep.c	Sat Aug 15 18:37:06 2009	(r196256)
@@ -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.


More information about the svn-src-head mailing list