shithub: riscv

Download patch

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;