summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-07-20 07:48:33 +0200
committercinap_lenrek <cinap_lenrek@localhost>2011-07-20 07:48:33 +0200
commit5be936a1926529abc8c9a0aa2cdca81d8e6583ec (patch)
treeaf81d873e2be42bc15ea112bb125970cc313302c /sys
parent61a8b5c8037a78843815eccc225487b27b1547a7 (diff)
pc/trap: cleanup exception handling
Diffstat (limited to 'sys')
-rw-r--r--sys/src/9/pc/fns.h2
-rw-r--r--sys/src/9/pc/l.s9
-rw-r--r--sys/src/9/pc/trap.c69
3 files changed, 40 insertions, 40 deletions
diff --git a/sys/src/9/pc/fns.h b/sys/src/9/pc/fns.h
index 123abca5c..3360d0995 100644
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -168,9 +168,7 @@ 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);
diff --git a/sys/src/9/pc/l.s b/sys/src/9/pc/l.s
index 6618421a2..4c6fba386 100644
--- a/sys/src/9/pc/l.s
+++ b/sys/src/9/pc/l.s
@@ -695,7 +695,7 @@ TEXT rdmsr(SB), $0 /* model-specific register */
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 @@ TEXT trywrmsr(SB), $0
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 @@ intrcommon:
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
diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c
index ba52895ea..686f9e53e 100644
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -425,51 +425,48 @@ trap(Ureg* ureg)
;
}
- if(vno == VectorGPF || vno == VectorSNP){
- ulong *sp;
- uchar *pc;
+ if(!user){
+ void (*pc)(void);
+ ulong *sp;
+
+ 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);
- /* l.s */
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;
-
- /*
- * 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;
+ sp = (ulong*)&ureg->sp; /* kernel stack */
+ pc = (void*)ureg->pc;
+
+ 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;