ref: 03d71535eca82570372650678eb91e447eacfb86
parent: eee8fc8f2a9a17f194d6ecf0ddcf46bbcf6f9a66
author: aiju <[email protected]>
date: Tue Jul 19 11:42:00 EDT 2011
reading from/writing to non-existant MSRs via /dev/msr no longer crashes the system
--- a/sys/src/9/pc/devarch.c
+++ b/sys/src/9/pc/devarch.c
@@ -397,7 +397,8 @@
error(Ebadarg);
vp = a;
for(port = offset; port < offset+n; port += 8)
- rdmsr(port, vp++);
+ if(tryrdmsr(port, vp++) < 0)
+ error(Ebadarg);
return n;
case Qioalloc:
@@ -475,7 +476,8 @@
error(Ebadarg);
vp = a;
for(port = offset; port < offset+n; port += 8)
- wrmsr(port, *vp++);
+ if(trywrmsr(port, *vp++) < 0)
+ error(Ebadarg);
return n;
default:
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -167,6 +167,10 @@
void trapinit(void);
void trapinit0(void);
int tas(void*);
+int tryrdmsr(int, vlong*);
+void tryrdmsrbody(void);
+int trywrmsr(int, vlong);
+void trywrmsrbody(void);
uvlong tscticks(uvlong*);
ulong umbmalloc(ulong, int, int);
void umbfree(ulong, int);
--- a/sys/src/9/pc/l.s
+++ b/sys/src/9/pc/l.s
@@ -691,6 +691,17 @@
MOVL AX, 0(CX) /* lo */
MOVL DX, 4(CX) /* hi */
RET
+
+TEXT tryrdmsr(SB), $0 /* model-specific register */
+ MOVL $0, BP
+ MOVL index+0(FP), CX
+TEXT tryrdmsrbody(SB), $0
+ RDMSR
+ MOVL vlong+4(FP), CX /* &vlong */
+ MOVL AX, 0(CX) /* lo */
+ MOVL DX, 4(CX) /* hi */
+ MOVL BP, AX
+ RET
TEXT wrmsr(SB), $0
MOVL index+0(FP), CX
@@ -697,6 +708,16 @@
MOVL lo+4(FP), AX
MOVL hi+8(FP), DX
WRMSR
+ RET
+
+TEXT trywrmsr(SB), $0
+ MOVL $0, BP
+ MOVL index+0(FP), CX
+ MOVL lo+4(FP), AX
+ MOVL hi+8(FP), DX
+TEXT trywrmsrbody(SB), $0
+ WRMSR
+ MOVL BP, AX
RET
/*
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -463,7 +463,13 @@
return;
}
}
-
+ if(vno == VectorGPF && !user &&
+ (ureg->pc == (ulong)(void*)tryrdmsrbody ||
+ ureg->pc == (ulong)(void*)trywrmsrbody)){
+ ureg->bp = -1;
+ ureg->pc += 2;
+ return;
+ }
dumpregs(ureg);
if(!user){
ureg->sp = (ulong)&ureg->sp;