--- /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*) {