--- /sys/src/9/pc/fns.h
+++ /sys/src/9/pc/fns.h
@@ -158,7 +158,7 @@ void putcr0(ulong);
void putcr3(ulong);
void putcr4(ulong);
void* rampage(void);
-void rdmsr(int, vlong*);
+int rdmsr(int, vlong*);
void realmode(Ureg*);
void screeninit(void);
void (*screenputs)(char*, int);
diff --git a/sys/src/9/pc/io.h b/sys/src/9/pc/io.h
index 0b85d09f9..35ff5fb60 100644
--- a/sys/src/9/pc/io.h
+++ b/sys/src/9/pc/io.h
@@ -10,6 +10,7 @@ enum {
VectorCNA = 7, /* coprocessor not available */
Vector2F = 8, /* double fault */
VectorCSO = 9, /* coprocessor segment overrun */
+ VectorGPF = 13, /* General protection fault */
VectorPF = 14, /* page fault */
Vector15 = 15, /* reserved */
VectorCERR = 16, /* coprocessor error */
--- /sys/src/9/pc/l.s
+++ /sys/src/9/pc/l.s
@@ -673,11 +673,17 @@ TEXT lcycles(SB),1,$0
TEXT rdmsr(SB), $0 /* model-specific register */
MOVL index+0(FP), CX
+TEXT mayberdmsr(SB), $0
RDMSR
+_rdmsrret:
MOVL vlong+4(FP), CX /* &vlong */
MOVL AX, 0(CX) /* lo */
MOVL DX, 4(CX) /* hi */
RET
+TEXT rdmsrfail(SB), $0
+ MOVL $0xffffffff, AX
+ MOVL AX, DX
+ JMP _rdmsrret
TEXT wrmsr(SB), $0
MOVL index+0(FP), CX
--- /sys/src/9/pc/trap.c
+++ /sys/src/9/pc/trap.c
@@ -14,6 +14,7 @@ static int trapinited;
void noted(Ureg*, ulong);
static void debugbpt(Ureg*, void*);
+static void faultgpf(Ureg*, void*);
static void fault386(Ureg*, void*);
static void doublefault(Ureg*, void*);
static void unexpected(Ureg*, void*);
@@ -221,6 +222,7 @@ trapinit(void)
*/
trapenable(VectorBPT, debugbpt, 0, "debugpt");
trapenable(VectorPF, fault386, 0, "fault386");
+ trapenable(VectorGPF, faultgpf, 0, "faultgpf");
trapenable(Vector2F, doublefault, 0, "doublefault");
trapenable(Vector15, unexpected, 0, "unexpected");
nmienable();
@@ -608,6 +610,17 @@ unexpected(Ureg* ureg, void*)
extern void checkpages(void);
extern void checkfault(ulong, ulong);
+extern void mayberdmsr(void);
+extern void rdmsrfail(void);
+
+static void
+faultgpf(Ureg* ureg, void*)
+{
+ if(ureg->pc != (ulong)mayberdmsr)
+ panic("unhandled GPF at 0x%.8lux", ureg->pc);
+ ureg->pc = (ulong)rdmsrfail;
+}
+
static void
fault386(Ureg* ureg, void*)
{
|