pc/trap: cleanup exception handling
This commit is contained in:
parent
61a8b5c803
commit
5be936a192
3 changed files with 39 additions and 39 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -425,51 +425,48 @@ trap(Ureg* ureg)
|
|||
;
|
||||
}
|
||||
|
||||
if(vno == VectorGPF || vno == VectorSNP){
|
||||
if(!user){
|
||||
void (*pc)(void);
|
||||
ulong *sp;
|
||||
uchar *pc;
|
||||
|
||||
/* 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 */
|
||||
if(pc == _forkretpopgs || pc == _forkretpopfs ||
|
||||
pc == _forkretpopes || pc == _forkretpopds){
|
||||
if(vno == VectorGPF || vno == VectorSNP){
|
||||
sp[0] = NULLSEL;
|
||||
return;
|
||||
case 0xcf: /* IRET */
|
||||
}
|
||||
} else if(pc == _forkretiret){
|
||||
if(vno == VectorGPF || vno == VectorSNP){
|
||||
sp[1] = UESEL; /* CS */
|
||||
sp[4] = UDSEL; /* SS */
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(vno == VectorGPF && !user &&
|
||||
(ureg->pc == (ulong)(void*)tryrdmsrbody ||
|
||||
ureg->pc == (ulong)(void*)trywrmsrbody)){
|
||||
} else if(pc == _tryrdmsrinst || pc == _trywrmsrinst){
|
||||
if(vno == VectorGPF){
|
||||
ureg->bp = -1;
|
||||
ureg->pc += 2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dumpregs(ureg);
|
||||
if(!user){
|
||||
ureg->sp = (ulong)&ureg->sp;
|
||||
|
|
Loading…
Reference in a new issue