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);
|
void trapinit0(void);
|
||||||
int tas(void*);
|
int tas(void*);
|
||||||
int tryrdmsr(int, vlong*);
|
int tryrdmsr(int, vlong*);
|
||||||
void tryrdmsrbody(void);
|
|
||||||
int trywrmsr(int, vlong);
|
int trywrmsr(int, vlong);
|
||||||
void trywrmsrbody(void);
|
|
||||||
uvlong tscticks(uvlong*);
|
uvlong tscticks(uvlong*);
|
||||||
ulong umbmalloc(ulong, int, int);
|
ulong umbmalloc(ulong, int, int);
|
||||||
void umbfree(ulong, int);
|
void umbfree(ulong, int);
|
||||||
|
|
|
@ -695,7 +695,7 @@ TEXT rdmsr(SB), $0 /* model-specific register */
|
||||||
TEXT tryrdmsr(SB), $0 /* model-specific register */
|
TEXT tryrdmsr(SB), $0 /* model-specific register */
|
||||||
MOVL $0, BP
|
MOVL $0, BP
|
||||||
MOVL index+0(FP), CX
|
MOVL index+0(FP), CX
|
||||||
TEXT tryrdmsrbody(SB), $0
|
TEXT _tryrdmsrinst(SB), $0
|
||||||
RDMSR
|
RDMSR
|
||||||
MOVL vlong+4(FP), CX /* &vlong */
|
MOVL vlong+4(FP), CX /* &vlong */
|
||||||
MOVL AX, 0(CX) /* lo */
|
MOVL AX, 0(CX) /* lo */
|
||||||
|
@ -715,7 +715,7 @@ TEXT trywrmsr(SB), $0
|
||||||
MOVL index+0(FP), CX
|
MOVL index+0(FP), CX
|
||||||
MOVL lo+4(FP), AX
|
MOVL lo+4(FP), AX
|
||||||
MOVL hi+8(FP), DX
|
MOVL hi+8(FP), DX
|
||||||
TEXT trywrmsrbody(SB), $0
|
TEXT _trywrmsrinst(SB), $0
|
||||||
WRMSR
|
WRMSR
|
||||||
MOVL BP, AX
|
MOVL BP, AX
|
||||||
RET
|
RET
|
||||||
|
@ -1065,11 +1065,16 @@ intrcommon:
|
||||||
TEXT forkret(SB), $0
|
TEXT forkret(SB), $0
|
||||||
POPL AX
|
POPL AX
|
||||||
POPAL
|
POPAL
|
||||||
|
TEXT _forkretpopgs(SB), $0
|
||||||
POPL GS
|
POPL GS
|
||||||
|
TEXT _forkretpopfs(SB), $0
|
||||||
POPL FS
|
POPL FS
|
||||||
|
TEXT _forkretpopes(SB), $0
|
||||||
POPL ES
|
POPL ES
|
||||||
|
TEXT _forkretpopds(SB), $0
|
||||||
POPL DS
|
POPL DS
|
||||||
ADDL $8, SP /* pop error code and trap type */
|
ADDL $8, SP /* pop error code and trap type */
|
||||||
|
TEXT _forkretiret(SB), $0
|
||||||
IRETL
|
IRETL
|
||||||
|
|
||||||
TEXT vectortable(SB), $0
|
TEXT vectortable(SB), $0
|
||||||
|
|
|
@ -425,51 +425,48 @@ trap(Ureg* ureg)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vno == VectorGPF || vno == VectorSNP){
|
if(!user){
|
||||||
ulong *sp;
|
void (*pc)(void);
|
||||||
uchar *pc;
|
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_fs(ulong);
|
||||||
extern void load_gs(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_fs(NULLSEL);
|
||||||
load_gs(NULLSEL);
|
load_gs(NULLSEL);
|
||||||
|
|
||||||
pc = (uchar*)ureg->pc;
|
sp = (ulong*)&ureg->sp; /* kernel stack */
|
||||||
sp = (ulong*)&ureg->sp;
|
pc = (void*)ureg->pc;
|
||||||
|
|
||||||
/*
|
if(pc == _forkretpopgs || pc == _forkretpopfs ||
|
||||||
* we test for the instructions used by forkret()
|
pc == _forkretpopes || pc == _forkretpopds){
|
||||||
* to load the segments and replace the selectors
|
if(vno == VectorGPF || vno == VectorSNP){
|
||||||
* on the (kernel) stack with null selectors.
|
sp[0] = NULLSEL;
|
||||||
*/
|
return;
|
||||||
switch(pc[0]){
|
}
|
||||||
case 0x0f: /* POP GS/FS */
|
} else if(pc == _forkretiret){
|
||||||
if(pc[1] != 0xa9 && pc[1] != 0xa1)
|
if(vno == VectorGPF || vno == VectorSNP){
|
||||||
break;
|
sp[1] = UESEL; /* CS */
|
||||||
case 0x07: /* POP ES */
|
sp[4] = UDSEL; /* SS */
|
||||||
case 0x1f: /* POP DS */
|
return;
|
||||||
sp[0] = NULLSEL;
|
}
|
||||||
return;
|
} else if(pc == _tryrdmsrinst || pc == _trywrmsrinst){
|
||||||
case 0xcf: /* IRET */
|
if(vno == VectorGPF){
|
||||||
sp[1] = UESEL; /* CS */
|
ureg->bp = -1;
|
||||||
sp[4] = UDSEL; /* SS */
|
ureg->pc += 2;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(vno == VectorGPF && !user &&
|
|
||||||
(ureg->pc == (ulong)(void*)tryrdmsrbody ||
|
|
||||||
ureg->pc == (ulong)(void*)trywrmsrbody)){
|
|
||||||
ureg->bp = -1;
|
|
||||||
ureg->pc += 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dumpregs(ureg);
|
dumpregs(ureg);
|
||||||
if(!user){
|
if(!user){
|
||||||
ureg->sp = (ulong)&ureg->sp;
|
ureg->sp = (ulong)&ureg->sp;
|
||||||
|
|
Loading…
Reference in a new issue