diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2003-05-18 15:57:48 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2003-05-18 15:57:48 +0000 |
commit | 0104529bd466688238c5b5bc13cc1adcf0a5a682 (patch) | |
tree | f392f92ae34f837ee797809733c172fad912bdc4 /sys/arch | |
parent | 2445b5bb89a257c9aec8e304a44845476b289008 (diff) |
save the fpu state for the signal handler. this is essential
as the fpu regs can be used by the gcc even for non-fpu
means and data copying.
rearrange the sigcontext a bit to include only the general
registers that are needed restoring upon return and thus
less waste of space and make up some space for the fpu regs.
ALL software that used the signal context on the stack
needs at least rebuilding now. a new snap has bin built as well.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 142 | ||||
-rw-r--r-- | sys/arch/hppa/include/signal.h | 8 |
2 files changed, 93 insertions, 57 deletions
diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index 9e01828a49a..d860fc9feec 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.104 2003/05/11 19:41:09 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.105 2003/05/18 15:57:46 mickey Exp $ */ /* * Copyright (c) 1999-2002 Michael Shalayeff @@ -1173,7 +1173,7 @@ setregs(p, pack, stack, retval) #ifdef DEBUG /*extern int pmapdebug;*/ /*pmapdebug = 13; - printf("setregs(%p, %p, %x, %p), ep=%x, cr30=%x\n", + printf("setregs(%p, %p, 0x%x, %p), ep=0x%x, cr30=0x%x\n", p, pack, stack, retval, pack->ep_entry, tf->tf_cr30); */ #endif @@ -1218,6 +1218,7 @@ sendsig(catcher, sig, mask, code, type, val) int type; union sigval val; { + extern paddr_t fpu_curpcb; /* from locore.S */ struct proc *p = curproc; struct trapframe *tf = p->p_md.md_regs; struct sigacts *psp = p->p_sigacts; @@ -1232,6 +1233,12 @@ sendsig(catcher, sig, mask, code, type, val) p->p_comm, p->p_pid, sig, catcher); #endif + /* flush the FPU ctx first */ + if (tf->tf_cr30 == fpu_curpcb) { + fpu_save(fpu_curpcb); + fpu_curpcb = 0; + } + ksc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; /* @@ -1255,12 +1262,44 @@ sendsig(catcher, sig, mask, code, type, val) } ksc.sc_mask = mask; - ksc.sc_sp = tf->tf_sp; ksc.sc_fp = (register_t)scp + sss; ksc.sc_ps = tf->tf_ipsw; ksc.sc_pcoqh = tf->tf_iioq_head; ksc.sc_pcoqt = tf->tf_iioq_tail; - bcopy(tf, &ksc.sc_tf, sizeof(ksc.sc_tf)); + ksc.sc_regs[0] = tf->tf_t1; + ksc.sc_regs[1] = tf->tf_t2; + ksc.sc_regs[2] = tf->tf_sp; + ksc.sc_regs[3] = tf->tf_t3; + ksc.sc_regs[4] = tf->tf_sar; + ksc.sc_regs[5] = tf->tf_r1; + ksc.sc_regs[6] = tf->tf_rp; + ksc.sc_regs[7] = tf->tf_r3; + ksc.sc_regs[8] = tf->tf_r4; + ksc.sc_regs[9] = tf->tf_r5; + ksc.sc_regs[10] = tf->tf_r6; + ksc.sc_regs[11] = tf->tf_r7; + ksc.sc_regs[12] = tf->tf_r8; + ksc.sc_regs[13] = tf->tf_r9; + ksc.sc_regs[14] = tf->tf_r10; + ksc.sc_regs[15] = tf->tf_r11; + ksc.sc_regs[16] = tf->tf_r12; + ksc.sc_regs[17] = tf->tf_r13; + ksc.sc_regs[18] = tf->tf_r14; + ksc.sc_regs[19] = tf->tf_r15; + ksc.sc_regs[20] = tf->tf_r16; + ksc.sc_regs[21] = tf->tf_r17; + ksc.sc_regs[22] = tf->tf_r18; + ksc.sc_regs[23] = tf->tf_t4; + ksc.sc_regs[24] = tf->tf_arg3; + ksc.sc_regs[25] = tf->tf_arg2; + ksc.sc_regs[26] = tf->tf_arg1; + ksc.sc_regs[27] = tf->tf_arg0; + ksc.sc_regs[28] = tf->tf_dp; + ksc.sc_regs[29] = tf->tf_ret0; + ksc.sc_regs[30] = tf->tf_ret1; + ksc.sc_regs[31] = tf->tf_r31; + bcopy(p->p_addr->u_pcb.pcb_fpregs, ksc.sc_fpregs, + sizeof(ksc.sc_fpregs)); if (copyout((caddr_t)&ksc, scp, sizeof(*scp))) sigexit(p, SIGILL); @@ -1274,8 +1313,8 @@ sendsig(catcher, sig, mask, code, type, val) #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) - printf("sendsig(%d): sig %d scp %p fp %p sp %x\n", - p->p_pid, sig, scp, ksc.sc_fp, ksc.sc_sp); + printf("sendsig(%d): sig %d scp %p fp %p sp 0x%x\n", + p->p_pid, sig, scp, ksc.sc_fp, (register_t)scp + sss); #endif tf->tf_arg0 = sig; @@ -1287,11 +1326,9 @@ sendsig(catcher, sig, mask, code, type, val) tf->tf_iioq_tail = tf->tf_iioq_head + 4; /* disable tracing in the trapframe */ - /* TODO FPU */ - #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) - printf("sendsig(%d): pc %x, catcher %x\n", p->p_pid, + printf("sendsig(%d): pc 0x%x, catcher 0x%x\n", p->p_pid, tf->tf_iioq_head, tf->tf_arg3); #endif } @@ -1302,6 +1339,7 @@ sys_sigreturn(p, v, retval) void *v; register_t *retval; { + extern paddr_t fpu_curpcb; /* from locore.S */ struct sys_sigreturn_args /* { syscallarg(struct sigcontext *) sigcntxp; } */ *uap = v; @@ -1315,6 +1353,12 @@ sys_sigreturn(p, v, retval) printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp); #endif + /* flush the FPU ctx first */ + if (tf->tf_cr30 == fpu_curpcb) { + fpu_save(fpu_curpcb); + fpu_curpcb = 0; + } + if ((error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc))) return (error); @@ -1329,15 +1373,47 @@ sys_sigreturn(p, v, retval) p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; p->p_sigmask = ksc.sc_mask &~ sigcantmask; - hppa_user2frame((struct trapframe *)&ksc.sc_tf, tf); + tf->tf_t1 = ksc.sc_regs[0]; /* r22 */ + tf->tf_t2 = ksc.sc_regs[1]; /* r21 */ + tf->tf_sp = ksc.sc_regs[2]; + tf->tf_t3 = ksc.sc_regs[3]; /* r20 */ + tf->tf_sar = ksc.sc_regs[4]; + tf->tf_r1 = ksc.sc_regs[5]; + tf->tf_rp = ksc.sc_regs[6]; + tf->tf_r3 = ksc.sc_regs[7]; + tf->tf_r4 = ksc.sc_regs[8]; + tf->tf_r5 = ksc.sc_regs[9]; + tf->tf_r6 = ksc.sc_regs[10]; + tf->tf_r7 = ksc.sc_regs[11]; + tf->tf_r8 = ksc.sc_regs[12]; + tf->tf_r9 = ksc.sc_regs[13]; + tf->tf_r10 = ksc.sc_regs[14]; + tf->tf_r11 = ksc.sc_regs[15]; + tf->tf_r12 = ksc.sc_regs[16]; + tf->tf_r13 = ksc.sc_regs[17]; + tf->tf_r14 = ksc.sc_regs[18]; + tf->tf_r15 = ksc.sc_regs[19]; + tf->tf_r16 = ksc.sc_regs[20]; + tf->tf_r17 = ksc.sc_regs[21]; + tf->tf_r18 = ksc.sc_regs[22]; + tf->tf_t4 = ksc.sc_regs[23]; /* r19 */ + tf->tf_arg3 = ksc.sc_regs[24]; /* r23 */ + tf->tf_arg2 = ksc.sc_regs[25]; /* r24 */ + tf->tf_arg1 = ksc.sc_regs[26]; /* r25 */ + tf->tf_arg0 = ksc.sc_regs[27]; /* r26 */ + tf->tf_dp = ksc.sc_regs[28]; + tf->tf_ret0 = ksc.sc_regs[29]; + tf->tf_ret1 = ksc.sc_regs[30]; + tf->tf_r31 = ksc.sc_regs[31]; + bcopy(ksc.sc_fpregs, p->p_addr->u_pcb.pcb_fpregs, + sizeof(ksc.sc_fpregs)); + fdcache(HPPA_SID_KERNEL, (vaddr_t)p->p_addr->u_pcb.pcb_fpregs, + sizeof(ksc.sc_fpregs)); - tf->tf_sp = ksc.sc_sp; tf->tf_iioq_head = ksc.sc_pcoqh | HPPA_PC_PRIV_USER; tf->tf_iioq_tail = ksc.sc_pcoqt | HPPA_PC_PRIV_USER; tf->tf_ipsw = ksc.sc_ps; - /* TODO FPU */ - #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) printf("sigreturn(%d): returns\n", p->p_pid); @@ -1345,46 +1421,6 @@ sys_sigreturn(p, v, retval) return (EJUSTRETURN); } -void -hppa_user2frame(sf, tf) - struct trapframe *sf, *tf; -{ - /* only restore r1-r31, sar */ - tf->tf_t1 = sf->tf_t1; /* r22 */ - tf->tf_t2 = sf->tf_t2; /* r21 */ - tf->tf_sp = sf->tf_sp; - tf->tf_t3 = sf->tf_t3; /* r20 */ - - tf->tf_sar = sf->tf_sar; - tf->tf_r1 = sf->tf_r1; - tf->tf_rp = sf->tf_rp; - tf->tf_r3 = sf->tf_r3; - tf->tf_r4 = sf->tf_r4; - tf->tf_r5 = sf->tf_r5; - tf->tf_r6 = sf->tf_r6; - tf->tf_r7 = sf->tf_r7; - tf->tf_r8 = sf->tf_r8; - tf->tf_r9 = sf->tf_r9; - tf->tf_r10 = sf->tf_r10; - tf->tf_r11 = sf->tf_r11; - tf->tf_r12 = sf->tf_r12; - tf->tf_r13 = sf->tf_r13; - tf->tf_r14 = sf->tf_r14; - tf->tf_r15 = sf->tf_r15; - tf->tf_r16 = sf->tf_r16; - tf->tf_r17 = sf->tf_r17; - tf->tf_r18 = sf->tf_r18; - tf->tf_t4 = sf->tf_t4; /* r19 */ - tf->tf_arg3 = sf->tf_arg3; /* r23 */ - tf->tf_arg2 = sf->tf_arg2; /* r24 */ - tf->tf_arg1 = sf->tf_arg1; /* r25 */ - tf->tf_arg0 = sf->tf_arg0; /* r26 */ - tf->tf_dp = sf->tf_dp; - tf->tf_ret0 = sf->tf_ret0; - tf->tf_ret1 = sf->tf_ret1; - tf->tf_r31 = sf->tf_r31; -} - /* * machine dependent system variables. */ diff --git a/sys/arch/hppa/include/signal.h b/sys/arch/hppa/include/signal.h index 875a6b7b3b2..fb6635c9dd2 100644 --- a/sys/arch/hppa/include/signal.h +++ b/sys/arch/hppa/include/signal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signal.h,v 1.2 2002/02/06 19:39:20 mickey Exp $ */ +/* $OpenBSD: signal.h,v 1.3 2003/05/18 15:57:47 mickey Exp $ */ /* * Copyright (c) 1994, The University of Utah and @@ -44,10 +44,10 @@ struct sigcontext { int sc_onstack; /* sigstack state to restore */ int sc_mask; /* signal mask to restore */ int sc_ps; /* psl to restore */ - int sc_sp; /* sp to restore */ int sc_fp; /* fp to restore */ int sc_pcoqh; /* pc offset queue (head) to restore */ int sc_pcoqt; /* pc offset queue (tail) to restore */ - int sc_resv[5]; - int sc_tf[64]; + int sc_resv[2]; + int sc_regs[32]; + int sc_fpregs[64]; }; |