1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-04 09:09:56 +00:00

* Move exception_return to exception.s which is a more logical home for it.

* Optimise the return path for syscalls so that they only restore a minimal
  set of registers instead of performing a full exception_return.

A new flag in the trapframe indicates that the frame only holds partial
state. When it is necessary to perform a full state restore (e.g. after an
execve or signal), the flag is cleared to force a full restore.
This commit is contained in:
Doug Rabson 2001-01-31 11:17:00 +00:00
parent 8ab109d131
commit c586bc8e57
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=71881
5 changed files with 166 additions and 114 deletions

View File

@ -113,13 +113,15 @@
stq s4,(FRAME_S4*8)(sp)
stq s5,(FRAME_S5*8)(sp)
stq s6,(FRAME_S6*8)(sp)
stq a0,(FRAME_A0*8)(sp)
stq a1,(FRAME_A1*8)(sp)
stq a2,(FRAME_A2*8)(sp)
stq a3,(FRAME_A3*8)(sp)
stq a4,(FRAME_A4*8)(sp)
stq a5,(FRAME_A5*8)(sp)
stq ra,(FRAME_RA*8)(sp)
stq a0,(FRAME_A0*8)(sp)
stq a1,(FRAME_A1*8)(sp)
stq a2,(FRAME_A2*8)(sp)
ldiq t1,FRAME_FLAGS_SYSCALL
stq t1,(FRAME_FLAGS*8)(sp)
/* syscall number, passed in v0, is first arg, frame pointer second */
mov v0,a0
@ -128,7 +130,50 @@
XentSys1: LDGP(pv)
CALL(syscall)
jmp zero, exception_return
/* see if we need a full exception_return */
ldq t1, (FRAME_FLAGS*8)(sp)
and t1, FRAME_FLAGS_SYSCALL
beq t1, exception_return
ldl t2, GD_ASTPENDING(globalp) /* AST pending? */
beq t2, 2f /* no: return */
/* We've got an AST. Handle it. */
mov sp, a0 /* only arg is frame */
CALL(ast)
2:
/* set the hae register if this process has specified a value */
ldq t0, GD_CURPROC(globalp)
beq t0, 3f
ldq t1, P_MD_FLAGS(t0)
and t1, MDP_HAEUSED
beq t1, 3f
ldq a0, P_MD_HAE(t0)
ldq pv, chipset + CHIPSET_WRITE_HAE
CALL((pv))
3:
/* restore the registers, and return */
ldq v0,(FRAME_V0*8)(sp)
ldq s0,(FRAME_S0*8)(sp)
ldq s1,(FRAME_S1*8)(sp)
ldq s2,(FRAME_S2*8)(sp)
ldq s3,(FRAME_S3*8)(sp)
ldq s4,(FRAME_S4*8)(sp)
ldq s5,(FRAME_S5*8)(sp)
ldq s6,(FRAME_S6*8)(sp)
ldq a3,(FRAME_A3*8)(sp)
ldq a4,(FRAME_A4*8)(sp)
ldq a5,(FRAME_A5*8)(sp)
ldq ra,(FRAME_RA*8)(sp)
ldq a0,(FRAME_A0*8)(sp)
ldq a1,(FRAME_A1*8)(sp)
ldq a2,(FRAME_A2*8)(sp)
lda sp,(FRAME_SW_SIZE*8)(sp)
call_pal PAL_OSF1_retsys
END(XentSys)
/**************************************************************************/
@ -203,3 +248,111 @@ LXconsole_restart1: LDGP(pv)
call_pal PAL_halt
END(XentRestart)
/*
* exception_return: return from trap, exception, or syscall
*/
LEAF(exception_return, 1) /* XXX should be NESTED */
br pv, Ler1
Ler1: LDGP(pv)
ldq s1, (FRAME_PS * 8)(sp) /* get the saved PS */
and s1, ALPHA_PSL_IPL_MASK, t0 /* look at the saved IPL */
bne t0, Lrestoreregs /* != 0: can't do AST or SIR */
and s1, ALPHA_PSL_USERMODE, t0 /* are we returning to user? */
beq t0, Lrestoreregs /* no: just return */
ldl t2, GD_ASTPENDING(globalp) /* AST pending? */
beq t2, Lrestoreregs /* no: return */
/* We've got an AST. Handle it. */
ldiq a0, ALPHA_PSL_IPL_0 /* drop IPL to zero */
call_pal PAL_OSF1_swpipl
mov sp, a0 /* only arg is frame */
CALL(ast)
Lrestoreregs:
/* set the hae register if this process has specified a value */
ldq t0, GD_CURPROC(globalp)
beq t0, Lnohae
ldq t1, P_MD_FLAGS(t0)
and t1, MDP_HAEUSED
beq t1, Lnohae
ldq a0, P_MD_HAE(t0)
ldq pv, chipset + CHIPSET_WRITE_HAE
CALL((pv))
Lnohae:
/* restore the registers, and return */
bsr ra, exception_restore_regs /* jmp/CALL trashes pv/t12 */
ldq ra,(FRAME_RA*8)(sp)
.set noat
ldq at_reg,(FRAME_AT*8)(sp)
lda sp,(FRAME_SW_SIZE*8)(sp)
call_pal PAL_OSF1_rti
.set at
END(exception_return)
LEAF(exception_save_regs, 0)
stq v0,(FRAME_V0*8)(sp)
stq a3,(FRAME_A3*8)(sp)
stq a4,(FRAME_A4*8)(sp)
stq a5,(FRAME_A5*8)(sp)
stq s0,(FRAME_S0*8)(sp)
stq s1,(FRAME_S1*8)(sp)
stq s2,(FRAME_S2*8)(sp)
stq s3,(FRAME_S3*8)(sp)
stq s4,(FRAME_S4*8)(sp)
stq s5,(FRAME_S5*8)(sp)
stq s6,(FRAME_S6*8)(sp)
stq t0,(FRAME_T0*8)(sp)
stq t1,(FRAME_T1*8)(sp)
stq t2,(FRAME_T2*8)(sp)
stq t3,(FRAME_T3*8)(sp)
stq t4,(FRAME_T4*8)(sp)
stq t5,(FRAME_T5*8)(sp)
stq t6,(FRAME_T6*8)(sp)
stq t7,(FRAME_T7*8)(sp)
stq t8,(FRAME_T8*8)(sp)
stq t9,(FRAME_T9*8)(sp)
stq t10,(FRAME_T10*8)(sp)
stq t11,(FRAME_T11*8)(sp)
stq t12,(FRAME_T12*8)(sp)
.set noat
lda at_reg,(FRAME_SIZE*8)(sp)
stq at_reg,(FRAME_SP*8)(sp)
.set at
stq zero,(FRAME_FLAGS*8)(sp)
RET
END(exception_save_regs)
LEAF(exception_restore_regs, 0)
ldq v0,(FRAME_V0*8)(sp)
ldq a3,(FRAME_A3*8)(sp)
ldq a4,(FRAME_A4*8)(sp)
ldq a5,(FRAME_A5*8)(sp)
ldq s0,(FRAME_S0*8)(sp)
ldq s1,(FRAME_S1*8)(sp)
ldq s2,(FRAME_S2*8)(sp)
ldq s3,(FRAME_S3*8)(sp)
ldq s4,(FRAME_S4*8)(sp)
ldq s5,(FRAME_S5*8)(sp)
ldq s6,(FRAME_S6*8)(sp)
ldq t0,(FRAME_T0*8)(sp)
ldq t1,(FRAME_T1*8)(sp)
ldq t2,(FRAME_T2*8)(sp)
ldq t3,(FRAME_T3*8)(sp)
ldq t4,(FRAME_T4*8)(sp)
ldq t5,(FRAME_T5*8)(sp)
ldq t6,(FRAME_T6*8)(sp)
ldq t7,(FRAME_T7*8)(sp)
ldq t8,(FRAME_T8*8)(sp)
ldq t9,(FRAME_T9*8)(sp)
ldq t10,(FRAME_T10*8)(sp)
ldq t11,(FRAME_T11*8)(sp)
ldq t12,(FRAME_T12*8)(sp)
RET
END(exception_restore_regs)

