Moved stop/start code for other CPUs to near the beginning/end of

kdb_trap().  Stopping the other CPUs acts like locking them out, but
it wasn't done early enough or held long enough to prevent concurrent
accesses to shared data.  In particular, the saved regs could be
clobbered.
This commit is contained in:
Bruce Evans 2003-09-07 13:43:01 +00:00
parent 95ad4657c8
commit 8aa1e716af
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=119844

View File

@ -101,6 +101,24 @@ kdb_trap(int type, int code, struct i386_saved_state *regs)
ef = read_eflags();
disable_intr();
#ifdef SMP
#ifdef CPUSTOP_ON_DDBBREAK
#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
db_printf("\nCPU%d stopping CPUs: 0x%08x...", PCPU_GET(cpuid),
PCPU_GET(other_cpus));
#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
/* We stop all CPUs except ourselves (obviously) */
stop_cpus(PCPU_GET(other_cpus));
#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
db_printf(" stopped.\n");
#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
#endif /* CPUSTOP_ON_DDBBREAK */
#endif /* SMP */
switch (type) {
case T_BPTFLT: /* breakpoint */
case T_TRCTRAP: /* debug exception */
@ -145,24 +163,6 @@ kdb_trap(int type, int code, struct i386_saved_state *regs)
ddb_regs.tf_ss = rss();
}
#ifdef SMP
#ifdef CPUSTOP_ON_DDBBREAK
#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
db_printf("\nCPU%d stopping CPUs: 0x%08x...", PCPU_GET(cpuid),
PCPU_GET(other_cpus));
#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
/* We stop all CPUs except ourselves (obviously) */
stop_cpus(PCPU_GET(other_cpus));
#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
db_printf(" stopped.\n");
#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
#endif /* CPUSTOP_ON_DDBBREAK */
#endif /* SMP */
(void) setjmp(db_global_jmpbuf);
if (ddb_mode) {
if (!db_active)
@ -176,29 +176,6 @@ kdb_trap(int type, int code, struct i386_saved_state *regs)
}
db_active = 0;
#ifdef SMP
#ifdef CPUSTOP_ON_DDBBREAK
#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
db_printf("\nCPU%d restarting CPUs: 0x%08x...", PCPU_GET(cpuid),
stopped_cpus);
#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
/* Restart all the CPUs we previously stopped */
if (stopped_cpus != PCPU_GET(other_cpus) && smp_started != 0) {
db_printf("whoa, other_cpus: 0x%08x, stopped_cpus: 0x%08x\n",
PCPU_GET(other_cpus), stopped_cpus);
panic("stop_cpus() failed");
}
restart_cpus(stopped_cpus);
#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
db_printf(" restarted.\n");
#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
#endif /* CPUSTOP_ON_DDBBREAK */
#endif /* SMP */
regs->tf_eip = ddb_regs.tf_eip;
regs->tf_eflags = ddb_regs.tf_eflags;
regs->tf_eax = ddb_regs.tf_eax;
@ -222,6 +199,29 @@ kdb_trap(int type, int code, struct i386_saved_state *regs)
regs->tf_cs = ddb_regs.tf_cs & 0xffff;
regs->tf_ds = ddb_regs.tf_ds & 0xffff;
#ifdef SMP
#ifdef CPUSTOP_ON_DDBBREAK
#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
db_printf("\nCPU%d restarting CPUs: 0x%08x...", PCPU_GET(cpuid),
stopped_cpus);
#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
/* Restart all the CPUs we previously stopped */
if (stopped_cpus != PCPU_GET(other_cpus) && smp_started != 0) {
db_printf("whoa, other_cpus: 0x%08x, stopped_cpus: 0x%08x\n",
PCPU_GET(other_cpus), stopped_cpus);
panic("stop_cpus() failed");
}
restart_cpus(stopped_cpus);
#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
db_printf(" restarted.\n");
#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
#endif /* CPUSTOP_ON_DDBBREAK */
#endif /* SMP */
write_eflags(ef);
return (1);