diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-12-02 23:32:24 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-12-02 23:32:24 +0100 |
commit | 5d59a44c21a14ed30034c27681f76efe1856b993 (patch) | |
tree | 43b75d1339d535ab1ee38d47a62876f625e425e7 /sys/src | |
parent | a8152739604244b0ab77c339955d799e63df5ce8 (diff) |
pc, pc64: clear debug watchpoint registers on exec and exit
when a process does an exec syscall, procsetup() is called and
we have to disable the debug watchpoint registers. just clearing
p->dr is not enougth as we are not going thru a procsave() and
procrestore() cycle which would disable and reload the saved
debug registers.
instead of clearing debug registers in procfork(), we should
clear the saved debug registers before a process goes to die
(pexit() calls sched() with up->state = Moribund) as the Proc
structure can get reused for kernel processes (kproc) which
never call procfork() and would therefore have debug registers
loaded.
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/pc/main.c | 24 | ||||
-rw-r--r-- | sys/src/9/pc64/main.c | 18 |
2 files changed, 28 insertions, 14 deletions
diff --git a/sys/src/9/pc/main.c b/sys/src/9/pc/main.c index 7d2e86b8d..5efebc809 100644 --- a/sys/src/9/pc/main.c +++ b/sys/src/9/pc/main.c @@ -585,13 +585,18 @@ procsetup(Proc *p) p->fpstate = FPinit; fpoff(); - cycles(&p->kentry); - p->pcycles = -p->kentry; - memset(p->gdt, 0, sizeof(p->gdt)); p->nldt = 0; + /* clear debug registers */ memset(p->dr, 0, sizeof(p->dr)); + if(m->dr7 != 0){ + m->dr7 = 0; + putdr7(0); + } + + cycles(&p->kentry); + p->pcycles = -p->kentry; } void @@ -624,9 +629,6 @@ procfork(Proc *p) memmove(p->fpsave, up->fpsave, sizeof(FPsave)); p->fpstate = FPinactive; } - - /* clear debug registers */ - memset(p->dr, 0, sizeof(p->dr)); splx(s); } @@ -659,15 +661,17 @@ procsave(Proc *p) { uvlong t; + cycles(&t); + p->kentry -= t; + p->pcycles += t; + /* we could just always putdr7(0) but accessing DR7 might be slow in a VM */ if(m->dr7 != 0){ m->dr7 = 0; putdr7(0); } - - cycles(&t); - p->kentry -= t; - p->pcycles += t; + if(p->state == Moribund) + p->dr[7] = 0; if(p->fpstate == FPactive){ if(p->state == Moribund) diff --git a/sys/src/9/pc64/main.c b/sys/src/9/pc64/main.c index 1abad73e4..aab95a484 100644 --- a/sys/src/9/pc64/main.c +++ b/sys/src/9/pc64/main.c @@ -581,6 +581,14 @@ procsetup(Proc *p) { p->fpstate = FPinit; _stts(); + + /* clear debug registers */ + memset(p->dr, 0, sizeof(p->dr)); + if(m->dr7 != 0){ + m->dr7 = 0; + putdr7(0); + } + cycles(&p->kentry); p->pcycles = -p->kentry; } @@ -639,14 +647,16 @@ procsave(Proc *p) { uvlong t; + cycles(&t); + p->kentry -= t; + p->pcycles += t; + if(m->dr7 != 0){ m->dr7 = 0; putdr7(0); } - - cycles(&t); - p->kentry -= t; - p->pcycles += t; + if(p->state == Moribund) + p->dr[7] = 0; switch(p->fpstate & ~(FPnouser|FPkernel|FPindexm)){ case FPactive | FPpush: |