View File

@ -133,6 +133,8 @@ ASSYM(FRAME_RA, FRAME_RA);
ASSYM(FRAME_T12, FRAME_T12);
ASSYM(FRAME_AT, FRAME_AT);
ASSYM(FRAME_SP, FRAME_SP);
ASSYM(FRAME_FLAGS, FRAME_FLAGS);
ASSYM(FRAME_FLAGS_SYSCALL, FRAME_FLAGS_SYSCALL);
ASSYM(FRAME_SW_SIZE, FRAME_SW_SIZE);

View File

@ -1324,6 +1324,7 @@ osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
*/
frame->tf_regs[FRAME_PC] = PS_STRINGS - (esigcode - sigcode);
frame->tf_regs[FRAME_A0] = sig;
frame->tf_regs[FRAME_FLAGS] = 0; /* full restore */
PROC_LOCK(p);
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig))
frame->tf_regs[FRAME_A1] = (u_int64_t)sip;
@ -1464,6 +1465,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
frame->tf_regs[FRAME_A2] = (u_int64_t)&(sfp->sf_uc);
frame->tf_regs[FRAME_T12] = (u_int64_t)catcher; /* t12 is pv */
frame->tf_regs[FRAME_FLAGS] = 0; /* full restore */
alpha_pal_wrusp((unsigned long)sfp);
#ifdef DEBUG
@ -1532,6 +1534,7 @@ osigreturn(struct proc *p,
p->p_md.md_tf->tf_regs[FRAME_PC] = ksc.sc_pc;
p->p_md.md_tf->tf_regs[FRAME_PS] =
(ksc.sc_ps | ALPHA_PSL_USERSET) & ~ALPHA_PSL_USERCLR;
p->p_md.md_tf->tf_regs[FRAME_FLAGS] = 0; /* full restore */
alpha_pal_wrusp(ksc.sc_regs[R_SP]);
@ -1578,6 +1581,7 @@ sigreturn(struct proc *p,
~ALPHA_PSL_USERCLR;
p->p_md.md_tf->tf_regs[FRAME_PS] = val;
p->p_md.md_tf->tf_regs[FRAME_PC] = uc.uc_mcontext.mc_regs[R_PC];
p->p_md.md_tf->tf_regs[FRAME_FLAGS] = 0; /* full restore */
alpha_pal_wrusp(uc.uc_mcontext.mc_regs[R_SP]);
PROC_LOCK(p);
@ -1651,6 +1655,7 @@ setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings)
tfp->tf_regs[FRAME_A2] = 0; /* a2 = rtld object */
tfp->tf_regs[FRAME_A3] = PS_STRINGS; /* a3 = ps_strings */
tfp->tf_regs[FRAME_T12] = tfp->tf_regs[FRAME_PC]; /* a.k.a. PV */
tfp->tf_regs[FRAME_FLAGS] = 0; /* full restore */
p->p_md.md_flags &= ~MDP_FPUSED;
alpha_fpstate_drop(p);

View File

@ -217,113 +217,3 @@ LEAF(switch_trampoline, 0)
mov sp, a2
jmp zero, fork_exit
END(switch_trampoline)
/**************************************************************************/
/*
* exception_return: return from trap, exception, or syscall
*/
LEAF(exception_return, 1) /* XXX should be NESTED */
br pv, Ler1
Ler1: LDGP(pv)
ldq s1, (FRAME_PS * 8)(sp) /* get the saved PS */
and s1, ALPHA_PSL_IPL_MASK, t0 /* look at the saved IPL */
bne t0, Lrestoreregs /* != 0: can't do AST or SIR */
and s1, ALPHA_PSL_USERMODE, t0 /* are we returning to user? */
beq t0, Lrestoreregs /* no: just return */
ldl t2, GD_ASTPENDING(globalp) /* AST pending? */
beq t2, Lrestoreregs /* no: return */
/* We've got an AST. Handle it. */
ldiq a0, ALPHA_PSL_IPL_0 /* drop IPL to zero */
call_pal PAL_OSF1_swpipl
mov sp, a0 /* only arg is frame */
CALL(ast)
Lrestoreregs:
/* set the hae register if this process has specified a value */
ldq t0, GD_CURPROC(globalp)
beq t0, Lnohae
ldq t1, P_MD_FLAGS(t0)
and t1, MDP_HAEUSED
beq t1, Lnohae
ldq a0, P_MD_HAE(t0)
ldq pv, chipset + CHIPSET_WRITE_HAE
CALL((pv))
Lnohae:
/* restore the registers, and return */
bsr ra, exception_restore_regs /* jmp/CALL trashes pv/t12 */
ldq ra,(FRAME_RA*8)(sp)
.set noat
ldq at_reg,(FRAME_AT*8)(sp)
lda sp,(FRAME_SW_SIZE*8)(sp)
call_pal PAL_OSF1_rti
.set at
END(exception_return)
LEAF(exception_save_regs, 0)
stq v0,(FRAME_V0*8)(sp)
stq a3,(FRAME_A3*8)(sp)
stq a4,(FRAME_A4*8)(sp)
stq a5,(FRAME_A5*8)(sp)
stq s0,(FRAME_S0*8)(sp)
stq s1,(FRAME_S1*8)(sp)
stq s2,(FRAME_S2*8)(sp)
stq s3,(FRAME_S3*8)(sp)
stq s4,(FRAME_S4*8)(sp)
stq s5,(FRAME_S5*8)(sp)
stq s6,(FRAME_S6*8)(sp)
stq t0,(FRAME_T0*8)(sp)
stq t1,(FRAME_T1*8)(sp)
stq t2,(FRAME_T2*8)(sp)
stq t3,(FRAME_T3*8)(sp)
stq t4,(FRAME_T4*8)(sp)
stq t5,(FRAME_T5*8)(sp)
stq t6,(FRAME_T6*8)(sp)
stq t7,(FRAME_T7*8)(sp)
stq t8,(FRAME_T8*8)(sp)
stq t9,(FRAME_T9*8)(sp)
stq t10,(FRAME_T10*8)(sp)
stq t11,(FRAME_T11*8)(sp)
stq t12,(FRAME_T12*8)(sp)
.set noat
lda at_reg,(FRAME_SIZE*8)(sp)
stq at_reg,(FRAME_SP*8)(sp)
.set at
RET
END(exception_save_regs)
LEAF(exception_restore_regs, 0)
ldq v0,(FRAME_V0*8)(sp)
ldq a3,(FRAME_A3*8)(sp)
ldq a4,(FRAME_A4*8)(sp)
ldq a5,(FRAME_A5*8)(sp)
ldq s0,(FRAME_S0*8)(sp)
ldq s1,(FRAME_S1*8)(sp)
ldq s2,(FRAME_S2*8)(sp)
ldq s3,(FRAME_S3*8)(sp)
ldq s4,(FRAME_S4*8)(sp)
ldq s5,(FRAME_S5*8)(sp)
ldq s6,(FRAME_S6*8)(sp)
ldq t0,(FRAME_T0*8)(sp)
ldq t1,(FRAME_T1*8)(sp)
ldq t2,(FRAME_T2*8)(sp)
ldq t3,(FRAME_T3*8)(sp)
ldq t4,(FRAME_T4*8)(sp)
ldq t5,(FRAME_T5*8)(sp)
ldq t6,(FRAME_T6*8)(sp)
ldq t7,(FRAME_T7*8)(sp)
ldq t8,(FRAME_T8*8)(sp)
ldq t9,(FRAME_T9*8)(sp)
ldq t10,(FRAME_T10*8)(sp)
ldq t11,(FRAME_T11*8)(sp)
ldq t12,(FRAME_T12*8)(sp)
RET
END(exception_restore_regs)

View File

@ -133,6 +133,8 @@ ASSYM(FRAME_RA, FRAME_RA);
ASSYM(FRAME_T12, FRAME_T12);
ASSYM(FRAME_AT, FRAME_AT);
ASSYM(FRAME_SP, FRAME_SP);
ASSYM(FRAME_FLAGS, FRAME_FLAGS);
ASSYM(FRAME_FLAGS_SYSCALL, FRAME_FLAGS_SYSCALL);
ASSYM(FRAME_SW_SIZE, FRAME_SW_SIZE);