shithub: riscv

Download patch

ref: 5d59a44c21a14ed30034c27681f76efe1856b993
parent: a8152739604244b0ab77c339955d799e63df5ce8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Dec 2 18:32:24 EST 2019

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.

--- a/sys/src/9/pc/main.c
+++ b/sys/src/9/pc/main.c
@@ -585,13 +585,18 @@
 	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 @@
 		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 @@
 {
 	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)
--- a/sys/src/9/pc64/main.c
+++ b/sys/src/9/pc64/main.c
@@ -581,6 +581,14 @@
 {
 	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 @@
 {
 	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: