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