Module Name:    src
Committed By:   chs
Date:           Thu Mar 16 16:13:21 UTC 2017

Modified Files:
        src/share/man/man9: pcu.9
        src/sys/arch/aarch64/include: locore.h
        src/sys/arch/alpha/alpha: compat_13_machdep.c compat_16_machdep.c
            machdep.c process_machdep.c trap.c
        src/sys/arch/alpha/include: alpha.h
        src/sys/arch/arm/arm: arm_machdep.c process_machdep.c
        src/sys/arch/arm/arm32: sys_machdep.c
        src/sys/arch/arm/include: locore.h
        src/sys/arch/arm/vfp: vfp_init.c
        src/sys/arch/mips/include: locore.h
        src/sys/arch/mips/mips: compat_16_machdep.c cpu_subr.c mips_dsp.c
            mips_fpu.c netbsd32_machdep.c process_machdep.c
        src/sys/arch/powerpc/booke: spe.c
        src/sys/arch/powerpc/include: altivec.h fpu.h
        src/sys/arch/powerpc/oea: altivec.c
        src/sys/arch/powerpc/powerpc: fpu.c process_machdep.c trap.c
        src/sys/arch/riscv/include: locore.h
        src/sys/arch/riscv/riscv: netbsd32_machdep.c process_machdep.c
            riscv_machdep.c
        src/sys/compat/linux/arch/powerpc: linux_machdep.c
        src/sys/kern: subr_pcu.c
        src/sys/sys: pcu.h

Log Message:
allow pcu_save() and pcu_discard() to be called on other threads,
ptrace needs to use it that way.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/share/man/man9/pcu.9
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/aarch64/include/locore.h
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/alpha/alpha/compat_13_machdep.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/alpha/alpha/compat_16_machdep.c
cvs rdiff -u -r1.349 -r1.350 src/sys/arch/alpha/alpha/machdep.c
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/alpha/alpha/process_machdep.c
cvs rdiff -u -r1.132 -r1.133 src/sys/arch/alpha/alpha/trap.c
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/alpha/include/alpha.h
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/arm/arm/arm_machdep.c
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/arm/arm/process_machdep.c
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/arm/arm32/sys_machdep.c
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/arm/include/locore.h
cvs rdiff -u -r1.50 -r1.51 src/sys/arch/arm/vfp/vfp_init.c
cvs rdiff -u -r1.101 -r1.102 src/sys/arch/mips/include/locore.h
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/mips/mips/compat_16_machdep.c
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/mips/mips/mips_dsp.c
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/mips/mips/mips_fpu.c \
    src/sys/arch/mips/mips/netbsd32_machdep.c
cvs rdiff -u -r1.37 -r1.38 src/sys/arch/mips/mips/process_machdep.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/powerpc/booke/spe.c
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/powerpc/include/altivec.h
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/powerpc/include/fpu.h
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/powerpc/oea/altivec.c
cvs rdiff -u -r1.37 -r1.38 src/sys/arch/powerpc/powerpc/fpu.c \
    src/sys/arch/powerpc/powerpc/process_machdep.c
cvs rdiff -u -r1.152 -r1.153 src/sys/arch/powerpc/powerpc/trap.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/riscv/include/locore.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/riscv/riscv/netbsd32_machdep.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/riscv/riscv/process_machdep.c \
    src/sys/arch/riscv/riscv/riscv_machdep.c
cvs rdiff -u -r1.48 -r1.49 src/sys/compat/linux/arch/powerpc/linux_machdep.c
cvs rdiff -u -r1.19 -r1.20 src/sys/kern/subr_pcu.c
cvs rdiff -u -r1.12 -r1.13 src/sys/sys/pcu.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man9/pcu.9
diff -u src/share/man/man9/pcu.9:1.10 src/share/man/man9/pcu.9:1.11
--- src/share/man/man9/pcu.9:1.10	Sun May 25 14:56:23 2014
+++ src/share/man/man9/pcu.9	Thu Mar 16 16:13:19 2017
@@ -1,4 +1,4 @@
-.\"	$NetBSD: pcu.9,v 1.10 2014/05/25 14:56:23 rmind Exp $
+.\"	$NetBSD: pcu.9,v 1.11 2017/03/16 16:13:19 chs Exp $
 .\"
 .\" Copyright (c) 2012-2014 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -38,11 +38,11 @@
 .Ft void
 .Fn pcu_load "const pcu_ops_t *pcu"
 .Ft void
-.Fn pcu_save "const pcu_ops_t *pcu"
+.Fn pcu_save "const pcu_ops_t *pcu" "lwp_t *l"
 .Ft void
 .Fn pcu_save_all "lwp_t *l"
 .Ft void
-.Fn pcu_discard "const pcu_ops_t *pcu" "bool valid"
+.Fn pcu_discard "const pcu_ops_t *pcu" "lwp_t *l" "bool valid"
 .Ft void
 .Fn pcu_discard_all "lwp_t *l"
 .Ft bool

Index: src/sys/arch/aarch64/include/locore.h
diff -u src/sys/arch/aarch64/include/locore.h:1.1 src/sys/arch/aarch64/include/locore.h:1.2
--- src/sys/arch/aarch64/include/locore.h:1.1	Sun Aug 10 05:47:38 2014
+++ src/sys/arch/aarch64/include/locore.h	Thu Mar 16 16:13:19 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.h,v 1.1 2014/08/10 05:47:38 matt Exp $ */
+/* $NetBSD: locore.h,v 1.2 2017/03/16 16:13:19 chs Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -69,22 +69,19 @@ extern const pcu_ops_t pcu_fpu_ops;
 static inline bool
 fpu_used_p(lwp_t *l)
 {
-	KASSERT(l == curlwp);
-	return pcu_valid_p(&pcu_fpu_ops);
+	return pcu_valid_p(&pcu_fpu_ops, l);
 }
 
 static inline void
 fpu_discard(lwp_t *l, bool usesw)
 {
-	KASSERT(l == curlwp);
-	pcu_discard(&pcu_fpu_ops, usesw);
+	pcu_discard(&pcu_fpu_ops, l, usesw);
 }
 
 static inline void
 fpu_save(lwp_t *l)
 {
-	KASSERT(l == curlwp);
-	pcu_save(&pcu_fpu_ops);
+	pcu_save(&pcu_fpu_ops, l);
 }
 
 static inline void cpsie(register_t psw) __attribute__((__unused__));

Index: src/sys/arch/alpha/alpha/compat_13_machdep.c
diff -u src/sys/arch/alpha/alpha/compat_13_machdep.c:1.21 src/sys/arch/alpha/alpha/compat_13_machdep.c:1.22
--- src/sys/arch/alpha/alpha/compat_13_machdep.c:1.21	Fri May 16 19:18:21 2014
+++ src/sys/arch/alpha/alpha/compat_13_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: compat_13_machdep.c,v 1.21 2014/05/16 19:18:21 matt Exp $ */
+/* $NetBSD: compat_13_machdep.c,v 1.22 2017/03/16 16:13:20 chs Exp $ */
 
 /*
  * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.21 2014/05/16 19:18:21 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.22 2017/03/16 16:13:20 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -94,7 +94,7 @@ compat_13_sys_sigreturn(struct lwp *l, c
 
 	/* XXX ksc.sc_ownedfp ? */
 	pcb = lwp_getpcb(l);
-	fpu_discard(true);
+	fpu_discard(l, true);
 	memcpy(&pcb->pcb_fp, (struct fpreg *)ksc.sc_fpregs,
 	    sizeof(struct fpreg));
 	/* XXX ksc.sc_fp_control ? */

