Index: sys/kern/kern_racct.c =================================================================== --- sys/kern/kern_racct.c +++ sys/kern/kern_racct.c @@ -1162,7 +1162,7 @@ */ td->td_flags |= TDF_NEEDRESCHED; #ifdef SMP - cpuid = td->td_oncpu; + cpuid = atomic_load_int(&td->td_oncpu); if ((cpuid != NOCPU) && (td != curthread)) ipi_cpu(cpuid, IPI_AST); #endif Index: sys/kern/subr_smp.c =================================================================== --- sys/kern/subr_smp.c +++ sys/kern/subr_smp.c @@ -204,7 +204,7 @@ if (td == curthread) return; - id = td->td_oncpu; + id = atomic_load_int(&td->td_oncpu); if (id == NOCPU) return; ipi_cpu(id, IPI_AST); Index: sys/x86/x86/mp_x86.c =================================================================== --- sys/x86/x86/mp_x86.c +++ sys/x86/x86/mp_x86.c @@ -1233,7 +1233,8 @@ u_int bitmap, old, new; u_int *cpu_bitmap; - KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu)); + KASSERT((u_int)cpu < MAXCPU && cpu_apic_ids[cpu] != -1, + ("IPI to non-existent CPU %d", cpu)); if (IPI_IS_BITMAPED(ipi)) { bitmap = 1 << ipi; Index: sys/x86/x86/stack_machdep.c =================================================================== --- sys/x86/x86/stack_machdep.c +++ sys/x86/x86/stack_machdep.c @@ -103,15 +103,25 @@ #ifdef STACK /* Don't consume an NMI that wasn't meant for us. */ - if (nmi_stack == NULL || curthread != nmi_pending) + if (nmi_stack == NULL) return (0); - if (!TRAPF_USERMODE(tf) && (TF_FLAGS(tf) & PSL_I) != 0) - stack_capture(curthread, nmi_stack, TF_FP(tf)); - else - /* We were running in usermode or had interrupts disabled. */ - nmi_stack->depth = 0; - + /* + * Pre-set to signify an error condition. + */ + nmi_stack->depth = 0; + + /* + * Make sure the current CPU is (still) running the expected thread. + */ + if (curthread == nmi_pending) { + /* + * We don't grab a backtrace if the thread is in userspace or + * interrupts were disabled. + */ + if (!TRAPF_USERMODE(tf) && (TF_FLAGS(tf) & PSL_I) != 0) + stack_capture(curthread, nmi_stack, TF_FP(tf)); + } atomic_store_rel_ptr((long *)&nmi_pending, (long)NULL); return (1); #else @@ -134,6 +144,9 @@ int stack_save_td_running(struct stack *st, struct thread *td) { +#ifdef SMP + int cpu; +#endif #ifdef STACK THREAD_LOCK_ASSERT(td, MA_OWNED); @@ -145,11 +158,15 @@ } #ifdef SMP + cpu = atomic_load_int(&td->td_oncpu); + if (cpu == NOCPU) + return (EAGAIN); + mtx_lock_spin(&nmi_lock); nmi_stack = st; nmi_pending = td; - ipi_cpu(td->td_oncpu, IPI_TRACE); + ipi_cpu(cpu, IPI_TRACE); while ((void *)atomic_load_acq_ptr((long *)&nmi_pending) != NULL) cpu_spinwait(); nmi_stack = NULL;