shithub: riscv

Download patch

ref: 5be936a1926529abc8c9a0aa2cdca81d8e6583ec
parent: 61a8b5c8037a78843815eccc225487b27b1547a7
author: cinap_lenrek <cinap_lenrek@localhost>
date: Wed Jul 20 03:48:33 EDT 2011

pc/trap: cleanup exception handling

--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -168,9 +168,7 @@
 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
@@ -695,7 +695,7 @@
 TEXT tryrdmsr(SB), $0				/* model-specific register */
 	MOVL	$0, BP
 	MOVL	index+0(FP), CX
-TEXT tryrdmsrbody(SB), $0
+TEXT _tryrdmsrinst(SB), $0
 	RDMSR
 	MOVL	vlong+4(FP), CX			/* &vlong */
 	MOVL	AX, 0(CX)			/* lo */
@@ -715,7 +715,7 @@
 	MOVL	index+0(FP), CX
 	MOVL	lo+4(FP), AX
 	MOVL	hi+8(FP), DX
-TEXT trywrmsrbody(SB), $0
+TEXT _trywrmsrinst(SB), $0
 	WRMSR
 	MOVL	BP, AX
 	RET
@@ -1065,11 +1065,16 @@
 TEXT forkret(SB), $0
 	POPL	AX
 	POPAL
+TEXT _forkretpopgs(SB), $0
 	POPL	GS
+TEXT _forkretpopfs(SB), $0
 	POPL	FS
+TEXT _forkretpopes(SB), $0
 	POPL	ES
+TEXT _forkretpopds(SB), $0
 	POPL	DS
 	ADDL	$8, SP			/* pop error code and trap type */
+TEXT _forkretiret(SB), $0
 	IRETL
 
 TEXT vectortable(SB), $0
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -425,51 +425,48 @@
 				;
 		}
 
-		if(vno == VectorGPF || vno == VectorSNP){
-			ulong *sp;
-			uchar *pc;
+		if(!user){
+			void (*pc)(void);
+			ulong *sp; 
 
-			/* l.s */
+			extern void _forkretpopgs(void);
+			extern void _forkretpopfs(void);
+			extern void _forkretpopes(void);
+			extern void _forkretpopds(void);
+			extern void _forkretiret(void);
+			extern void _tryrdmsrinst(void);
+			extern void _trywrmsrinst(void);
+
 			extern void load_fs(ulong);
 			extern void load_gs(ulong);
 
-			/*
-			 * CS, SS, DS and ES are initialized by strayintr
-			 * in l.s. initialize the others too so we dont trap
-			 * again when restoring the old context.
-			 */
 			load_fs(NULLSEL);
 			load_gs(NULLSEL);
 
-			pc = (uchar*)ureg->pc;
-			sp = (ulong*)&ureg->sp;
+			sp = (ulong*)&ureg->sp;	/* kernel stack */
+			pc = (void*)ureg->pc;
 
-			/*
-			 * we test for the instructions used by forkret()
-			 * to load the segments and replace the selectors 
-			 * on the (kernel) stack with null selectors.
-			 */
-			switch(pc[0]){
-			case 0x0f:	/* POP GS/FS */
-				if(pc[1] != 0xa9 && pc[1] != 0xa1)
-					break;
-			case 0x07:	/* POP ES */
-			case 0x1f:	/* POP DS */
-				sp[0] = NULLSEL;
-				return;
-			case 0xcf:	/* IRET */
-				sp[1] = UESEL;	/* CS */
-				sp[4] = UDSEL;	/* SS */
-				return;
+			if(pc == _forkretpopgs || pc == _forkretpopfs || 
+			   pc == _forkretpopes || pc == _forkretpopds){
+				if(vno == VectorGPF || vno == VectorSNP){
+					sp[0] = NULLSEL;
+					return;
+				}
+			} else if(pc == _forkretiret){
+				if(vno == VectorGPF || vno == VectorSNP){
+					sp[1] = UESEL;	/* CS */
+					sp[4] = UDSEL;	/* SS */
+					return;
+				}
+			} else if(pc == _tryrdmsrinst || pc == _trywrmsrinst){
+				if(vno == VectorGPF){
+					ureg->bp = -1;
+					ureg->pc += 2;
+					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;