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:
parent
8ab109d131
commit
c586bc8e57
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=71881
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user