summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2014-11-16 22:02:09 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2014-11-16 22:05:27 +0100
commite4f0d5fcc0f885ea34f83176b23871bba6346cc8 (patch)
tree2eddbb188cccbe7529c7dbc3f2e744a70ef1be37
parentacf1525f4dec4088c075e4d7847be7305873a3a9 (diff)
Only set debug registers when they are used
* i386/i386/db_interface.c (zero_dr): New variable (db_load_context): Do not set debug registers to zero when they are already zero. (db_dr): When kernel debug registers get zero, record that the debug registers have been zeroed.
-rw-r--r--i386/i386/db_interface.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/i386/i386/db_interface.c b/i386/i386/db_interface.c
index b442b862..b3fac0bb 100644
--- a/i386/i386/db_interface.c
+++ b/i386/i386/db_interface.c
@@ -63,6 +63,8 @@
/* Whether the kernel uses any debugging register. */
static boolean_t kernel_dr;
#endif
+/* Whether the current debug registers are zero. */
+static boolean_t zero_dr;
void db_load_context(pcb_t pcb)
{
@@ -74,13 +76,20 @@ void db_load_context(pcb_t pcb)
return;
}
#endif
+ /* Else set user debug registers, if any */
+ unsigned int *dr = pcb->ims.ids.dr;
+ boolean_t will_zero_dr = !dr[0] && !dr[1] && !dr[2] && !dr[3] && !dr[7];
+
+ if (!(zero_dr && will_zero_dr))
+ {
+ set_dr0(dr[0]);
+ set_dr1(dr[1]);
+ set_dr2(dr[2]);
+ set_dr3(dr[3]);
+ set_dr7(dr[7]);
+ zero_dr = will_zero_dr;
+ }
- /* Else set user debug registers */
- set_dr0(pcb->ims.ids.dr[0]);
- set_dr1(pcb->ims.ids.dr[1]);
- set_dr2(pcb->ims.ids.dr[2]);
- set_dr3(pcb->ims.ids.dr[3]);
- set_dr7(pcb->ims.ids.dr[7]);
#if MACH_KDB
splx(s);
#endif
@@ -163,7 +172,9 @@ void db_dr (
if (kernel_dr) {
if (!ids.dr[0] && !ids.dr[1] && !ids.dr[2] && !ids.dr[3]) {
/* Not used any more, switch back to user debugging registers */
+ set_dr7 (0);
kernel_dr = FALSE;
+ zero_dr = TRUE;
db_load_context(current_thread()->pcb);
}
}