diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-07-05 11:29:22 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-07-05 11:29:22 +0000 |
commit | dd20fbc75da7e37108120a7081fd24bb9241d9a0 (patch) | |
tree | a0e53f01f96fcf631d0a9cd902e1241e01610453 | |
parent | 58db0d0707cdad9d85f3ed6c40f7cb071445daa4 (diff) |
Save FPU state to PCB before running a signal handler. This doesn't
completely fix the case where the FPU is used in a signal handler
but it is part of the solution and makes sure the processor mode check
in sys_sigreturn() passes if the process was using the FPU when the signal
happened.
-rw-r--r-- | sys/arch/powerpc64/powerpc64/machdep.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/arch/powerpc64/powerpc64/machdep.c b/sys/arch/powerpc64/powerpc64/machdep.c index bad24026422..c131fda5324 100644 --- a/sys/arch/powerpc64/powerpc64/machdep.c +++ b/sys/arch/powerpc64/powerpc64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.42 2020/07/05 10:34:08 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.43 2020/07/05 11:29:21 kettenis Exp $ */ /* * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> @@ -671,6 +671,7 @@ void sendsig(sig_t catcher, int sig, sigset_t mask, const siginfo_t *ksip) { struct proc *p = curproc; + struct pcb *pcb = &p->p_addr->u_pcb; struct trapframe *tf = p->p_md.md_regs; struct sigframe *fp, frame; struct sigacts *psp = p->p_p->ps_sigacts; @@ -687,6 +688,13 @@ sendsig(sig_t catcher, int sig, sigset_t mask, const siginfo_t *ksip) fp = (struct sigframe *)(STACKALIGN(fp - 1) - 288); + /* Save FPU state to PCB if necessary. */ + if (pcb->pcb_flags & (PCB_FP|PCB_VEC|PCB_VSX) && + tf->srr1 & (PSL_FP|PSL_VEC|PSL_VSX)) { + tf->srr1 &= ~(PSL_FP|PSL_VEC|PSL_VSX); + save_vsx(p); + } + /* Build stack frame for signal trampoline. */ memset(&frame, 0, sizeof(frame)); frame.sf_signum = sig; |