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);