shithub: riscv

Download patch

ref: dea6bc51bcb43f5a8330b7786c0f593e8c460b7e
parent: 89f71fa9ed166c06a23937544b453f65fb224456
author: aiju <devnull@localhost>
date: Mon Jun 12 18:58:25 EDT 2017

pc/pc64: debugexc: ignore exception if in kernel mode and can't get hold of up->debug

--- a/sys/src/9/pc/l.s
+++ b/sys/src/9/pc/l.s
@@ -877,6 +877,133 @@
 	MOVL	AX, DR7
 	RET
 
+/* VMX instructions */
+TEXT vmxon(SB), $0
+	/* VMXON 4(SP) */
+	BYTE	$0xf3; BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x04
+	JMP	_vmout
+
+TEXT vmxoff(SB), $0
+	BYTE	$0x0f; BYTE $0x01; BYTE $0xc4
+	JMP	_vmout
+
+TEXT vmclear(SB), $0
+	/* VMCLEAR 4(SP) */
+	BYTE	$0x66; BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x04
+	JMP	_vmout
+
+TEXT vmlaunch(SB), $0
+	PUSHFL
+	CLI
+	
+	MOVL	$0x6C14, DI
+	MOVL	SP, DX
+	BYTE	$0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
+	JBE	_launchout
+	MOVL	$0x6C16, DI
+	MOVL	$vmrestore+1(SB), DX /* add 1 to skip extra PUSHFL */
+	BYTE	$0x0f; BYTE $0x79; BYTE $0xfa /* VMWRITE DX, DI */
+	JBE	_launchout
+	
+	FPON
+	MOVL	fp+8(FP), AX
+	FXRSTOR	0(AX)
+	
+	MOVL	resume+4(FP), AX
+	TESTL	AX, AX
+	MOVL	ureg+0(FP), DI
+	MOVL	32(DI), AX
+	MOVL	AX, CR2
+	MOVL	4(DI), SI
+	MOVL	8(DI), BP
+	MOVL	16(DI), BX
+	MOVL	20(DI), DX
+	MOVL	24(DI), CX
+	MOVL	28(DI), AX
+	MOVL	0(DI), DI
+	JNE	_vmresume
+	BYTE	$0x0f; BYTE $0x01; BYTE	$0xc2 /* VMLAUNCH	*/
+	JMP	_launchout
+_vmresume:
+	BYTE	$0x0f; BYTE $0x01; BYTE $0xc3 /* VMRESUME	*/
+_launchout:
+	JC	_launchout1
+	JZ	_launchout2
+	XORL	AX, AX
+_launchret:
+	FPOFF
+	POPFL
+	RET
+_launchout1:
+	MOVL	$-1, AX
+	JMP	_launchret
+_launchout2:
+	MOVL	$-2, AX
+	JMP	_launchret
+
+TEXT vmrestore(SB), $0
+	PUSHFL /* stupid hack to make 8l happy; nexer executed */
+	PUSHL	DI
+	MOVL	ureg+0(FP), DI
+	POPL	0(DI)
+	MOVL	SI, 4(DI)
+	MOVL	BP, 8(DI)
+	MOVL	BX, 16(DI)
+	MOVL	DX, 20(DI)
+	MOVL	CX, 24(DI)
+	MOVL	AX, 28(DI)
+	MOVL	CR2, AX
+	MOVL	AX, 32(DI)
+	MOVL	fp+8(FP), AX
+	FXSAVE	0(AX)
+	FPOFF
+	XORL	AX, AX
+	POPFL
+	RET
+
+TEXT vmptrld(SB), $0
+	/* VMPTRLD 4(SP) */
+	BYTE $0x0f; BYTE $0xc7; BYTE $0x74; BYTE $0x24; BYTE $0x04
+	JMP _vmout
+
+TEXT vmwrite(SB), $0
+	MOVL addr+0(FP),DI
+	MOVL val+4(FP),DX
+	/* VMWRITE DX, DI */
+	BYTE $0x0f; BYTE $0x79; BYTE $0xfa
+	JMP _vmout
+
+TEXT vmread(SB), $0
+	MOVL addr+0(FP),DI
+	MOVL valp+4(FP),SI
+	/* VMREAD (SI), DI */
+	BYTE $0x0f; BYTE $0x78; BYTE $0x3e
+	JMP _vmout
+
+TEXT invept(SB), $0
+	MOVL type+0(FP), AX
+	/* INVEPT AX, 8(SP) */
+	BYTE $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x80; BYTE $0x44; BYTE $0x24; BYTE $0x08
+	JMP _vmout
+
+TEXT invvpid(SB), $0
+	MOVL type+0(FP), AX
+	/* INVVPID AX, 8(SP) */
+	BYTE $0x66; BYTE $0x0f; BYTE $0x38; BYTE $0x81; BYTE $0x44; BYTE $0x24; BYTE $0x08
+	JMP _vmout
+
+_vmout:
+	JC _vmout1
+	JZ _vmout2
+	XORL AX, AX
+	RET
+_vmout1:
+	MOVL $-1, AX
+	RET
+_vmout2:
+	MOVL $-2, AX
+	RET
+
 /*
  *  Used to get to the first process:
  * 	set up an interrupt return frame and IRET to user level.
--- a/sys/src/9/pc/pcf
+++ b/sys/src/9/pc/pcf
@@ -36,6 +36,9 @@
 	i82365		cis
 	uart
 	usb
+	
+	segment
+	vmx
 
 link
 	segdesc
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -629,7 +629,7 @@
 }
 
 static void
-debugexc(Ureg *, void *)
+debugexc(Ureg *ureg, void *)
 {
 	u32int dr6, m;
 	char buf[ERRMAX];
@@ -640,12 +640,16 @@
 	if(up == nil)
 		panic("kernel debug exception dr6=%#.8ux", dr6);
 	putdr6(up->dr[6]);
+	if(userureg(ureg))
+		qlock(&up->debug);
+	else if(!canqlock(&up->debug))
+		return;
 	m = up->dr[7];
 	m = (m >> 4 | m >> 3) & 8 | (m >> 3 | m >> 2) & 4 | (m >> 2 | m >> 1) & 2 | (m >> 1 | m) & 1;
 	m &= dr6;
 	if(m == 0){
 		sprint(buf, "sys: debug exception dr6=%#.8ux", dr6);
-		postnote(up, 1, buf, NDebug);
+		postnote(up, 0, buf, NDebug);
 	}else{
 		p = buf;
 		e = buf + sizeof(buf);
@@ -653,8 +657,9 @@
 		for(i = 0; i < 4; i++)
 			if((m & 1<<i) != 0)
 				p = seprint(p, e, "%d%s", i, (m >> i + 1 != 0) ? "," : "");
-		postnote(up, 1, buf, NDebug);
+		postnote(up, 0, buf, NDebug);
 	}
+	qunlock(&up->debug);
 }
 
 static void
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -590,7 +590,7 @@
 }
 
 static void
-debugexc(Ureg *, void *)
+debugexc(Ureg *ureg, void *)
 {
 	u64int dr6, m;
 	char buf[ERRMAX];
@@ -601,12 +601,16 @@
 	if(up == nil)
 		panic("kernel debug exception dr6=%#.8ullx", dr6);
 	putdr6(up->dr[6]);
+	if(userureg(ureg))
+		qlock(&up->debug);
+	else if(!canqlock(&up->debug))
+		return;
 	m = up->dr[7];
 	m = (m >> 4 | m >> 3) & 8 | (m >> 3 | m >> 2) & 4 | (m >> 2 | m >> 1) & 2 | (m >> 1 | m) & 1;
 	m &= dr6;
 	if(m == 0){
 		sprint(buf, "sys: debug exception dr6=%#.8ullx", dr6);
-		postnote(up, 1, buf, NDebug);
+		postnote(up, 0, buf, NDebug);
 	}else{
 		p = buf;
 		e = buf + sizeof(buf);
@@ -614,8 +618,9 @@
 		for(i = 0; i < 4; i++)
 			if((m & 1<<i) != 0)
 				p = seprint(p, e, "%d%s", i, (m >> i + 1 != 0) ? "," : "");
-		postnote(up, 1, buf, NDebug);
+		postnote(up, 0, buf, NDebug);
 	}
+	qunlock(&up->debug);
 }
 			
 static void
--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -820,9 +820,9 @@
 		if(f[1] == q || *q != 0 || x != (uintptr) x) error("invalid address");
 		wq->addr = x;
 		x = strtoull(f[2], &q, 0);
-		if(f[2] == q || *q != 0 || x != (uintptr) x) error("invalid length");
+		if(f[2] == q || *q != 0 || x > (uintptr)-wq->addr) error("invalid length");
 		wq->len = x;
-		if(!okaddr(wq->addr, wq->len, 0)) error("bad address");
+		if(wq->addr + wq->len > USTKTOP) error("bad address");
 		wq++;
 	}
 	nwp = wq - (wp + nwp0);