diff options
author | aiju <devnull@localhost> | 2017-06-12 22:58:25 +0000 |
---|---|---|
committer | aiju <devnull@localhost> | 2017-06-12 22:58:25 +0000 |
commit | dea6bc51bcb43f5a8330b7786c0f593e8c460b7e (patch) | |
tree | 8c02ae26a5e8b1ad142a2d7f0b4aa927ccf30a66 | |
parent | 89f71fa9ed166c06a23937544b453f65fb224456 (diff) |
pc/pc64: debugexc: ignore exception if in kernel mode and can't get hold of up->debug
-rw-r--r-- | sys/src/9/pc/l.s | 127 | ||||
-rw-r--r-- | sys/src/9/pc/pcf | 3 | ||||
-rw-r--r-- | sys/src/9/pc/trap.c | 11 | ||||
-rw-r--r-- | sys/src/9/pc64/trap.c | 11 | ||||
-rw-r--r-- | sys/src/9/port/devproc.c | 4 |
5 files changed, 148 insertions, 8 deletions
diff --git a/sys/src/9/pc/l.s b/sys/src/9/pc/l.s index 600188b62..4e0a9a031 100644 --- a/sys/src/9/pc/l.s +++ b/sys/src/9/pc/l.s @@ -877,6 +877,133 @@ TEXT putdr7(SB), $0 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. diff --git a/sys/src/9/pc/pcf b/sys/src/9/pc/pcf index a34964559..e51e33ceb 100644 --- a/sys/src/9/pc/pcf +++ b/sys/src/9/pc/pcf @@ -36,6 +36,9 @@ dev i82365 cis uart usb + + segment + vmx link segdesc diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c index b7877563d..fbc80024d 100644 --- a/sys/src/9/pc/trap.c +++ b/sys/src/9/pc/trap.c @@ -629,7 +629,7 @@ dumpstack(void) } static void -debugexc(Ureg *, void *) +debugexc(Ureg *ureg, void *) { u32int dr6, m; char buf[ERRMAX]; @@ -640,12 +640,16 @@ debugexc(Ureg *, void *) 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 @@ debugexc(Ureg *, void *) 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 diff --git a/sys/src/9/pc64/trap.c b/sys/src/9/pc64/trap.c index 5ac1b0d6b..4dec706d5 100644 --- a/sys/src/9/pc64/trap.c +++ b/sys/src/9/pc64/trap.c @@ -590,7 +590,7 @@ dumpstack(void) } static void -debugexc(Ureg *, void *) +debugexc(Ureg *ureg, void *) { u64int dr6, m; char buf[ERRMAX]; @@ -601,12 +601,16 @@ debugexc(Ureg *, void *) 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 @@ debugexc(Ureg *, void *) 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 diff --git a/sys/src/9/port/devproc.c b/sys/src/9/port/devproc.c index d960d0eec..425cbc962 100644 --- a/sys/src/9/port/devproc.c +++ b/sys/src/9/port/devproc.c @@ -820,9 +820,9 @@ writewatchpt(Proc *pr, char *buf, int nbuf, uvlong offset) 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); |