pc/trap: cleanup exception handling

This commit is contained in:
cinap_lenrek 2011-07-20 07:48:33 +02:00
parent 61a8b5c803
commit 5be936a192
3 changed files with 39 additions and 39 deletions

View file

@ -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);

View file

@ -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

View file

@ -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;
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;