Index: src/sys/arch/alpha/alpha/compat_16_machdep.c
diff -u src/sys/arch/alpha/alpha/compat_16_machdep.c:1.20 src/sys/arch/alpha/alpha/compat_16_machdep.c:1.21
--- src/sys/arch/alpha/alpha/compat_16_machdep.c:1.20	Sat Mar 19 20:57:48 2016
+++ src/sys/arch/alpha/alpha/compat_16_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: compat_16_machdep.c,v 1.20 2016/03/19 20:57:48 mrg Exp $ */
+/* $NetBSD: compat_16_machdep.c,v 1.21 2017/03/16 16:13:20 chs Exp $ */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -86,7 +86,7 @@
 #include <machine/cpu.h>
 #include <machine/reg.h>
 
-__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.20 2016/03/19 20:57:48 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.21 2017/03/16 16:13:20 chs Exp $");
 
 
 #ifdef DEBUG
@@ -132,7 +132,7 @@ sendsig_sigcontext(const ksiginfo_t *ksi
 	frame.sf_sc.sc_regs[R_SP] = alpha_pal_rdusp();
 
  	/* save the floating-point state, if necessary, then copy it. */
-	fpu_save();
+	fpu_save(l);
 	frame.sf_sc.sc_ownedfp = fpu_valid_p(l);
 	memcpy((struct fpreg *)frame.sf_sc.sc_fpregs, &pcb->pcb_fp,
 	    sizeof(struct fpreg));
@@ -281,7 +281,7 @@ compat_16_sys___sigreturn14(struct lwp *
 	alpha_pal_wrusp(ksc.sc_regs[R_SP]);
 
 	pcb = lwp_getpcb(l);
-	fpu_discard(true);
+	fpu_discard(l, true);
 	memcpy(&pcb->pcb_fp, (struct fpreg *)ksc.sc_fpregs,
 	    sizeof(struct fpreg));
 	pcb->pcb_fp.fpr_cr = ksc.sc_fpcr;

Index: src/sys/arch/alpha/alpha/machdep.c
diff -u src/sys/arch/alpha/alpha/machdep.c:1.349 src/sys/arch/alpha/alpha/machdep.c:1.350
--- src/sys/arch/alpha/alpha/machdep.c:1.349	Fri Dec 23 07:15:27 2016
+++ src/sys/arch/alpha/alpha/machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.349 2016/12/23 07:15:27 cherry Exp $ */
+/* $NetBSD: machdep.c,v 1.350 2017/03/16 16:13:20 chs Exp $ */
 
 /*-
  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.349 2016/12/23 07:15:27 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.350 2017/03/16 16:13:20 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1796,7 +1796,7 @@ cpu_getmcontext(struct lwp *l, mcontext_
 
 	/* Save floating point register context, if any, and copy it. */
 	if (fpu_valid_p(l)) {
-		fpu_save();
+		fpu_save(l);
 		(void)memcpy(&mcp->__fpregs, &pcb->pcb_fp,
 		    sizeof (mcp->__fpregs));
 		mcp->__fpregs.__fp_fpcr = alpha_read_fp_c(l);
@@ -1844,7 +1844,7 @@ cpu_setmcontext(struct lwp *l, const mco
 	/* Restore floating point register context, if any. */
 	if (flags & _UC_FPU) {
 		/* If we have an FP register context, get rid of it. */
-		fpu_discard(true);
+		fpu_discard(l, true);
 		(void)memcpy(&pcb->pcb_fp, &mcp->__fpregs,
 		    sizeof (pcb->pcb_fp));
 		l->l_md.md_flags = mcp->__fpregs.__fp_fpcr & MDLWP_FP_C;

Index: src/sys/arch/alpha/alpha/process_machdep.c
diff -u src/sys/arch/alpha/alpha/process_machdep.c:1.29 src/sys/arch/alpha/alpha/process_machdep.c:1.30
--- src/sys/arch/alpha/alpha/process_machdep.c:1.29	Fri May 16 19:18:21 2014
+++ src/sys/arch/alpha/alpha/process_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: process_machdep.c,v 1.29 2014/05/16 19:18:21 matt Exp $ */
+/* $NetBSD: process_machdep.c,v 1.30 2017/03/16 16:13:20 chs Exp $ */
 
 /*
  * Copyright (c) 1994 Christopher G. Demetriou
@@ -54,7 +54,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.29 2014/05/16 19:18:21 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.30 2017/03/16 16:13:20 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -116,7 +116,7 @@ process_read_fpregs(struct lwp *l, struc
 {
 	struct pcb *pcb = lwp_getpcb(l);
 
-	fpu_save();
+	fpu_save(l);
 
 	memcpy(regs, &pcb->pcb_fp, sizeof(struct fpreg));
 	return (0);
@@ -127,7 +127,7 @@ process_write_fpregs(struct lwp *l, cons
 {
 	struct pcb *pcb = lwp_getpcb(l);
 
-	fpu_discard(true);
+	fpu_discard(l, true);
 
 	memcpy(&pcb->pcb_fp, regs, sizeof(struct fpreg));
 	return (0);

Index: src/sys/arch/alpha/alpha/trap.c
diff -u src/sys/arch/alpha/alpha/trap.c:1.132 src/sys/arch/alpha/alpha/trap.c:1.133
--- src/sys/arch/alpha/alpha/trap.c:1.132	Mon Mar  2 11:07:16 2015
+++ src/sys/arch/alpha/alpha/trap.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.132 2015/03/02 11:07:16 martin Exp $ */
+/* $NetBSD: trap.c,v 1.133 2017/03/16 16:13:20 chs Exp $ */
 
 /*-
  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@@ -93,7 +93,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.132 2015/03/02 11:07:16 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.133 2017/03/16 16:13:20 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -641,13 +641,13 @@ static const int reg_to_framereg[32] = {
 
 #define	unaligned_load_floating(storage, mod) do {			\
 	struct pcb * const pcb = lwp_getpcb(l);				\
-	fpu_save();							\
+	fpu_save(l);							\
 	unaligned_load(storage, frp, mod)				\
 } while (/*CONSTCOND*/0)
 
 #define	unaligned_store_floating(storage, mod) do {			\
 	struct pcb * const pcb = lwp_getpcb(l);				\
-	fpu_save();							\
+	fpu_save(l);							\
 	unaligned_store(storage, frp, mod)				\
 } while (/*CONSTCOND*/0)
 

Index: src/sys/arch/alpha/include/alpha.h
diff -u src/sys/arch/alpha/include/alpha.h:1.34 src/sys/arch/alpha/include/alpha.h:1.35
--- src/sys/arch/alpha/include/alpha.h:1.34	Fri May 16 19:18:21 2014
+++ src/sys/arch/alpha/include/alpha.h	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: alpha.h,v 1.34 2014/05/16 19:18:21 matt Exp $ */
+/* $NetBSD: alpha.h,v 1.35 2017/03/16 16:13:20 chs Exp $ */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -116,8 +116,7 @@ void    fpu_state_release(struct lwp *);
 static inline bool
 fpu_valid_p(struct lwp *l)
 {
-	KASSERT(l == curlwp);
-	return pcu_valid_p(&fpu_ops);
+	return pcu_valid_p(&fpu_ops, l);
 }
 
 static inline void
@@ -127,15 +126,15 @@ fpu_load(void)
 }
 
 static inline void
-fpu_save(void)
+fpu_save(lwp_t *l)
 {
-	pcu_save(&fpu_ops);
+	pcu_save(&fpu_ops, l);
 }
 
 static inline void
-fpu_discard(bool valid_p)
+fpu_discard(lwp_t *l, bool valid_p)
 {
-	pcu_discard(&fpu_ops, valid_p);
+	pcu_discard(&fpu_ops, l, valid_p);
 }
 
 void	alpha_patch(bool);

Index: src/sys/arch/arm/arm/arm_machdep.c
diff -u src/sys/arch/arm/arm/arm_machdep.c:1.49 src/sys/arch/arm/arm/arm_machdep.c:1.50
--- src/sys/arch/arm/arm/arm_machdep.c:1.49	Sat May  2 16:20:41 2015
+++ src/sys/arch/arm/arm/arm_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm_machdep.c,v 1.49 2015/05/02 16:20:41 skrll Exp $	*/
+/*	$NetBSD: arm_machdep.c,v 1.50 2017/03/16 16:13:20 chs Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.49 2015/05/02 16:20:41 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm_machdep.c,v 1.50 2017/03/16 16:13:20 chs Exp $");
 
 #include <sys/exec.h>
 #include <sys/proc.h>
@@ -201,7 +201,7 @@ setregs(struct lwp *l, struct exec_packa
 		l->l_md.md_flags |= MDLWP_NOALIGNFLT;
 #endif
 #ifdef FPU_VFP
-	vfp_discardcontext(false);
+	vfp_discardcontext(l, false);
 #endif
 }
 

Index: src/sys/arch/arm/arm/process_machdep.c
diff -u src/sys/arch/arm/arm/process_machdep.c:1.31 src/sys/arch/arm/arm/process_machdep.c:1.32
--- src/sys/arch/arm/arm/process_machdep.c:1.31	Tue Feb 21 07:40:28 2017
+++ src/sys/arch/arm/arm/process_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: process_machdep.c,v 1.31 2017/02/21 07:40:28 skrll Exp $	*/
+/*	$NetBSD: process_machdep.c,v 1.32 2017/03/16 16:13:20 chs Exp $	*/
 
 /*
  * Copyright (c) 1993 The Regents of the University of California.
@@ -133,7 +133,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.31 2017/02/21 07:40:28 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.32 2017/03/16 16:13:20 chs Exp $");
 
 #include <sys/proc.h>
 #include <sys/ptrace.h>
@@ -177,7 +177,7 @@ process_read_fpregs(struct lwp *l, struc
 		return 0;
 	}
 	const struct pcb * const pcb = lwp_getpcb(l);
-	vfp_savecontext();
+	vfp_savecontext(l);
 	regs->fpr_vfp = pcb->pcb_vfp;
 	regs->fpr_vfp.vfp_fpexc &= ~VFP_FPEXC_EN;
 #endif
@@ -220,7 +220,7 @@ process_write_fpregs(struct lwp *l, cons
 		return EINVAL;
 	}
 	struct pcb * const pcb = lwp_getpcb(l);
-	vfp_discardcontext(true);
+	vfp_discardcontext(l, true);
 	pcb->pcb_vfp = regs->fpr_vfp;
 	pcb->pcb_vfp.vfp_fpexc &= ~VFP_FPEXC_EN;
 #endif

Index: src/sys/arch/arm/arm32/sys_machdep.c
diff -u src/sys/arch/arm/arm32/sys_machdep.c:1.22 src/sys/arch/arm/arm32/sys_machdep.c:1.23
--- src/sys/arch/arm/arm32/sys_machdep.c:1.22	Thu Jul  2 08:33:31 2015
+++ src/sys/arch/arm/arm32/sys_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_machdep.c,v 1.22 2015/07/02 08:33:31 skrll Exp $	*/
+/*	$NetBSD: sys_machdep.c,v 1.23 2017/03/16 16:13:20 chs Exp $	*/
 
 /*
  * Copyright (c) 1995-1997 Mark Brinicombe.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.22 2015/07/02 08:33:31 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.23 2017/03/16 16:13:20 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -101,7 +101,7 @@ arm32_vfp_fpscr(struct lwp *l, const voi
 	 * Save the current VFP state (to make sure the FPSCR copy is
 	 * up to date).
 	 */
-	vfp_savecontext();
+	vfp_savecontext(l);
 #endif
 
 	retval[0] = pcb->pcb_vfp.vfp_fpscr;
@@ -125,7 +125,7 @@ arm32_fpu_used(struct lwp *l, const void
 {
 	/* No args */
 #ifdef FPU_VFP
-	retval[0] = vfp_used_p();
+	retval[0] = vfp_used_p(l);
 #else
 	retval[0] = false;
 #endif

Index: src/sys/arch/arm/include/locore.h
diff -u src/sys/arch/arm/include/locore.h:1.26 src/sys/arch/arm/include/locore.h:1.27
--- src/sys/arch/arm/include/locore.h:1.26	Tue Jun  9 08:13:17 2015
+++ src/sys/arch/arm/include/locore.h	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.h,v 1.26 2015/06/09 08:13:17 skrll Exp $	*/
+/*	$NetBSD: locore.h,v 1.27 2017/03/16 16:13:20 chs Exp $	*/
 
 /*
  * Copyright (c) 1994-1996 Mark Brinicombe.
@@ -310,11 +310,11 @@ void	ucas_ras_check(trapframe_t *);
 
 /* vfp_init.c */
 void	vfp_attach(struct cpu_info *);
-void	vfp_discardcontext(bool);
-void	vfp_savecontext(void);
+void	vfp_discardcontext(lwp_t *, bool);
+void	vfp_savecontext(lwp_t *);
 void	vfp_kernel_acquire(void);
 void	vfp_kernel_release(void);
-bool	vfp_used_p(void);
+bool	vfp_used_p(const lwp_t *);
 extern const pcu_ops_t arm_vfp_ops;
 
 #endif	/* !_LOCORE */

Index: src/sys/arch/arm/vfp/vfp_init.c
diff -u src/sys/arch/arm/vfp/vfp_init.c:1.50 src/sys/arch/arm/vfp/vfp_init.c:1.51
--- src/sys/arch/arm/vfp/vfp_init.c:1.50	Thu Mar  3 17:01:31 2016
+++ src/sys/arch/arm/vfp/vfp_init.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*      $NetBSD: vfp_init.c,v 1.50 2016/03/03 17:01:31 skrll Exp $ */
+/*      $NetBSD: vfp_init.c,v 1.51 2017/03/16 16:13:20 chs Exp $ */
 
 /*
  * Copyright (c) 2008 ARM Ltd
@@ -196,7 +196,7 @@ vfp_fpscr_handler(u_int address, u_int i
 	if (pcb->pcb_vfp.vfp_fpexc & VFP_FPEXC_EN)
 		return 1;
 
-	if (__predict_false(!vfp_used_p())) {
+	if (__predict_false(!vfp_used_p(l))) {
 		pcb->pcb_vfp.vfp_fpscr = vfp_fpscr_default;
 	}
 #endif
@@ -434,7 +434,7 @@ vfp_handler(u_int address, u_int insn, t
 		 */
 		armreg_fpexc_write(fpexc & ~(VFP_FPEXC_EX|VFP_FPEXC_FSUM));
 
-		pcu_save(&arm_vfp_ops);
+		pcu_save(&arm_vfp_ops, curlwp);
 
 		/*
 		 * XXX Need to emulate bounce instructions here to get correct
@@ -603,29 +603,30 @@ vfp_state_release(lwp_t *l)
 }
 
 void
-vfp_savecontext(void)
+vfp_savecontext(lwp_t *l)
 {
-	pcu_save(&arm_vfp_ops);
+	pcu_save(&arm_vfp_ops, l);
 }
 
 void
-vfp_discardcontext(bool used_p)
+vfp_discardcontext(lwp_t *l, bool used_p)
 {
-	pcu_discard(&arm_vfp_ops, used_p);
+	pcu_discard(&arm_vfp_ops, l, used_p);
 }
 
 bool
-vfp_used_p(void)
+vfp_used_p(const lwp_t *l)
 {
-	return pcu_valid_p(&arm_vfp_ops);
+	return pcu_valid_p(&arm_vfp_ops, l);
 }
 
 void
 vfp_getcontext(struct lwp *l, mcontext_t *mcp, int *flagsp)
 {
-	if (vfp_used_p()) {
+	if (vfp_used_p(l)) {
 		const struct pcb * const pcb = lwp_getpcb(l);
-		pcu_save(&arm_vfp_ops);
+
+		pcu_save(&arm_vfp_ops, l);
 		mcp->__fpu.__vfpregs.__vfp_fpscr = pcb->pcb_vfp.vfp_fpscr;
 		memcpy(mcp->__fpu.__vfpregs.__vfp_fstmx, pcb->pcb_vfp.vfp_regs,
 		    sizeof(mcp->__fpu.__vfpregs.__vfp_fstmx));
@@ -636,8 +637,9 @@ vfp_getcontext(struct lwp *l, mcontext_t
 void
 vfp_setcontext(struct lwp *l, const mcontext_t *mcp)
 {
-	pcu_discard(&arm_vfp_ops, true);
 	struct pcb * const pcb = lwp_getpcb(l);
+
+	pcu_discard(&arm_vfp_ops, l, true);
 	pcb->pcb_vfp.vfp_fpscr = mcp->__fpu.__vfpregs.__vfp_fpscr;
 	memcpy(pcb->pcb_vfp.vfp_regs, mcp->__fpu.__vfpregs.__vfp_fstmx,
 	    sizeof(mcp->__fpu.__vfpregs.__vfp_fstmx));

Index: src/sys/arch/mips/include/locore.h
diff -u src/sys/arch/mips/include/locore.h:1.101 src/sys/arch/mips/include/locore.h:1.102
--- src/sys/arch/mips/include/locore.h:1.101	Thu Oct 13 18:52:30 2016
+++ src/sys/arch/mips/include/locore.h	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.h,v 1.101 2016/10/13 18:52:30 macallan Exp $ */
+/* $NetBSD: locore.h,v 1.102 2017/03/16 16:13:20 chs Exp $ */
 
 /*
  * This file should not be included by MI code!!!
@@ -727,18 +727,18 @@ int	kdbpeek(vaddr_t);
 
 /* mips_dsp.c */
 void	dsp_init(void);
-void	dsp_discard(void);
+void	dsp_discard(lwp_t *);
 void	dsp_load(void);
-void	dsp_save(void);
-bool	dsp_used_p(void);
+void	dsp_save(lwp_t *);
+bool	dsp_used_p(const lwp_t *);
 extern const pcu_ops_t mips_dsp_ops;
 
 /* mips_fpu.c */
 void	fpu_init(void);
-void	fpu_discard(void);
+void	fpu_discard(lwp_t *);
 void	fpu_load(void);
-void	fpu_save(void);
-bool	fpu_used_p(void);
+void	fpu_save(lwp_t *);
+bool	fpu_used_p(const lwp_t *);
 extern const pcu_ops_t mips_fpu_ops;
 
 /* mips_machdep.c */

Index: src/sys/arch/mips/mips/compat_16_machdep.c
diff -u src/sys/arch/mips/mips/compat_16_machdep.c:1.21 src/sys/arch/mips/mips/compat_16_machdep.c:1.22
--- src/sys/arch/mips/mips/compat_16_machdep.c:1.21	Fri Dec  6 13:52:05 2013
+++ src/sys/arch/mips/mips/compat_16_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat_16_machdep.c,v 1.21 2013/12/06 13:52:05 mrg Exp $	*/
+/*	$NetBSD: compat_16_machdep.c,v 1.22 2017/03/16 16:13:20 chs Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -45,7 +45,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 	
-__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.21 2013/12/06 13:52:05 mrg Exp $"); 
+__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.22 2017/03/16 16:13:20 chs Exp $"); 
 
 #ifdef _KERNEL_OPT
 #include "opt_cputype.h"
@@ -131,11 +131,11 @@ sendsig_sigcontext(const ksiginfo_t *ksi
 #endif
 
 	/* Save the FP state, if necessary, then copy it. */
-	ksc.sc_fpused = fpu_used_p();
+	ksc.sc_fpused = fpu_used_p(l);
 #if !defined(NOFPU)
 	if (ksc.sc_fpused) {
 		/* if FPU has current state, save it first */
-		fpu_save();
+		fpu_save(l);
 	}
 #endif
 	*(struct fpreg *)ksc.sc_fpregs = *(struct fpreg *)&pcb->pcb_fpregs;
@@ -275,7 +275,7 @@ compat_16_sys___sigreturn14(struct lwp *
 #endif
 #if !defined(NOFPU)
 	if (scp->sc_fpused) {
-		fpu_discard();
+		fpu_discard(l);
 	}
 #endif
 	*(struct fpreg *)&pcb->pcb_fpregs = *(struct fpreg *)scp->sc_fpregs;

Index: src/sys/arch/mips/mips/cpu_subr.c
diff -u src/sys/arch/mips/mips/cpu_subr.c:1.30 src/sys/arch/mips/mips/cpu_subr.c:1.31
--- src/sys/arch/mips/mips/cpu_subr.c:1.30	Mon Oct 31 12:49:04 2016
+++ src/sys/arch/mips/mips/cpu_subr.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu_subr.c,v 1.30 2016/10/31 12:49:04 skrll Exp $	*/
+/*	$NetBSD: cpu_subr.c,v 1.31 2017/03/16 16:13:20 chs Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.30 2016/10/31 12:49:04 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.31 2017/03/16 16:13:20 chs Exp $");
 
 #include "opt_ddb.h"
 #include "opt_cputype.h"
@@ -371,13 +371,13 @@ cpu_getmcontext(struct lwp *l, mcontext_
 
 	/* Save floating point register context, if any. */
 	KASSERT(l == curlwp);
-	if (fpu_used_p()) {
+	if (fpu_used_p(l)) {
 		size_t fplen;
 		/*
 		 * If this process is the current FP owner, dump its
 		 * context to the PCB first.
 		 */
-		fpu_save();
+		fpu_save(l);
 
 		/*
 		 * The PCB FP regs struct includes the FP CSR, so use the
@@ -451,7 +451,7 @@ cpu_setmcontext(struct lwp *l, const mco
 		size_t fplen;
 
 		/* Disable the FPU contents. */
-		fpu_discard();
+		fpu_discard(l);
 
 #if !defined(__mips_o32)
 		if (_MIPS_SIM_NEWABI_P(l->l_proc->p_md.md_abi)) {

Index: src/sys/arch/mips/mips/mips_dsp.c
diff -u src/sys/arch/mips/mips/mips_dsp.c:1.4 src/sys/arch/mips/mips/mips_dsp.c:1.5
--- src/sys/arch/mips/mips/mips_dsp.c:1.4	Fri May 16 00:48:41 2014
+++ src/sys/arch/mips/mips/mips_dsp.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_dsp.c,v 1.4 2014/05/16 00:48:41 rmind Exp $	*/
+/*	$NetBSD: mips_dsp.c,v 1.5 2017/03/16 16:13:20 chs Exp $	*/
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_dsp.c,v 1.4 2014/05/16 00:48:41 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_dsp.c,v 1.5 2017/03/16 16:13:20 chs Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -58,9 +58,9 @@ const pcu_ops_t mips_dsp_ops = {
 };
 
 void
-dsp_discard(void)
+dsp_discard(lwp_t *l)
 {
-	pcu_discard(&mips_dsp_ops, false);
+	pcu_discard(&mips_dsp_ops, l, false);
 }
 
 void
@@ -70,15 +70,15 @@ dsp_load(void)
 }
 
 void
-dsp_save(void)
+dsp_save(lwp_t *l)
 {
-	pcu_save(&mips_dsp_ops);
+	pcu_save(&mips_dsp_ops, l);
 }
 
 bool
-dsp_used_p(void)
+dsp_used_p(const lwp_t *l)
 {
-	return pcu_valid_p(&mips_dsp_ops);
+	return pcu_valid_p(&mips_dsp_ops, l);
 }
 
 void

Index: src/sys/arch/mips/mips/mips_fpu.c
diff -u src/sys/arch/mips/mips/mips_fpu.c:1.13 src/sys/arch/mips/mips/mips_fpu.c:1.14
--- src/sys/arch/mips/mips/mips_fpu.c:1.13	Sat Mar 26 17:40:02 2016
+++ src/sys/arch/mips/mips/mips_fpu.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_fpu.c,v 1.13 2016/03/26 17:40:02 martin Exp $	*/
+/*	$NetBSD: mips_fpu.c,v 1.14 2017/03/16 16:13:20 chs Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mips_fpu.c,v 1.13 2016/03/26 17:40:02 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_fpu.c,v 1.14 2017/03/16 16:13:20 chs Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -58,9 +58,9 @@ const pcu_ops_t mips_fpu_ops = {
 };
 
 void
-fpu_discard(void)
+fpu_discard(lwp_t *l)
 {
-	pcu_discard(&mips_fpu_ops, false);
+	pcu_discard(&mips_fpu_ops, l, false);
 }
 
 void
@@ -70,15 +70,15 @@ fpu_load(void)
 }
 
 void
-fpu_save(void)
+fpu_save(lwp_t *l)
 {
-	pcu_save(&mips_fpu_ops);
+	pcu_save(&mips_fpu_ops, l);
 }
 
 bool
-fpu_used_p(void)
+fpu_used_p(const lwp_t *l)
 {
-	return pcu_valid_p(&mips_fpu_ops);
+	return pcu_valid_p(&mips_fpu_ops, l);
 }
 
 void
Index: src/sys/arch/mips/mips/netbsd32_machdep.c
diff -u src/sys/arch/mips/mips/netbsd32_machdep.c:1.13 src/sys/arch/mips/mips/netbsd32_machdep.c:1.14
--- src/sys/arch/mips/mips/netbsd32_machdep.c:1.13	Thu Nov 26 13:15:34 2015
+++ src/sys/arch/mips/mips/netbsd32_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_machdep.c,v 1.13 2015/11/26 13:15:34 martin Exp $	*/
+/*	$NetBSD: netbsd32_machdep.c,v 1.14 2017/03/16 16:13:20 chs Exp $	*/
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.13 2015/11/26 13:15:34 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.14 2017/03/16 16:13:20 chs Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_coredump.h"
@@ -324,8 +324,7 @@ cpu_coredump32(struct lwp *l, struct cor
 		return 0;
 	}
 
-	KASSERT(l == curlwp);
-	fpu_save();
+	fpu_save(l);
 
 	struct pcb * const pcb = lwp_getpcb(l);
 	cpustate.frame = *l->l_md.md_utf;

Index: src/sys/arch/mips/mips/process_machdep.c
diff -u src/sys/arch/mips/mips/process_machdep.c:1.37 src/sys/arch/mips/mips/process_machdep.c:1.38
--- src/sys/arch/mips/mips/process_machdep.c:1.37	Sat Jan  4 00:10:03 2014
+++ src/sys/arch/mips/mips/process_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: process_machdep.c,v 1.37 2014/01/04 00:10:03 dsl Exp $	*/
+/*	$NetBSD: process_machdep.c,v 1.38 2017/03/16 16:13:20 chs Exp $	*/
 
 /*
  * Copyright (c) 1993 The Regents of the University of California.
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.37 2014/01/04 00:10:03 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.38 2017/03/16 16:13:20 chs Exp $");
 
 /*
  * This file may seem a bit stylized, but that so that it's easier to port.
@@ -144,7 +144,7 @@ process_read_fpregs(struct lwp *l, struc
 		*regslen_p = sizeof(struct fpreg_oabi);
 #endif
 
-	fpu_save();
+	fpu_save(l);
 	memcpy(regs, &pcb->pcb_fpregs, sizeof(*regs));
 	return 0;
 }
@@ -156,7 +156,7 @@ process_write_fpregs(struct lwp *l, cons
 
 #ifndef NOFPU
 	/* to load FPA contents next time when FP insn is executed */
-	fpu_discard();
+	fpu_discard(l);
 #endif /* !NOFPU */
 
 #if defined(__mips_n32) || defined(__mips_n64)

Index: src/sys/arch/powerpc/booke/spe.c
diff -u src/sys/arch/powerpc/booke/spe.c:1.8 src/sys/arch/powerpc/booke/spe.c:1.9
--- src/sys/arch/powerpc/booke/spe.c:1.8	Fri May 16 00:48:41 2014
+++ src/sys/arch/powerpc/booke/spe.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: spe.c,v 1.8 2014/05/16 00:48:41 rmind Exp $	*/
+/*	$NetBSD: spe.c,v 1.9 2017/03/16 16:13:20 chs Exp $	*/
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spe.c,v 1.8 2014/05/16 00:48:41 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spe.c,v 1.9 2017/03/16 16:13:20 chs Exp $");
 
 #include "opt_altivec.h"
 
@@ -63,13 +63,13 @@ const pcu_ops_t vec_ops = {
 bool
 vec_used_p(lwp_t *l)
 {
-	return pcu_valid_p(&vec_ops);
+	return pcu_valid_p(&vec_ops, l);
 }
 
 void
 vec_mark_used(lwp_t *l)
 {
-	pcu_discard(&vec_ops, true);
+	pcu_discard(&vec_ops, l, true);
 }
 
 void

Index: src/sys/arch/powerpc/include/altivec.h
diff -u src/sys/arch/powerpc/include/altivec.h:1.16 src/sys/arch/powerpc/include/altivec.h:1.17
--- src/sys/arch/powerpc/include/altivec.h:1.16	Thu Aug 22 19:50:54 2013
+++ src/sys/arch/powerpc/include/altivec.h	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: altivec.h,v 1.16 2013/08/22 19:50:54 drochner Exp $	*/
+/*	$NetBSD: altivec.h,v 1.17 2017/03/16 16:13:20 chs Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -60,15 +60,15 @@ vec_load(void)
 }
 
 static inline void
-vec_save(void)
+vec_save(lwp_t *l)
 {
-	pcu_save(&vec_ops);
+	pcu_save(&vec_ops, l);
 }
 
 static inline void
-vec_discard(void)
+vec_discard(lwp_t *l)
 {
-	pcu_discard(&vec_ops, false);
+	pcu_discard(&vec_ops, l, false);
 }
 
 void	vec_load_from_vreg(const struct vreg *);

Index: src/sys/arch/powerpc/include/fpu.h
diff -u src/sys/arch/powerpc/include/fpu.h:1.20 src/sys/arch/powerpc/include/fpu.h:1.21
--- src/sys/arch/powerpc/include/fpu.h:1.20	Thu Aug 22 19:50:54 2013
+++ src/sys/arch/powerpc/include/fpu.h	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: fpu.h,v 1.20 2013/08/22 19:50:54 drochner Exp $	*/
+/*	$NetBSD: fpu.h,v 1.21 2017/03/16 16:13:20 chs Exp $	*/
 
 /*-
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -98,15 +98,15 @@ fpu_load(void)
 }
 
 static inline void
-fpu_save(void)
+fpu_save(lwp_t *l)
 {
-	pcu_save(&fpu_ops);
+	pcu_save(&fpu_ops, l);
 }
 
 static inline void
-fpu_discard(void)
+fpu_discard(lwp_t *l)
 {
-	pcu_discard(&fpu_ops, false);
+	pcu_discard(&fpu_ops, l, false);
 }
 
 void	fpu_load_from_fpreg(const struct fpreg *);

Index: src/sys/arch/powerpc/oea/altivec.c
diff -u src/sys/arch/powerpc/oea/altivec.c:1.30 src/sys/arch/powerpc/oea/altivec.c:1.31
--- src/sys/arch/powerpc/oea/altivec.c:1.30	Mon Jul  6 02:43:26 2015
+++ src/sys/arch/powerpc/oea/altivec.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: altivec.c,v 1.30 2015/07/06 02:43:26 matt Exp $	*/
+/*	$NetBSD: altivec.c,v 1.31 2017/03/16 16:13:20 chs Exp $	*/
 
 /*
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.30 2015/07/06 02:43:26 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.31 2017/03/16 16:13:20 chs Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -63,13 +63,13 @@ const pcu_ops_t vec_ops = {
 bool
 vec_used_p(lwp_t *l)
 {
-	return pcu_valid_p(&vec_ops);
+	return pcu_valid_p(&vec_ops, l);
 }
 
 void
 vec_mark_used(lwp_t *l)
 {
-	return pcu_discard(&vec_ops, true);
+	return pcu_discard(&vec_ops, l, true);
 }
 
 void
@@ -166,7 +166,8 @@ vec_restore_from_mcontext(struct lwp *l,
 	KASSERT(l == curlwp);
 
 	/* we don't need to save the state, just drop it */
-	pcu_discard(&vec_ops, true);
+	pcu_discard(&vec_ops, l, true);
+
 	memcpy(pcb->pcb_vr.vreg, &mcp->__vrf.__vrs, sizeof (pcb->pcb_vr.vreg));
 	pcb->pcb_vr.vscr = mcp->__vrf.__vscr;
 	pcb->pcb_vr.vrsave = mcp->__vrf.__vrsave;
@@ -187,7 +188,7 @@ vec_save_to_mcontext(struct lwp *l, mcon
 	/*
 	 * If we're the AltiVec owner, dump its context to the PCB first.
 	 */
-	pcu_save(&vec_ops);
+	pcu_save(&vec_ops, l);
 
 	mcp->__gregs[_REG_MSR] |= PSL_VEC;
 	mcp->__vrf.__vscr = pcb->pcb_vr.vscr;

Index: src/sys/arch/powerpc/powerpc/fpu.c
diff -u src/sys/arch/powerpc/powerpc/fpu.c:1.37 src/sys/arch/powerpc/powerpc/fpu.c:1.38
--- src/sys/arch/powerpc/powerpc/fpu.c:1.37	Thu Mar  9 00:14:03 2017
+++ src/sys/arch/powerpc/powerpc/fpu.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: fpu.c,v 1.37 2017/03/09 00:14:03 chs Exp $	*/
+/*	$NetBSD: fpu.c,v 1.38 2017/03/16 16:13:20 chs Exp $	*/
 
 /*
  * Copyright (C) 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.37 2017/03/09 00:14:03 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.38 2017/03/16 16:13:20 chs Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -65,13 +65,13 @@ const pcu_ops_t fpu_ops = {
 bool
 fpu_used_p(lwp_t *l)
 {
-	return pcu_valid_p(&fpu_ops);
+	return pcu_valid_p(&fpu_ops, l);
 }
 
 void
 fpu_mark_used(lwp_t *l)
 {
-	pcu_discard(&fpu_ops, true);
+	pcu_discard(&fpu_ops, l, true);
 }
 
 #ifdef PPC_HAVE_FPU
@@ -176,7 +176,7 @@ fpu_get_fault_code(void)
 		 * We got preempted to a different CPU so we need to save
 		 * our FPU state.
 		 */
-		fpu_save();
+		fpu_save(l);
 		fpscr64 = *(uint64_t *)&pcb->pcb_fpu.fpscr;
 		((uint32_t *)&pcb->pcb_fpu.fpscr)[_QUAD_LOWWORD] &= ~MASKBITS;
 	}
@@ -214,14 +214,14 @@ fpu_save_to_mcontext(lwp_t *l, mcontext_
 {
 	KASSERT(l == curlwp);
 
-	if (!pcu_valid_p(&fpu_ops))
+	if (!pcu_valid_p(&fpu_ops, l))
 		return false;
 
 	struct pcb * const pcb = lwp_getpcb(l);
 
 #ifdef PPC_HAVE_FPU
 	/* If we're the FPU owner, dump its context to the PCB first. */
-	pcu_save(&fpu_ops);
+	pcu_save(&fpu_ops, l);
 #endif
 	(void)memcpy(mcp->__fpregs.__fpu_regs, pcb->pcb_fpu.fpreg,
 	    sizeof (mcp->__fpregs.__fpu_regs));
@@ -242,8 +242,7 @@ fpu_restore_from_mcontext(lwp_t *l, cons
 
 #ifdef PPC_HAVE_FPU
 	/* we don't need to save the state, just drop it */
-	if (l == curlwp)
-		pcu_discard(&fpu_ops, true);
+	pcu_discard(&fpu_ops, l, true);
 #endif
 	(void)memcpy(&pcb->pcb_fpu.fpreg, &mcp->__fpregs.__fpu_regs,
 	    sizeof (pcb->pcb_fpu.fpreg));
Index: src/sys/arch/powerpc/powerpc/process_machdep.c
diff -u src/sys/arch/powerpc/powerpc/process_machdep.c:1.37 src/sys/arch/powerpc/powerpc/process_machdep.c:1.38
--- src/sys/arch/powerpc/powerpc/process_machdep.c:1.37	Sun Mar  9 22:31:25 2014
+++ src/sys/arch/powerpc/powerpc/process_machdep.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: process_machdep.c,v 1.37 2014/03/09 22:31:25 matt Exp $	*/
+/*	$NetBSD: process_machdep.c,v 1.38 2017/03/16 16:13:20 chs Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.37 2014/03/09 22:31:25 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.38 2017/03/16 16:13:20 chs Exp $");
 
 #include "opt_altivec.h"
 
@@ -90,12 +90,8 @@ process_read_fpregs(struct lwp *l, struc
 	if (!fpu_used_p(l)) {
 		memset(fpregs, 0, sizeof (*fpregs));
 #ifdef PPC_HAVE_FPU
-	} else if (l == curlwp) {
-		fpu_save();
 	} else {
-		KASSERTMSG(l->l_pcu_cpu[PCU_FPU] == NULL,
-		    "%s: FPU of l (%p) active on cpu%u",
-		     __func__, l, cpu_index(l->l_pcu_cpu[PCU_FPU]));
+		fpu_save(l);
 #endif
 	}
 	*fpregs = pcb->pcb_fpu;
@@ -110,8 +106,7 @@ process_write_fpregs(struct lwp *l, cons
 	struct pcb * const pcb = lwp_getpcb(l);
 
 #ifdef PPC_HAVE_FPU
-	KASSERT(l == curlwp);
-	fpu_discard();
+	fpu_discard(l);
 #endif
 	pcb->pcb_fpu = *fpregs;
 	fpu_mark_used(l);		/* pcb_fpu is initialized now. */
@@ -154,7 +149,6 @@ process_machdep_read_vecregs(struct lwp 
 {
 	struct pcb * const pcb = lwp_getpcb(l);
 
-	KASSERT(l == curlwp);
 #ifdef ALTIVEC
 	if (cpu_altivec == 0)
 		return EINVAL;
@@ -163,13 +157,9 @@ process_machdep_read_vecregs(struct lwp 
 	/* Is the process using AltiVEC? */
 	if (!vec_used_p(l)) {
 		memset(vregs, 0, sizeof (*vregs));
-	} else if (l == curlwp) {
-		vec_save();
-		*vregs = pcb->pcb_vr;
 	} else {
-		KASSERTMSG(l->l_pcu_cpu[PCU_VEC] == NULL,
-		    "%s: VEC of l (%p) active on cpu%u",
-		     __func__, l, cpu_index(l->l_pcu_cpu[PCU_FPU]));
+		vec_save(l);
+		*vregs = pcb->pcb_vr;
 	}
 	vec_mark_used(l);
 
@@ -181,15 +171,13 @@ process_machdep_write_vecregs(struct lwp
 {
 	struct pcb * const pcb = lwp_getpcb(l);
 
-	KASSERT(l == curlwp);
-
 #ifdef ALTIVEC
 	if (cpu_altivec == 0)
 		return (EINVAL);
 #endif
 
 #if defined(ALTIVEC) || defined(PPC_HAVE_SPE)
-	vec_discard();
+	vec_discard(l);
 #endif
 	pcb->pcb_vr = *vregs;		/* pcb_vr is initialized now. */
 	vec_mark_used(l);

Index: src/sys/arch/powerpc/powerpc/trap.c
diff -u src/sys/arch/powerpc/powerpc/trap.c:1.152 src/sys/arch/powerpc/powerpc/trap.c:1.153
--- src/sys/arch/powerpc/powerpc/trap.c:1.152	Thu Mar  9 00:15:06 2017
+++ src/sys/arch/powerpc/powerpc/trap.c	Thu Mar 16 16:13:20 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: trap.c,v 1.152 2017/03/09 00:15:06 chs Exp $	*/
+/*	$NetBSD: trap.c,v 1.153 2017/03/16 16:13:20 chs Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.152 2017/03/09 00:15:06 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.153 2017/03/16 16:13:20 chs Exp $");
 
 #include "opt_altivec.h"
 #include "opt_ddb.h"
@@ -757,12 +757,12 @@ fix_unaligned(struct lwp *l, struct trap
 				memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu));
 				fpu_mark_used(l);
 			} else {
-				fpu_save();
+				fpu_save(l);
 			}
 
-				if (copyin((void *)tf->tf_dar, fpreg,
-				    sizeof(double)) != 0)
-					return -1;
+			if (copyin((void *)tf->tf_dar, fpreg,
+				   sizeof(double)) != 0)
+				return -1;
 
 			if (dsi->flags & DSI_OP_INDEXED) {
 			    /* do nothing */
@@ -803,12 +803,12 @@ fix_unaligned(struct lwp *l, struct trap
 				memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu));
 				fpu_mark_used(l);
 			} else {
-				fpu_save();
+				fpu_save(l);
 			}
 
-				if (copyout(fpreg, (void *)tf->tf_dar,
+			if (copyout(fpreg, (void *)tf->tf_dar,
 				    sizeof(double)) != 0)
-					return -1;
+				return -1;
 
 			if (dsi->flags & DSI_OP_INDEXED) {
 			    /* do nothing */

Index: src/sys/arch/riscv/include/locore.h
diff -u src/sys/arch/riscv/include/locore.h:1.2 src/sys/arch/riscv/include/locore.h:1.3
--- src/sys/arch/riscv/include/locore.h:1.2	Sat Mar 28 16:13:56 2015
+++ src/sys/arch/riscv/include/locore.h	Thu Mar 16 16:13:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.h,v 1.2 2015/03/28 16:13:56 matt Exp $ */
+/* $NetBSD: locore.h,v 1.3 2017/03/16 16:13:21 chs Exp $ */
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -138,27 +138,27 @@ fpu_load(void)
 }
 
 static inline void
-fpu_save(void)
+fpu_save(lwp_t *l)
 {
-	pcu_save(&pcu_fpu_ops);
+	pcu_save(&pcu_fpu_ops, l);
 }
 
 static inline void
-fpu_discard(void)
+fpu_discard(lwp_t *l)
 {
-	pcu_discard(&pcu_fpu_ops, false);
+	pcu_discard(&pcu_fpu_ops, l, false);
 }
 
 static inline void
-fpu_replace(void)
+fpu_replace(lwp_t *l)
 {
-	pcu_discard(&pcu_fpu_ops, true);
+	pcu_discard(&pcu_fpu_ops, l, true);
 }
 
 static inline bool
-fpu_valid_p(void)
+fpu_valid_p(lwp_t *l)
 {
-	return pcu_valid_p(&pcu_fpu_ops);
+	return pcu_valid_p(&pcu_fpu_ops, l);
 }
 
 void	__syncicache(const void *, size_t);

Index: src/sys/arch/riscv/riscv/netbsd32_machdep.c
diff -u src/sys/arch/riscv/riscv/netbsd32_machdep.c:1.2 src/sys/arch/riscv/riscv/netbsd32_machdep.c:1.3
--- src/sys/arch/riscv/riscv/netbsd32_machdep.c:1.2	Thu Nov 26 13:15:34 2015
+++ src/sys/arch/riscv/riscv/netbsd32_machdep.c	Thu Mar 16 16:13:21 2017
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>
 
-__RCSID("$NetBSD: netbsd32_machdep.c,v 1.2 2015/11/26 13:15:34 martin Exp $");
+__RCSID("$NetBSD: netbsd32_machdep.c,v 1.3 2017/03/16 16:13:21 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/ucontext.h>
@@ -92,12 +92,12 @@ cpu_getmcontext32(struct lwp *l, mcontex
 
 	/* Save floating point register context, if any. */
 	KASSERT(l == curlwp);
-	if (fpu_valid_p()) {
+	if (fpu_valid_p(l)) {
 		/*
 		 * If this process is the current FP owner, dump its
 		 * context to the PCB first.
 		 */
-		fpu_save();
+		fpu_save(l);
 
 		struct pcb * const pcb = lwp_getpcb(l);
 		*(struct fpreg *)mcp->__fregs = pcb->pcb_fpregs;
@@ -149,7 +149,7 @@ cpu_setmcontext32(struct lwp *l, const m
 	if (flags & _UC_FPU) {
 		KASSERT(l == curlwp);
 		/* Tell PCU we are replacing the FPU contents. */
-		fpu_replace();
+		fpu_replace(l);
 
 		/*
 		 * The PCB FP regs struct includes the FP CSR, so use the
@@ -185,4 +185,3 @@ netbsd32_vm_default_addr(struct proc *p,
 	else
 		return VM_DEFAULT_ADDRESS32_BOTTOMUP(base, size);
 }
-

Index: src/sys/arch/riscv/riscv/process_machdep.c
diff -u src/sys/arch/riscv/riscv/process_machdep.c:1.1 src/sys/arch/riscv/riscv/process_machdep.c:1.2
--- src/sys/arch/riscv/riscv/process_machdep.c:1.1	Sat Mar 28 16:13:56 2015
+++ src/sys/arch/riscv/riscv/process_machdep.c	Thu Mar 16 16:13:21 2017
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>
 
-__RCSID("$NetBSD: process_machdep.c,v 1.1 2015/03/28 16:13:56 matt Exp $");
+__RCSID("$NetBSD: process_machdep.c,v 1.2 2017/03/16 16:13:21 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/ptrace.h>
@@ -63,19 +63,14 @@ process_read_fpregs(struct lwp *l, struc
 {
 	struct pcb * const pcb = lwp_getpcb(l);
 
-	if (l == curlwp) {
-		/* Is the process using the fpu? */
-		if (!fpu_valid_p()) {
-			memset(fpregs, 0, sizeof (*fpregs));
-			return 0;
-		}
-		fpu_save();
-	} else {
-		KASSERTMSG(l->l_pcu_cpu[PCU_FPU] == NULL,
-		    "%s: FPU of l (%p) active on %s",
-		     __func__, l, l->l_pcu_cpu[PCU_FPU]->ci_cpuname);
+	/* Is the process using the fpu? */
+	if (!fpu_valid_p(l)) {
+		memset(fpregs, 0, sizeof (*fpregs));
+		return 0;
 	}
+	fpu_save(l);
 	*fpregs = pcb->pcb_fpregs;
+
 	return 0;
 }
 
@@ -84,9 +79,7 @@ process_write_fpregs(struct lwp *l, cons
 {
 	struct pcb * const pcb = lwp_getpcb(l);
 
-	KASSERT(l == curlwp);
-	fpu_replace();
-
+	fpu_replace(l);
 	pcb->pcb_fpregs = *fpregs;
 
 	return 0;
Index: src/sys/arch/riscv/riscv/riscv_machdep.c
diff -u src/sys/arch/riscv/riscv/riscv_machdep.c:1.1 src/sys/arch/riscv/riscv/riscv_machdep.c:1.2
--- src/sys/arch/riscv/riscv/riscv_machdep.c:1.1	Sat Mar 28 16:13:56 2015
+++ src/sys/arch/riscv/riscv/riscv_machdep.c	Thu Mar 16 16:13:21 2017
@@ -31,7 +31,7 @@
 
 #include "opt_modular.h"
 
-__RCSID("$NetBSD: riscv_machdep.c,v 1.1 2015/03/28 16:13:56 matt Exp $");
+__RCSID("$NetBSD: riscv_machdep.c,v 1.2 2017/03/16 16:13:21 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -170,12 +170,12 @@ cpu_getmcontext(struct lwp *l, mcontext_
 
 	/* Save floating point register context, if any. */
 	KASSERT(l == curlwp);
-	if (fpu_valid_p()) {
+	if (fpu_valid_p(l)) {
 		/*
 		 * If this process is the current FP owner, dump its
 		 * context to the PCB first.
 		 */
-		fpu_save();
+		fpu_save(l);
 
 		struct pcb * const pcb = lwp_getpcb(l);
 		*(struct fpreg *)mcp->__fregs = pcb->pcb_fpregs;
@@ -224,7 +224,7 @@ cpu_setmcontext(struct lwp *l, const mco
 	if (flags & _UC_FPU) {
 		KASSERT(l == curlwp);
 		/* Tell PCU we are replacing the FPU contents. */
-		fpu_replace();
+		fpu_replace(l);
 
 		/*
 		 * The PCB FP regs struct includes the FP CSR, so use the

Index: src/sys/compat/linux/arch/powerpc/linux_machdep.c
diff -u src/sys/compat/linux/arch/powerpc/linux_machdep.c:1.48 src/sys/compat/linux/arch/powerpc/linux_machdep.c:1.49
--- src/sys/compat/linux/arch/powerpc/linux_machdep.c:1.48	Sun Nov  9 17:48:08 2014
+++ src/sys/compat/linux/arch/powerpc/linux_machdep.c	Thu Mar 16 16:13:21 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_machdep.c,v 1.48 2014/11/09 17:48:08 maxv Exp $ */
+/*	$NetBSD: linux_machdep.c,v 1.49 2017/03/16 16:13:21 chs Exp $ */
 
 /*-
  * Copyright (c) 1995, 2000, 2001 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.48 2014/11/09 17:48:08 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.49 2017/03/16 16:13:21 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -181,7 +181,7 @@ linux_sendsig(const ksiginfo_t *ksi, con
 	memcpy(&frame.lgp_regs, &linux_regs, sizeof(linux_regs));
 
 #ifdef PPC_HAVE_FPU
-	fpu_save();
+	fpu_save(l);
 #endif
 	memcpy(&frame.lfp_regs, curpcb->pcb_fpu.fpreg, sizeof(frame.lfp_regs));
 

Index: src/sys/kern/subr_pcu.c
diff -u src/sys/kern/subr_pcu.c:1.19 src/sys/kern/subr_pcu.c:1.20
--- src/sys/kern/subr_pcu.c:1.19	Sun May 25 14:53:55 2014
+++ src/sys/kern/subr_pcu.c	Thu Mar 16 16:13:21 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_pcu.c,v 1.19 2014/05/25 14:53:55 rmind Exp $	*/
+/*	$NetBSD: subr_pcu.c,v 1.20 2017/03/16 16:13:21 chs Exp $	*/
 
 /*-
  * Copyright (c) 2011, 2014 The NetBSD Foundation, Inc.
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_pcu.c,v 1.19 2014/05/25 14:53:55 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_pcu.c,v 1.20 2017/03/16 16:13:21 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -313,7 +313,7 @@ pcu_load(const pcu_ops_t *pcu)
 		 * some architectures.
 		 */
 		KASSERT(curci->ci_pcu_curlwp[id] == l);
-		KASSERT(pcu_valid_p(pcu));
+		KASSERT(pcu_valid_p(pcu, l));
 		pcu->pcu_state_load(l, PCU_VALID | PCU_REENABLE);
 		splx(s);
 		return;
@@ -356,14 +356,13 @@ pcu_load(const pcu_ops_t *pcu)
 }
 
 /*
- * pcu_discard: discard the PCU state of current LWP.  If "valid"
+ * pcu_discard: discard the PCU state of the given LWP.  If "valid"
  * parameter is true, then keep considering the PCU state as valid.
  */
 void
-pcu_discard(const pcu_ops_t *pcu, bool valid)
+pcu_discard(const pcu_ops_t *pcu, lwp_t *l, bool valid)
 {
 	const u_int id = pcu->pcu_id;
-	lwp_t * const l = curlwp;
 
 	KASSERT(!cpu_intr_p() && !cpu_softintr_p());
 
@@ -382,10 +381,9 @@ pcu_discard(const pcu_ops_t *pcu, bool v
  * pcu_save_lwp: save PCU state to the given LWP.
  */
 void
-pcu_save(const pcu_ops_t *pcu)
+pcu_save(const pcu_ops_t *pcu, lwp_t *l)
 {
 	const u_int id = pcu->pcu_id;
-	lwp_t * const l = curlwp;
 
 	KASSERT(!cpu_intr_p() && !cpu_softintr_p());
 
@@ -420,10 +418,9 @@ pcu_save_all_on_cpu(void)
  * it always becomes "valid" when pcu_load() is called.
  */
 bool
-pcu_valid_p(const pcu_ops_t *pcu)
+pcu_valid_p(const pcu_ops_t *pcu, const lwp_t *l)
 {
 	const u_int id = pcu->pcu_id;
-	lwp_t * const l = curlwp;
 
 	return (l->l_pcu_valid & (1U << id)) != 0;
 }

Index: src/sys/sys/pcu.h
diff -u src/sys/sys/pcu.h:1.12 src/sys/sys/pcu.h:1.13
--- src/sys/sys/pcu.h:1.12	Fri May 16 00:48:41 2014
+++ src/sys/sys/pcu.h	Thu Mar 16 16:13:21 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: pcu.h,v 1.12 2014/05/16 00:48:41 rmind Exp $	*/
+/*	$NetBSD: pcu.h,v 1.13 2017/03/16 16:13:21 chs Exp $	*/
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -81,10 +81,10 @@ void	pcu_discard_all(lwp_t *);
 void	pcu_save_all(lwp_t *);
 
 void	pcu_load(const pcu_ops_t *);
-void	pcu_save(const pcu_ops_t *);
+void	pcu_save(const pcu_ops_t *, lwp_t *);
 void	pcu_save_all_on_cpu(void);
-void	pcu_discard(const pcu_ops_t *, bool);
-bool	pcu_valid_p(const pcu_ops_t *);
+void	pcu_discard(const pcu_ops_t *, lwp_t *, bool);
+bool	pcu_valid_p(const pcu_ops_t *, const lwp_t *);
 
 #else
 #define	pcu_switchpoint(l)

Reply via email to