summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2003-09-07 13:43:01 +0000
committerbde <bde@FreeBSD.org>2003-09-07 13:43:01 +0000
commit4ffaa4dacdc1e05731b6fa6cba7ed4b19a8d7003 (patch)
tree4d60e4d69550cba43d5dd01ce34afdbb4e4c7b21
parentf35a57851fa382dd55052dc218b47fbd23fb8bb4 (diff)
downloadFreeBSD-src-4ffaa4dacdc1e05731b6fa6cba7ed4b19a8d7003.zip
FreeBSD-src-4ffaa4dacdc1e05731b6fa6cba7ed4b19a8d7003.tar.gz
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.
-rw-r--r--sys/i386/i386/db_interface.c82
1 files changed, 41 insertions, 41 deletions
diff --git a/sys/i386/i386/db_interface.c b/sys/i386/i386/db_interface.c
index f17f603..ab916be 100644
--- a/sys/i386/i386/db_interface.c
+++ b/sys/i386/i386/db_interface.c
@@ -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);
OpenPOWER on IntegriCloud