Deleted Added
full compact
27c27
< __FBSDID("$FreeBSD: head/sys/i386/i386/mp_machdep.c 194784 2009-06-23 22:42:39Z jeff $");
---
> __FBSDID("$FreeBSD: head/sys/i386/i386/mp_machdep.c 196196 2009-08-13 17:09:45Z attilio $");
158,163d157
< #ifdef STOP_NMI
< static volatile cpumask_t ipi_nmi_pending;
<
< static void ipi_nmi_selected(cpumask_t cpus);
< #endif
<
180,193d173
< #ifdef STOP_NMI
< /*
< * Provide an alternate method of stopping other CPUs. If another CPU has
< * disabled interrupts the conventional STOP IPI will be blocked. This
< * NMI-based stop should get through in that case.
< */
< static int stop_cpus_with_nmi = 1;
< SYSCTL_INT(_debug, OID_AUTO, stop_cpus_with_nmi, CTLTYPE_INT | CTLFLAG_RW,
< &stop_cpus_with_nmi, 0, "");
< TUNABLE_INT("debug.stop_cpus_with_nmi", &stop_cpus_with_nmi);
< #else
< #define stop_cpus_with_nmi 0
< #endif
<
194a175
> static volatile cpumask_t ipi_nmi_pending;
1321,1326c1302,1309
< #ifdef STOP_NMI
< if (ipi == IPI_STOP && stop_cpus_with_nmi) {
< ipi_nmi_selected(cpus);
< return;
< }
< #endif
---
> /*
> * 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);
>
1357c1340
< if (IPI_IS_BITMAPED(ipi) || (ipi == IPI_STOP && stop_cpus_with_nmi)) {
---
> if (IPI_IS_BITMAPED(ipi)) {
1360a1344,1351
>
> /*
> * 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));
1365,1399d1355
< #ifdef STOP_NMI
< /*
< * send NMI IPI to selected CPUs
< */
<
< #define BEFORE_SPIN 1000000
<
< void
< ipi_nmi_selected(cpumask_t cpus)
< {
< int cpu;
< register_t icrlo;
<
< icrlo = APIC_DELMODE_NMI | APIC_DESTMODE_PHY | APIC_LEVEL_ASSERT
< | APIC_TRIGMOD_EDGE;
<
< CTR2(KTR_SMP, "%s: cpus: %x nmi", __func__, cpus);
<
< atomic_set_int(&ipi_nmi_pending, cpus);
<
< while ((cpu = ffs(cpus)) != 0) {
< cpu--;
< cpus &= ~(1 << cpu);
<
< KASSERT(cpu_apic_ids[cpu] != -1,
< ("IPI NMI to non-existent CPU %d", cpu));
<
< /* Wait for an earlier IPI to finish. */
< if (!lapic_ipi_wait(BEFORE_SPIN))
< panic("ipi_nmi_selected: previous IPI has not cleared");
<
< lapic_ipi_raw(icrlo, cpu_apic_ids[cpu]);
< }
< }
<
1401c1357
< ipi_nmi_handler(void)
---
> ipi_nmi_handler()
1403c1359
< int cpumask = PCPU_GET(cpumask);
---
> cpumask_t cpumask;
1405,1406c1361,1369
< if (!(ipi_nmi_pending & cpumask))
< return 1;
---
> /*
> * 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);
1410c1373
< return 0;
---
> return (0);
1413,1414d1375
< #endif /* STOP_NMI */
<