Thu Sep 3 14:26:31 2020 UTC ()
The conversion of FPU tracking to PCU rendered the fpcurlwp variable
unmaintained, which broke FP status info in the COMPAT_LINUX sigcontext.
Use the new API, which will at least be closer to correct.


(thorpej)
diff -r1.50 -r1.51 src/sys/compat/linux/arch/alpha/linux_machdep.c

cvs diff -r1.50 -r1.51 src/sys/compat/linux/arch/alpha/linux_machdep.c (expand / switch to unified diff)

--- src/sys/compat/linux/arch/alpha/linux_machdep.c 2014/11/09 17:48:07 1.50
+++ src/sys/compat/linux/arch/alpha/linux_machdep.c 2020/09/03 14:26:31 1.51
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: linux_machdep.c,v 1.50 2014/11/09 17:48:07 maxv Exp $ */ 1/* $NetBSD: linux_machdep.c,v 1.51 2020/09/03 14:26:31 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Eric Haszlakiewicz. 8 * by Eric Haszlakiewicz.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 * 30 *
31 * Based on sys/arch/i386/i386/linux_machdep.c: 31 * Based on sys/arch/i386/i386/linux_machdep.c:
32 * linux_machdep.c,v 1.42 1998/09/11 12:50:06 mycroft Exp 32 * linux_machdep.c,v 1.42 1998/09/11 12:50:06 mycroft Exp
33 * written by Frank van der Linden 33 * written by Frank van der Linden
34 * 34 *
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.50 2014/11/09 17:48:07 maxv Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.51 2020/09/03 14:26:31 thorpej Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/signalvar.h> 42#include <sys/signalvar.h>
43#include <sys/kernel.h> 43#include <sys/kernel.h>
44#include <sys/proc.h> 44#include <sys/proc.h>
45#include <sys/buf.h> 45#include <sys/buf.h>
46#include <sys/reboot.h> 46#include <sys/reboot.h>
47#include <sys/conf.h> 47#include <sys/conf.h>
48#include <sys/exec.h> 48#include <sys/exec.h>
49#include <sys/file.h> 49#include <sys/file.h>
50#include <sys/callout.h> 50#include <sys/callout.h>
51#include <sys/mbuf.h> 51#include <sys/mbuf.h>
@@ -233,34 +233,31 @@ void setup_linux_sigframe(struct trapfra @@ -233,34 +233,31 @@ void setup_linux_sigframe(struct trapfra
233#endif /* DEBUG */ 233#endif /* DEBUG */
234 234
235 /* 235 /*
236 * Build the signal context to be used by sigreturn. 236 * Build the signal context to be used by sigreturn.
237 */ 237 */
238 memset(&sigframe.sf_sc, 0, sizeof(struct linux_sigcontext)); 238 memset(&sigframe.sf_sc, 0, sizeof(struct linux_sigcontext));
239 sigframe.sf_sc.sc_onstack = onstack; 239 sigframe.sf_sc.sc_onstack = onstack;
240 native_to_linux_old_sigset(&sigframe.sf_sc.sc_mask, mask); 240 native_to_linux_old_sigset(&sigframe.sf_sc.sc_mask, mask);
241 sigframe.sf_sc.sc_pc = tf->tf_regs[FRAME_PC]; 241 sigframe.sf_sc.sc_pc = tf->tf_regs[FRAME_PC];
242 sigframe.sf_sc.sc_ps = ALPHA_PSL_USERMODE; 242 sigframe.sf_sc.sc_ps = ALPHA_PSL_USERMODE;
243 frametoreg(tf, (struct reg *)sigframe.sf_sc.sc_regs); 243 frametoreg(tf, (struct reg *)sigframe.sf_sc.sc_regs);
244 sigframe.sf_sc.sc_regs[R_SP] = alpha_pal_rdusp(); 244 sigframe.sf_sc.sc_regs[R_SP] = alpha_pal_rdusp();
245 245
246 if (l == fpcurlwp) { 246 if (fpu_valid_p(l)) {
247 struct pcb *pcb = lwp_getpcb(l); 247 struct pcb *pcb = lwp_getpcb(l);
248 248
249 alpha_pal_wrfen(1); 249 fpu_save(l);
250 savefpstate(&pcb->pcb_fp); 
251 alpha_pal_wrfen(0); 
252 sigframe.sf_sc.sc_fpcr = pcb->pcb_fp.fpr_cr; 250 sigframe.sf_sc.sc_fpcr = pcb->pcb_fp.fpr_cr;
253 fpcurlwp = NULL; 
254 } 251 }
255 /* XXX ownedfp ? etc...? */ 252 /* XXX ownedfp ? etc...? */
256 253
257 sigframe.sf_sc.sc_traparg_a0 = tf->tf_regs[FRAME_A0]; 254 sigframe.sf_sc.sc_traparg_a0 = tf->tf_regs[FRAME_A0];
258 sigframe.sf_sc.sc_traparg_a1 = tf->tf_regs[FRAME_A1]; 255 sigframe.sf_sc.sc_traparg_a1 = tf->tf_regs[FRAME_A1];
259 sigframe.sf_sc.sc_traparg_a2 = tf->tf_regs[FRAME_A2]; 256 sigframe.sf_sc.sc_traparg_a2 = tf->tf_regs[FRAME_A2];
260 257
261 sendsig_reset(l, sig); 258 sendsig_reset(l, sig);
262 mutex_exit(p->p_lock); 259 mutex_exit(p->p_lock);
263 error = copyout((void *)&sigframe, (void *)sfp, fsize); 260 error = copyout((void *)&sigframe, (void *)sfp, fsize);
264 mutex_enter(p->p_lock); 261 mutex_enter(p->p_lock);
265 262
266 if (error != 0) { 263 if (error != 0) {
@@ -384,29 +381,26 @@ linux_restore_sigcontext(struct lwp *l,  @@ -384,29 +381,26 @@ linux_restore_sigcontext(struct lwp *l,
384 /* 381 /*
385 * Check for security violations. 382 * Check for security violations.
386 * Linux doesn't allow any changes to the PSL. 383 * Linux doesn't allow any changes to the PSL.
387 */ 384 */
388 if (context.sc_ps != ALPHA_PSL_USERMODE) 385 if (context.sc_ps != ALPHA_PSL_USERMODE)
389 return(EINVAL); 386 return(EINVAL);
390 387
391 l->l_md.md_tf->tf_regs[FRAME_PC] = context.sc_pc; 388 l->l_md.md_tf->tf_regs[FRAME_PC] = context.sc_pc;
392 l->l_md.md_tf->tf_regs[FRAME_PS] = context.sc_ps; 389 l->l_md.md_tf->tf_regs[FRAME_PS] = context.sc_ps;
393 390
394 regtoframe((struct reg *)context.sc_regs, l->l_md.md_tf); 391 regtoframe((struct reg *)context.sc_regs, l->l_md.md_tf);
395 alpha_pal_wrusp(context.sc_regs[R_SP]); 392 alpha_pal_wrusp(context.sc_regs[R_SP]);
396 393
397 if (l == fpcurlwp) 
398 fpcurlwp = NULL; 
399 
400 /* Restore fp regs and fpr_cr */ 394 /* Restore fp regs and fpr_cr */
401 pcb = lwp_getpcb(l); 395 pcb = lwp_getpcb(l);
402 memcpy(&pcb->pcb_fp, (struct fpreg *)context.sc_fpregs, 396 memcpy(&pcb->pcb_fp, (struct fpreg *)context.sc_fpregs,
403 sizeof(struct fpreg)); 397 sizeof(struct fpreg));
404 /* XXX sc_ownedfp ? */ 398 /* XXX sc_ownedfp ? */
405 /* XXX sc_fp_control ? */ 399 /* XXX sc_fp_control ? */
406 400
407#ifdef DEBUG 401#ifdef DEBUG
408 if (sigdebug & SDB_FOLLOW) 402 if (sigdebug & SDB_FOLLOW)
409 printf("linux_rt_sigreturn(%d): returns\n", p->p_pid); 403 printf("linux_rt_sigreturn(%d): returns\n", p->p_pid);
410#endif 404#endif
411 return (EJUSTRETURN); 405 return (EJUSTRETURN);
412} 406}