diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2019-03-23 05:47:24 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2019-03-23 05:47:24 +0000 |
commit | f521f9e1b2f1715477b2c105eb48c1f25315e953 (patch) | |
tree | e82fafdc3546960380cc7e5354d69f36b67f6ade /sys/arch/mips64 | |
parent | 805f6dc04087ae26b5b0db8f107a6685a3362df3 (diff) |
Use the debugger mutex for `ddb_mp_mutex'. This should prevent a race
that could leave `ddb_mp_mutex' locked if one CPU incremented
`db_active' while another CPU was in the critical section. When the race
hit, the debugger was unable to resume execution or switch between CPUs.
Race analyzed by patrick@
OK mpi@ patrick@
Diffstat (limited to 'sys/arch/mips64')
-rw-r--r-- | sys/arch/mips64/include/db_machdep.h | 4 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/db_machdep.c | 32 |
2 files changed, 17 insertions, 19 deletions
diff --git a/sys/arch/mips64/include/db_machdep.h b/sys/arch/mips64/include/db_machdep.h index 7367d00a7be..fc40211ad82 100644 --- a/sys/arch/mips64/include/db_machdep.h +++ b/sys/arch/mips64/include/db_machdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: db_machdep.h,v 1.17 2016/04/27 11:10:48 mpi Exp $ */ +/* $OpenBSD: db_machdep.h,v 1.18 2019/03/23 05:47:23 visa Exp $ */ /* * Copyright (c) 1998-2003 Opsycon AB (www.opsycon.se) @@ -70,8 +70,6 @@ void db_stopcpu(int); int dbmd_print_insn(uint32_t, db_addr_t, int (*)(const char *, ...)); -extern struct mutex ddb_mp_mutex; - #define DDB_STATE_NOT_RUNNING 0 #define DDB_STATE_RUNNING 1 #define DDB_STATE_EXITING 2 diff --git a/sys/arch/mips64/mips64/db_machdep.c b/sys/arch/mips64/mips64/db_machdep.c index e3bcc5a10c9..899f9fa16b2 100644 --- a/sys/arch/mips64/mips64/db_machdep.c +++ b/sys/arch/mips64/mips64/db_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_machdep.c,v 1.50 2018/06/13 14:38:42 visa Exp $ */ +/* $OpenBSD: db_machdep.c,v 1.51 2019/03/23 05:47:23 visa Exp $ */ /* * Copyright (c) 1998-2003 Opsycon AB (www.opsycon.se) @@ -69,7 +69,7 @@ void db_trap_trace_cmd(db_expr_t, int, db_expr_t, char *); void db_dump_tlb_cmd(db_expr_t, int, db_expr_t, char *); #ifdef MULTIPROCESSOR -struct mutex ddb_mp_mutex = MUTEX_INITIALIZER(IPL_HIGH); +struct db_mutex ddb_mp_mutex = DB_MUTEX_INITIALIZER; volatile int ddb_state = DDB_STATE_NOT_RUNNING; volatile cpuid_t ddb_active_cpu; boolean_t db_switch_cpu; @@ -152,10 +152,10 @@ db_ktrap(int type, struct trapframe *fp) } #ifdef MULTIPROCESSOR - mtx_enter(&ddb_mp_mutex); + db_mtx_enter(&ddb_mp_mutex); if (ddb_state == DDB_STATE_EXITING) ddb_state = DDB_STATE_NOT_RUNNING; - mtx_leave(&ddb_mp_mutex); + db_mtx_leave(&ddb_mp_mutex); while (db_enter_ddb()) { #endif @@ -182,7 +182,7 @@ db_enter_ddb(void) { int i; struct cpu_info *ci = curcpu(); - mtx_enter(&ddb_mp_mutex); + db_mtx_enter(&ddb_mp_mutex); #ifdef DEBUG printf("db_enter_ddb %lu: state %x pause %x\n", ci->ci_cpuid, @@ -200,7 +200,7 @@ db_enter_ddb(void) mips64_send_ipi(get_cpu_info(i)->ci_cpuid, MIPS64_IPI_DDB); } } - mtx_leave(&ddb_mp_mutex); + db_mtx_leave(&ddb_mp_mutex); return (1); } @@ -209,7 +209,7 @@ db_enter_ddb(void) for (i = 0; i < ncpus; i++) { get_cpu_info(i)->ci_ddb = CI_DDB_RUNNING; } - mtx_leave(&ddb_mp_mutex); + db_mtx_leave(&ddb_mp_mutex); return (0); } @@ -227,21 +227,21 @@ db_enter_ddb(void) ci->ci_ddb != CI_DDB_RUNNING) { if (ci->ci_ddb == CI_DDB_SHOULDSTOP) ci->ci_ddb = CI_DDB_STOPPED; - mtx_leave(&ddb_mp_mutex); + db_mtx_leave(&ddb_mp_mutex); /* Busy wait without locking, we will confirm with lock later */ while (ddb_active_cpu != cpu_number() && ci->ci_ddb != CI_DDB_RUNNING) ; /* Do nothing */ - mtx_enter(&ddb_mp_mutex); + db_mtx_enter(&ddb_mp_mutex); } /* Either enter ddb or exit */ if (ddb_active_cpu == cpu_number() && ddb_state == DDB_STATE_RUNNING) { ci->ci_ddb = CI_DDB_INDDB; - mtx_leave(&ddb_mp_mutex); + db_mtx_leave(&ddb_mp_mutex); return (1); } else { - mtx_leave(&ddb_mp_mutex); + db_mtx_leave(&ddb_mp_mutex); return (0); } } @@ -604,23 +604,23 @@ void db_startcpu(int cpu) { if (cpu != cpu_number() && cpu < ncpus) { - mtx_enter(&ddb_mp_mutex); + db_mtx_enter(&ddb_mp_mutex); get_cpu_info(cpu)->ci_ddb = CI_DDB_RUNNING; - mtx_leave(&ddb_mp_mutex); + db_mtx_leave(&ddb_mp_mutex); } } void db_stopcpu(int cpu) { - mtx_enter(&ddb_mp_mutex); + db_mtx_enter(&ddb_mp_mutex); if (cpu != cpu_number() && cpu < ncpus && get_cpu_info(cpu)->ci_ddb != CI_DDB_STOPPED) { get_cpu_info(cpu)->ci_ddb = CI_DDB_SHOULDSTOP; - mtx_leave(&ddb_mp_mutex); + db_mtx_leave(&ddb_mp_mutex); mips64_send_ipi(cpu, MIPS64_IPI_DDB); } else { - mtx_leave(&ddb_mp_mutex); + db_mtx_leave(&ddb_mp_mutex); } } #endif |