From 8aa1e716aff7a42b808ba46c0bed292c4246ad41 Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Sun, 7 Sep 2003 13:43:01 +0000 Subject: [PATCH] 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. --- sys/i386/i386/db_interface.c | 82 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/sys/i386/i386/db_interface.c b/sys/i386/i386/db_interface.c index f17f603be525..ab916bed63cf 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);