summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2003-03-24 10:17:14 +0000
committerbde <bde@FreeBSD.org>2003-03-24 10:17:14 +0000
commit79afd37295979afa452a4b5ed75ac6a74f9569fe (patch)
tree4b95fc998041d683ead48a7c799ac1e529d0f525
parent97be9a96e65371bca742adf3199022c9e8bf0aeb (diff)
downloadFreeBSD-src-79afd37295979afa452a4b5ed75ac6a74f9569fe.zip
FreeBSD-src-79afd37295979afa452a4b5ed75ac6a74f9569fe.tar.gz
Disable interrupts while in kdb_trap() to handle cases where the caller
doesn't do it. This fixes all known causes of "Context switches not allowed in the debugger" in mi_switch(). The main cause was trap_fatal() calling kdb_trap() with interrupts enabled. Switching to ithreads for interrupt handling then made fatal traps more fatal and harder to debug. The problem was limited in -current because most interrupt handlers are blocked by Giant, but it occurred almost deterministically for me because my clock interrupt handlers are non-fast and not blocked by Giant.
-rw-r--r--sys/amd64/amd64/db_interface.c7
-rw-r--r--sys/i386/i386/db_interface.c7
2 files changed, 14 insertions, 0 deletions
diff --git a/sys/amd64/amd64/db_interface.c b/sys/amd64/amd64/db_interface.c
index f1ba48c..e2b936b 100644
--- a/sys/amd64/amd64/db_interface.c
+++ b/sys/amd64/amd64/db_interface.c
@@ -77,6 +77,7 @@ rss(void)
int
kdb_trap(int type, int code, struct i386_saved_state *regs)
{
+ u_int ef;
volatile int ddb_mode = !(boothowto & RB_GDB);
/*
@@ -96,6 +97,9 @@ kdb_trap(int type, int code, struct i386_saved_state *regs)
return (0);
}
+ ef = read_eflags();
+ disable_intr();
+
switch (type) {
case T_BPTFLT: /* breakpoint */
case T_TRCTRAP: /* debug exception */
@@ -216,6 +220,9 @@ kdb_trap(int type, int code, struct i386_saved_state *regs)
regs->tf_fs = ddb_regs.tf_fs & 0xffff;
regs->tf_cs = ddb_regs.tf_cs & 0xffff;
regs->tf_ds = ddb_regs.tf_ds & 0xffff;
+
+ write_eflags(ef);
+
return (1);
}
diff --git a/sys/i386/i386/db_interface.c b/sys/i386/i386/db_interface.c
index f1ba48c..e2b936b 100644
--- a/sys/i386/i386/db_interface.c
+++ b/sys/i386/i386/db_interface.c
@@ -77,6 +77,7 @@ rss(void)
int
kdb_trap(int type, int code, struct i386_saved_state *regs)
{
+ u_int ef;
volatile int ddb_mode = !(boothowto & RB_GDB);
/*
@@ -96,6 +97,9 @@ kdb_trap(int type, int code, struct i386_saved_state *regs)
return (0);
}
+ ef = read_eflags();
+ disable_intr();
+
switch (type) {
case T_BPTFLT: /* breakpoint */
case T_TRCTRAP: /* debug exception */
@@ -216,6 +220,9 @@ kdb_trap(int type, int code, struct i386_saved_state *regs)
regs->tf_fs = ddb_regs.tf_fs & 0xffff;
regs->tf_cs = ddb_regs.tf_cs & 0xffff;
regs->tf_ds = ddb_regs.tf_ds & 0xffff;
+
+ write_eflags(ef);
+
return (1);
}
OpenPOWER on IntegriCloud