Module Name: src Committed By: matt Date: Tue Jun 7 00:48:32 UTC 2011
Modified Files: src/sys/arch/alpha/alpha: compat_13_machdep.c compat_16_machdep.c core_machdep.c cpu.c fp_complete.c genassym.cf ipifuncs.c locore.s machdep.c process_machdep.c trap.c vm_machdep.c src/sys/arch/alpha/include: alpha.h intr.h pcb.h proc.h types.h src/sys/arch/mips/mips: mips_machdep.c src/sys/arch/powerpc/powerpc: fpu.c powerpc_machdep.c Log Message: Switch alpha to use PCU to manage the FPU. Tested by mhitch and review by rmind. To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/sys/arch/alpha/alpha/compat_13_machdep.c cvs rdiff -u -r1.16 -r1.17 src/sys/arch/alpha/alpha/compat_16_machdep.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/alpha/alpha/core_machdep.c cvs rdiff -u -r1.90 -r1.91 src/sys/arch/alpha/alpha/cpu.c cvs rdiff -u -r1.12 -r1.13 src/sys/arch/alpha/alpha/fp_complete.c cvs rdiff -u -r1.19 -r1.20 src/sys/arch/alpha/alpha/genassym.cf cvs rdiff -u -r1.45 -r1.46 src/sys/arch/alpha/alpha/ipifuncs.c cvs rdiff -u -r1.120 -r1.121 src/sys/arch/alpha/alpha/locore.s cvs rdiff -u -r1.333 -r1.334 src/sys/arch/alpha/alpha/machdep.c cvs rdiff -u -r1.25 -r1.26 src/sys/arch/alpha/alpha/process_machdep.c cvs rdiff -u -r1.125 -r1.126 src/sys/arch/alpha/alpha/trap.c cvs rdiff -u -r1.106 -r1.107 src/sys/arch/alpha/alpha/vm_machdep.c cvs rdiff -u -r1.25 -r1.26 src/sys/arch/alpha/include/alpha.h cvs rdiff -u -r1.68 -r1.69 src/sys/arch/alpha/include/intr.h cvs rdiff -u -r1.19 -r1.20 src/sys/arch/alpha/include/pcb.h \ src/sys/arch/alpha/include/proc.h cvs rdiff -u -r1.45 -r1.46 src/sys/arch/alpha/include/types.h cvs rdiff -u -r1.240 -r1.241 src/sys/arch/mips/mips/mips_machdep.c cvs rdiff -u -r1.29 -r1.30 src/sys/arch/powerpc/powerpc/fpu.c cvs rdiff -u -r1.49 -r1.50 src/sys/arch/powerpc/powerpc/powerpc_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/alpha/alpha/compat_13_machdep.c diff -u src/sys/arch/alpha/alpha/compat_13_machdep.c:1.18 src/sys/arch/alpha/alpha/compat_13_machdep.c:1.19 --- src/sys/arch/alpha/alpha/compat_13_machdep.c:1.18 Sat Nov 21 05:35:40 2009 +++ src/sys/arch/alpha/alpha/compat_13_machdep.c Tue Jun 7 00:48:29 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: compat_13_machdep.c,v 1.18 2009/11/21 05:35:40 rmind Exp $ */ +/* $NetBSD: compat_13_machdep.c,v 1.19 2011/06/07 00:48:29 matt 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.18 2009/11/21 05:35:40 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.19 2011/06/07 00:48:29 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -94,8 +94,7 @@ /* XXX ksc.sc_ownedfp ? */ pcb = lwp_getpcb(l); - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 0); + fpu_discard(); 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.16 src/sys/arch/alpha/alpha/compat_16_machdep.c:1.17 --- src/sys/arch/alpha/alpha/compat_16_machdep.c:1.16 Sat Nov 21 05:35:40 2009 +++ src/sys/arch/alpha/alpha/compat_16_machdep.c Tue Jun 7 00:48:29 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: compat_16_machdep.c,v 1.16 2009/11/21 05:35:40 rmind Exp $ */ +/* $NetBSD: compat_16_machdep.c,v 1.17 2011/06/07 00:48:29 matt 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.16 2009/11/21 05:35:40 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.17 2011/06/07 00:48:29 matt Exp $"); #ifdef DEBUG @@ -132,9 +132,8 @@ frame.sf_sc.sc_regs[R_SP] = alpha_pal_rdusp(); /* save the floating-point state, if necessary, then copy it. */ - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 1); - frame.sf_sc.sc_ownedfp = l->l_md.md_flags & MDP_FPUSED; + fpu_save(); + frame.sf_sc.sc_ownedfp = fpu_used_p(l); memcpy((struct fpreg *)frame.sf_sc.sc_fpregs, &pcb->pcb_fp, sizeof(struct fpreg)); frame.sf_sc.sc_fp_control = alpha_read_fp_c(l); @@ -281,14 +280,13 @@ regtoframe((struct reg *)ksc.sc_regs, l->l_md.md_tf); alpha_pal_wrusp(ksc.sc_regs[R_SP]); - /* XXX ksc.sc_ownedfp ? */ pcb = lwp_getpcb(l); - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 0); + fpu_discard(); memcpy(&pcb->pcb_fp, (struct fpreg *)ksc.sc_fpregs, sizeof(struct fpreg)); pcb->pcb_fp.fpr_cr = ksc.sc_fpcr; - l->l_md.md_flags = ksc.sc_fp_control & MDP_FP_C; + l->l_md.md_flags = (ksc.sc_fp_control & MDLWP_FP_C) + | (ksc.sc_ownedfp ? MDLWP_FPUSED : 0); mutex_enter(p->p_lock); /* Restore signal stack. */ Index: src/sys/arch/alpha/alpha/core_machdep.c diff -u src/sys/arch/alpha/alpha/core_machdep.c:1.4 src/sys/arch/alpha/alpha/core_machdep.c:1.5 --- src/sys/arch/alpha/alpha/core_machdep.c:1.4 Wed Dec 15 01:32:31 2010 +++ src/sys/arch/alpha/alpha/core_machdep.c Tue Jun 7 00:48:29 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: core_machdep.c,v 1.4 2010/12/15 01:32:31 matt Exp $ */ +/* $NetBSD: core_machdep.c,v 1.5 2011/06/07 00:48:29 matt 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: core_machdep.c,v 1.4 2010/12/15 01:32:31 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: core_machdep.c,v 1.5 2011/06/07 00:48:29 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -68,10 +68,9 @@ cpustate.md_tf = *l->l_md.md_tf; cpustate.md_tf.tf_regs[FRAME_SP] = alpha_pal_rdusp(); /* XXX */ - if (l->l_md.md_flags & MDP_FPUSED) { + if (fpu_used_p(l)) { struct pcb *pcb = lwp_getpcb(l); - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 1); + fpu_save(); cpustate.md_fpstate = pcb->pcb_fp; } else memset(&cpustate.md_fpstate, 0, sizeof(cpustate.md_fpstate)); Index: src/sys/arch/alpha/alpha/cpu.c diff -u src/sys/arch/alpha/alpha/cpu.c:1.90 src/sys/arch/alpha/alpha/cpu.c:1.91 --- src/sys/arch/alpha/alpha/cpu.c:1.90 Fri Dec 17 02:36:35 2010 +++ src/sys/arch/alpha/alpha/cpu.c Tue Jun 7 00:48:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.90 2010/12/17 02:36:35 joerg Exp $ */ +/* $NetBSD: cpu.c,v 1.91 2011/06/07 00:48:30 matt Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.90 2010/12/17 02:36:35 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.91 2011/06/07 00:48:30 matt Exp $"); #include "opt_ddb.h" #include "opt_multiprocessor.h" @@ -660,16 +660,15 @@ struct cpu_info *ci; CPU_INFO_ITERATOR cii; - db_printf("addr dev id flags ipis curproc fpcurproc\n"); + db_printf("addr dev id flags ipis curproc\n"); for (CPU_INFO_FOREACH(cii, ci)) { - db_printf("%p %s %lu %lx %lx %p %p\n", + db_printf("%p %s %lu %lx %lx %p\n", ci, ci->ci_softc->sc_dev.dv_xname, ci->ci_cpuid, ci->ci_flags, ci->ci_ipis, - ci->ci_curlwp, - ci->ci_fpcurlwp); + ci->ci_curlwp); } } Index: src/sys/arch/alpha/alpha/fp_complete.c diff -u src/sys/arch/alpha/alpha/fp_complete.c:1.12 src/sys/arch/alpha/alpha/fp_complete.c:1.13 --- src/sys/arch/alpha/alpha/fp_complete.c:1.12 Sat May 10 15:31:04 2008 +++ src/sys/arch/alpha/alpha/fp_complete.c Tue Jun 7 00:48:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: fp_complete.c,v 1.12 2008/05/10 15:31:04 martin Exp $ */ +/* $NetBSD: fp_complete.c,v 1.13 2011/06/07 00:48:30 matt Exp $ */ /*- * Copyright (c) 2001 Ross Harvey @@ -35,13 +35,15 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: fp_complete.c,v 1.12 2008/05/10 15:31:04 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fp_complete.c,v 1.13 2011/06/07 00:48:30 matt Exp $"); #include "opt_compat_osf1.h" #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> +#include <sys/atomic.h> +#include <sys/evcnt.h> #ifdef COMPAT_OSF1 #include <compat/osf1/osf1_exec.h> @@ -99,6 +101,9 @@ #define CRBLIT(sw, hw, m, offs) (((sw) & ~(m)) | ((hw) >> (offs) & (m))) +struct evcnt fpevent_use; +struct evcnt fpevent_reuse; + /* * Temporary trap shadow instrumentation. The [un]resolved counters * could be kept permanently, as they provide information on whether @@ -398,12 +403,13 @@ { u_int64_t md_flags; - fp_c &= MDP_FP_C; + fp_c &= MDLWP_FP_C; md_flags = l->l_md.md_flags; - if ((md_flags & MDP_FP_C) == fp_c) + if ((md_flags & MDLWP_FP_C) == fp_c) return; - l->l_md.md_flags = (md_flags & ~MDP_FP_C) | fp_c; - alpha_enable_fp(l, 1); + l->l_md.md_flags = (md_flags & ~MDLWP_FP_C) | fp_c; + fpu_load(); + alpha_pal_wrfen(1); fp_c_to_fpcr(l); alpha_pal_wrfen(0); } @@ -417,7 +423,7 @@ * but in a transparent way. Some of the code for that would need to * go right here. */ - return l->l_md.md_flags & MDP_FP_C; + return l->l_md.md_flags & MDLWP_FP_C; } static float64 @@ -579,7 +585,8 @@ this_cannot_happen(6, -1); return SIGSEGV; } - alpha_enable_fp(l, 1); + fpu_load(); + alpha_pal_wrfen(1); /* * If necessary, lie about the dynamic rounding mode so emulation * software need go to only one place for it, and so we don't have to @@ -707,3 +714,55 @@ } return 0; } + +/* + * Load the float-point context for the current lwp. + */ +void +fpu_state_load(struct lwp *l, bool used) +{ + struct pcb * const pcb = lwp_getpcb(l); + + /* + * Instrument FP usage -- if a process had not previously + * used FP, mark it as having used FP for the first time, + * and count this event. + * + * If a process has used FP, count a "used FP, and took + * a trap to use it again" event. + */ + if (!fpu_used_p(l)) { + atomic_inc_ulong(&fpevent_use.ev_count); + fpu_mark_used(l); + } else + atomic_inc_ulong(&fpevent_reuse.ev_count); + + alpha_pal_wrfen(1); + restorefpstate(&pcb->pcb_fp); + alpha_pal_wrfen(0); + + l->l_md.md_flags |= MDLWP_FPACTIVE; +} + +/* + * Save the FPU state. + */ + +void +fpu_state_save(struct lwp *l) +{ + struct pcb * const pcb = lwp_getpcb(l); + + alpha_pal_wrfen(1); + savefpstate(&pcb->pcb_fp); + alpha_pal_wrfen(0); +} + +/* + * Release the FPU. + */ +void +fpu_state_release(struct lwp *l) +{ + l->l_md.md_flags &= ~MDLWP_FPACTIVE; +} Index: src/sys/arch/alpha/alpha/genassym.cf diff -u src/sys/arch/alpha/alpha/genassym.cf:1.19 src/sys/arch/alpha/alpha/genassym.cf:1.20 --- src/sys/arch/alpha/alpha/genassym.cf:1.19 Wed Dec 15 01:33:37 2010 +++ src/sys/arch/alpha/alpha/genassym.cf Tue Jun 7 00:48:30 2011 @@ -1,4 +1,4 @@ -# $NetBSD: genassym.cf,v 1.19 2010/12/15 01:33:37 matt Exp $ +# $NetBSD: genassym.cf,v 1.20 2011/06/07 00:48:30 matt Exp $ # # Copyright (c) 1982, 1990, 1993 @@ -190,7 +190,6 @@ # CPU info define CPU_INFO_CURLWP offsetof(struct cpu_info, ci_curlwp) -define CPU_INFO_FPCURLWP offsetof(struct cpu_info, ci_fpcurlwp) define CPU_INFO_CURPCB offsetof(struct cpu_info, ci_curpcb) define CPU_INFO_IDLE_LWP offsetof(struct cpu_info, ci_data.cpu_idlelwp) define CPU_INFO_SIZEOF sizeof(struct cpu_info) Index: src/sys/arch/alpha/alpha/ipifuncs.c diff -u src/sys/arch/alpha/alpha/ipifuncs.c:1.45 src/sys/arch/alpha/alpha/ipifuncs.c:1.46 --- src/sys/arch/alpha/alpha/ipifuncs.c:1.45 Fri Dec 17 02:36:35 2010 +++ src/sys/arch/alpha/alpha/ipifuncs.c Tue Jun 7 00:48:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ipifuncs.c,v 1.45 2010/12/17 02:36:35 joerg Exp $ */ +/* $NetBSD: ipifuncs.c,v 1.46 2011/06/07 00:48:30 matt Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.45 2010/12/17 02:36:35 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.46 2011/06/07 00:48:30 matt Exp $"); /* * Interprocessor interrupt handlers. @@ -47,6 +47,7 @@ #include <sys/cpu.h> #include <sys/intr.h> #include <sys/xcall.h> +#include <sys/bitops.h> #include <uvm/uvm_extern.h> @@ -62,8 +63,6 @@ void alpha_ipi_microset(struct cpu_info *, struct trapframe *); void alpha_ipi_imb(struct cpu_info *, struct trapframe *); void alpha_ipi_ast(struct cpu_info *, struct trapframe *); -void alpha_ipi_synch_fpu(struct cpu_info *, struct trapframe *); -void alpha_ipi_discard_fpu(struct cpu_info *, struct trapframe *); void alpha_ipi_pause(struct cpu_info *, struct trapframe *); void alpha_ipi_xcall(struct cpu_info *, struct trapframe *); @@ -71,28 +70,24 @@ * NOTE: This table must be kept in order with the bit definitions * in <machine/intr.h>. */ -ipifunc_t ipifuncs[ALPHA_NIPIS] = { - alpha_ipi_halt, - alpha_ipi_microset, - pmap_do_tlb_shootdown, - alpha_ipi_imb, - alpha_ipi_ast, - alpha_ipi_synch_fpu, - alpha_ipi_discard_fpu, - alpha_ipi_pause, - alpha_ipi_xcall +const ipifunc_t ipifuncs[ALPHA_NIPIS] = { + [ilog2(ALPHA_IPI_HALT)] = alpha_ipi_halt, + [ilog2(ALPHA_IPI_MICROSET)] = alpha_ipi_microset, + [ilog2(ALPHA_IPI_SHOOTDOWN)] = pmap_do_tlb_shootdown, + [ilog2(ALPHA_IPI_IMB)] = alpha_ipi_imb, + [ilog2(ALPHA_IPI_AST)] = alpha_ipi_ast, + [ilog2(ALPHA_IPI_PAUSE)] = alpha_ipi_pause, + [ilog2(ALPHA_IPI_XCALL)] = alpha_ipi_xcall }; -const char *ipinames[ALPHA_NIPIS] = { - "halt ipi", - "microset ipi", - "shootdown ipi", - "imb ipi", - "ast ipi", - "synch fpu ipi", - "discard fpu ipi", - "pause ipi", - "xcall ipi" +const char * const ipinames[ALPHA_NIPIS] = { + [ilog2(ALPHA_IPI_HALT)] = "halt ipi", + [ilog2(ALPHA_IPI_MICROSET)] = "microset ipi", + [ilog2(ALPHA_IPI_SHOOTDOWN)] = "shootdown ipi", + [ilog2(ALPHA_IPI_IMB)] = "imb ipi", + [ilog2(ALPHA_IPI_AST)] = "ast ipi", + [ilog2(ALPHA_IPI_PAUSE)] = "pause ipi", + [ilog2(ALPHA_IPI_XCALL)] = "xcall ipi" }; /* @@ -269,24 +264,6 @@ } void -alpha_ipi_synch_fpu(struct cpu_info *ci, struct trapframe *framep) -{ - - if (ci->ci_flags & CPUF_FPUSAVE) - return; - fpusave_cpu(ci, 1); -} - -void -alpha_ipi_discard_fpu(struct cpu_info *ci, struct trapframe *framep) -{ - - if (ci->ci_flags & CPUF_FPUSAVE) - return; - fpusave_cpu(ci, 0); -} - -void alpha_ipi_pause(struct cpu_info *ci, struct trapframe *framep) { u_long cpumask = (1UL << ci->ci_cpuid); Index: src/sys/arch/alpha/alpha/locore.s diff -u src/sys/arch/alpha/alpha/locore.s:1.120 src/sys/arch/alpha/alpha/locore.s:1.121 --- src/sys/arch/alpha/alpha/locore.s:1.120 Wed Jul 7 01:17:49 2010 +++ src/sys/arch/alpha/alpha/locore.s Tue Jun 7 00:48:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: locore.s,v 1.120 2010/07/07 01:17:49 chs Exp $ */ +/* $NetBSD: locore.s,v 1.121 2011/06/07 00:48:30 matt Exp $ */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ #include <machine/asm.h> -__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.120 2010/07/07 01:17:49 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.121 2011/06/07 00:48:30 matt Exp $"); #include "assym.h" @@ -275,11 +275,9 @@ bne t3, 7f /* yes */ /* no: headed back to user space */ - /* Enable the FPU based on whether the current proc is fpcurlwp. */ -4: ldq t2, CPU_INFO_FPCURLWP(v0) - cmpeq t1, t2, t1 - mov zero, a0 - cmovne t1, 1, a0 + /* Enable the FPU based on whether MDLWP_FPACTIVE is set. */ +4: ldq t2, L_MD_FLAGS(t1) + cmplt t2, zero, a0 call_pal PAL_OSF1_wrfen /* restore the registers, and return */ Index: src/sys/arch/alpha/alpha/machdep.c diff -u src/sys/arch/alpha/alpha/machdep.c:1.333 src/sys/arch/alpha/alpha/machdep.c:1.334 --- src/sys/arch/alpha/alpha/machdep.c:1.333 Tue May 24 20:26:34 2011 +++ src/sys/arch/alpha/alpha/machdep.c Tue Jun 7 00:48:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.333 2011/05/24 20:26:34 rmind Exp $ */ +/* $NetBSD: machdep.c,v 1.334 2011/06/07 00:48:30 matt 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.333 2011/05/24 20:26:34 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.334 2011/06/07 00:48:30 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -205,6 +205,17 @@ void identifycpu(void); void printregs(struct reg *); +const pcu_ops_t fpu_ops = { + .pcu_id = PCU_FPU, + .pcu_state_load = fpu_state_load, + .pcu_state_save = fpu_state_save, + .pcu_state_release = fpu_state_release, +}; + +const pcu_ops_t * const pcu_ops_md_defs[PCU_UNIT_COUNT] = { + [PCU_FPU] = &fpu_ops, +}; + void alpha_init(u_long pfn, u_long ptb, u_long bim, u_long bip, u_long biv) /* pfn: first free PFN number */ @@ -657,7 +668,6 @@ */ pcb0->pcb_hw.apcb_ksp = v + USPACE - sizeof(struct trapframe); lwp0.l_md.md_tf = (struct trapframe *)pcb0->pcb_hw.apcb_ksp; - mutex_init(&pcb0->pcb_fpcpu_lock, MUTEX_DEFAULT, IPL_HIGH); /* Indicate that lwp0 has a CPU. */ lwp0.l_cpu = ci; @@ -1631,117 +1641,12 @@ tfp->tf_regs[FRAME_A3] = l->l_proc->p_psstrp; /* a3 = ps_strings */ tfp->tf_regs[FRAME_T12] = tfp->tf_regs[FRAME_PC]; /* a.k.a. PV */ - l->l_md.md_flags &= ~MDP_FPUSED; + l->l_md.md_flags &= ~MDLWP_FPUSED; if (__predict_true((l->l_md.md_flags & IEEE_INHERIT) == 0)) { - l->l_md.md_flags &= ~MDP_FP_C; + l->l_md.md_flags &= ~MDLWP_FP_C; pcb->pcb_fp.fpr_cr = FPCR_DYN(FP_RN); } - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 0); -} - -/* - * Release the FPU. - */ -void -fpusave_cpu(struct cpu_info *ci, int save) -{ - struct lwp *l; - struct pcb *pcb; -#if defined(MULTIPROCESSOR) - int s; -#endif - - KDASSERT(ci == curcpu()); - -#if defined(MULTIPROCESSOR) - s = splhigh(); /* block IPIs for the duration */ - atomic_or_ulong(&ci->ci_flags, CPUF_FPUSAVE); -#endif - - l = ci->ci_fpcurlwp; - if (l == NULL) - goto out; - - pcb = lwp_getpcb(l); - if (save) { - alpha_pal_wrfen(1); - savefpstate(&pcb->pcb_fp); - } - - alpha_pal_wrfen(0); - - FPCPU_LOCK(pcb); - - pcb->pcb_fpcpu = NULL; - ci->ci_fpcurlwp = NULL; - - FPCPU_UNLOCK(pcb); - - out: -#if defined(MULTIPROCESSOR) - atomic_and_ulong(&ci->ci_flags, ~CPUF_FPUSAVE); - splx(s); -#endif - return; -} - -/* - * Synchronize FP state for this process. - */ -void -fpusave_proc(struct lwp *l, int save) -{ - struct cpu_info *ci = curcpu(); - struct cpu_info *oci; - struct pcb *pcb; -#if defined(MULTIPROCESSOR) - u_long ipi = save ? ALPHA_IPI_SYNCH_FPU : ALPHA_IPI_DISCARD_FPU; - int s, spincount; -#endif - - pcb = lwp_getpcb(l); - KDASSERT(pcb != NULL); - -#if defined(MULTIPROCESSOR) - s = splhigh(); /* block IPIs for the duration */ -#endif - FPCPU_LOCK(pcb); - - oci = pcb->pcb_fpcpu; - if (oci == NULL) { - FPCPU_UNLOCK(pcb); -#if defined(MULTIPROCESSOR) - splx(s); -#endif - return; - } - -#if defined(MULTIPROCESSOR) - if (oci == ci) { - KASSERT(ci->ci_fpcurlwp == l); - FPCPU_UNLOCK(pcb); - splx(s); - fpusave_cpu(ci, save); - return; - } - - KASSERT(oci->ci_fpcurlwp == l); - alpha_send_ipi(oci->ci_cpuid, ipi); - FPCPU_UNLOCK(pcb); - - spincount = 0; - while (pcb->pcb_fpcpu != NULL) { - spincount++; - delay(1000); /* XXX */ - if (spincount > 10000) - panic("fpsave ipi didn't"); - } -#else - KASSERT(ci->ci_fpcurlwp == l); - FPCPU_UNLOCK(pcb); - fpusave_cpu(ci, save); -#endif /* MULTIPROCESSOR */ + fpu_discard(); } /* @@ -1905,8 +1810,8 @@ *flags |= _UC_CPU | _UC_UNIQUE; /* Save floating point register context, if any, and copy it. */ - if (l->l_md.md_flags & MDP_FPUSED) { - fpusave_proc(l, 1); + if (fpu_used_p(l)) { + fpu_save(); (void)memcpy(&mcp->__fpregs, &pcb->pcb_fp, sizeof (mcp->__fpregs)); mcp->__fpregs.__fp_fpcr = alpha_read_fp_c(l); @@ -1942,12 +1847,11 @@ /* Restore floating point register context, if any. */ if (flags & _UC_FPU) { /* If we have an FP register context, get rid of it. */ - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 0); + fpu_discard(); (void)memcpy(&pcb->pcb_fp, &mcp->__fpregs, sizeof (pcb->pcb_fp)); - l->l_md.md_flags = mcp->__fpregs.__fp_fpcr & MDP_FP_C; - l->l_md.md_flags |= MDP_FPUSED; + l->l_md.md_flags = mcp->__fpregs.__fp_fpcr & MDLWP_FP_C; + fpu_mark_used(l); } return (0); Index: src/sys/arch/alpha/alpha/process_machdep.c diff -u src/sys/arch/alpha/alpha/process_machdep.c:1.25 src/sys/arch/alpha/alpha/process_machdep.c:1.26 --- src/sys/arch/alpha/alpha/process_machdep.c:1.25 Sat Nov 21 05:35:40 2009 +++ src/sys/arch/alpha/alpha/process_machdep.c Tue Jun 7 00:48:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: process_machdep.c,v 1.25 2009/11/21 05:35:40 rmind Exp $ */ +/* $NetBSD: process_machdep.c,v 1.26 2011/06/07 00:48:30 matt 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.25 2009/11/21 05:35:40 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.26 2011/06/07 00:48:30 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -116,8 +116,7 @@ { struct pcb *pcb = lwp_getpcb(l); - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 1); + fpu_save(); memcpy(regs, &pcb->pcb_fp, sizeof(struct fpreg)); return (0); @@ -128,8 +127,8 @@ { struct pcb *pcb = lwp_getpcb(l); - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 0); + fpu_discard(); + fpu_mark_used(l); 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.125 src/sys/arch/alpha/alpha/trap.c:1.126 --- src/sys/arch/alpha/alpha/trap.c:1.125 Fri Apr 15 20:52:36 2011 +++ src/sys/arch/alpha/alpha/trap.c Tue Jun 7 00:48:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.125 2011/04/15 20:52:36 martin Exp $ */ +/* $NetBSD: trap.c,v 1.126 2011/06/07 00:48:30 matt 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.125 2011/04/15 20:52:36 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.126 2011/06/07 00:48:30 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -123,9 +123,6 @@ static int handle_opdec(struct lwp *l, u_long *ucodep); static int alpha_ucode_to_ksiginfo(u_long ucode); -struct evcnt fpevent_use; -struct evcnt fpevent_reuse; - /* * Initialize the trap vectors for the current processor. */ @@ -360,8 +357,7 @@ break; case ALPHA_IF_CODE_FEN: - alpha_enable_fp(l, 0); - alpha_pal_wrfen(0); + fpu_load(); goto out; default: @@ -563,71 +559,6 @@ } /* - * Set the float-point enable for the current process, and return - * the FPU context to the named process. If check == 0, it is an - * error for the named process to already be fpcurlwp. - */ -void -alpha_enable_fp(struct lwp *l, int check) -{ -#if defined(MULTIPROCESSOR) - int s; -#endif - struct cpu_info *ci = curcpu(); - struct pcb *pcb; - - if (check && ci->ci_fpcurlwp == l) { - alpha_pal_wrfen(1); - return; - } - if (ci->ci_fpcurlwp == l) - panic("trap: fp disabled for fpcurlwp == %p", l); - - if (ci->ci_fpcurlwp != NULL) - fpusave_cpu(ci, 1); - - KDASSERT(ci->ci_fpcurlwp == NULL); - - pcb = lwp_getpcb(l); -#if defined(MULTIPROCESSOR) - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 1); -#else - KDASSERT(pcb->pcb_fpcpu == NULL); -#endif - -#if defined(MULTIPROCESSOR) - s = splhigh(); /* block IPIs */ -#endif - FPCPU_LOCK(pcb); - - pcb->pcb_fpcpu = ci; - ci->ci_fpcurlwp = l; - - FPCPU_UNLOCK(pcb); -#if defined(MULTIPROCESSOR) - splx(s); -#endif - - /* - * Instrument FP usage -- if a process had not previously - * used FP, mark it as having used FP for the first time, - * and count this event. - * - * If a process has used FP, count a "used FP, and took - * a trap to use it again" event. - */ - if ((l->l_md.md_flags & MDP_FPUSED) == 0) { - atomic_inc_ulong(&fpevent_use.ev_count); - l->l_md.md_flags |= MDP_FPUSED; - } else - atomic_inc_ulong(&fpevent_reuse.ev_count); - - alpha_pal_wrfen(1); - restorefpstate(&pcb->pcb_fp); -} - -/* * Process an asynchronous software trap. * This is relatively easy. */ @@ -687,10 +618,6 @@ #define frp(l, reg) \ (&pcb->pcb_fp.fpr_regs[(reg)]) -#define dump_fp_regs(pcb) \ - if (pcb->pcb_fpcpu != NULL) \ - fpusave_proc(l, 1) - #define unaligned_load(storage, ptrf, mod) \ if (copyin((void *)va, &(storage), sizeof (storage)) != 0) \ break; \ @@ -714,14 +641,14 @@ unaligned_store(storage, irp, ) #define unaligned_load_floating(storage, mod) do { \ - struct pcb *pcb = lwp_getpcb(l); \ - dump_fp_regs(pcb); \ + struct pcb * const pcb = lwp_getpcb(l); \ + fpu_save(); \ unaligned_load(storage, frp, mod) \ } while (/*CONSTCOND*/0) #define unaligned_store_floating(storage, mod) do { \ - struct pcb *pcb = lwp_getpcb(l); \ - dump_fp_regs(pcb); \ + struct pcb * const pcb = lwp_getpcb(l); \ + fpu_save(); \ unaligned_store(storage, frp, mod) \ } while (/*CONSTCOND*/0) Index: src/sys/arch/alpha/alpha/vm_machdep.c diff -u src/sys/arch/alpha/alpha/vm_machdep.c:1.106 src/sys/arch/alpha/alpha/vm_machdep.c:1.107 --- src/sys/arch/alpha/alpha/vm_machdep.c:1.106 Tue May 24 20:26:34 2011 +++ src/sys/arch/alpha/alpha/vm_machdep.c Tue Jun 7 00:48:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: vm_machdep.c,v 1.106 2011/05/24 20:26:34 rmind Exp $ */ +/* $NetBSD: vm_machdep.c,v 1.107 2011/06/07 00:48:30 matt 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: vm_machdep.c,v 1.106 2011/05/24 20:26:34 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.107 2011/06/07 00:48:30 matt Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -50,12 +50,7 @@ void cpu_lwp_free(struct lwp *l, int proc) { - struct pcb *pcb = lwp_getpcb(l); - - if (pcb->pcb_fpcpu != NULL) - fpusave_proc(l, 0); - - mutex_destroy(&pcb->pcb_fpcpu_lock); + (void) l; } void @@ -93,7 +88,7 @@ pcb2 = lwp_getpcb(l2); l2->l_md.md_tf = l1->l_md.md_tf; - l2->l_md.md_flags = l1->l_md.md_flags & (MDP_FPUSED | MDP_FP_C); + l2->l_md.md_flags = l1->l_md.md_flags & (MDLWP_FPUSED | MDLWP_FP_C); l2->l_md.md_astpending = 0; /* @@ -103,15 +98,9 @@ l2->l_md.md_pcbpaddr = (void *)vtophys((vaddr_t)pcb2); /* - * Copy floating point state from the FP chip to the PCB - * if this process has state stored there. - */ - if (pcb1->pcb_fpcpu != NULL) - fpusave_proc(l1, 1); - - /* * Copy pcb and user stack pointer from proc p1 to p2. * If specificed, give the child a different stack. + * Floating point state from the FP chip has already been saved. */ *pcb2 = *pcb1; if (stack != NULL) @@ -119,8 +108,6 @@ else pcb2->pcb_hw.apcb_usp = alpha_pal_rdusp(); - mutex_init(&pcb2->pcb_fpcpu_lock, MUTEX_DEFAULT, IPL_HIGH); - /* * Arrange for a non-local goto when the new process * is started, to resume here, returning nonzero from setjmp. Index: src/sys/arch/alpha/include/alpha.h diff -u src/sys/arch/alpha/include/alpha.h:1.25 src/sys/arch/alpha/include/alpha.h:1.26 --- src/sys/arch/alpha/include/alpha.h:1.25 Tue Feb 8 20:20:07 2011 +++ src/sys/arch/alpha/include/alpha.h Tue Jun 7 00:48:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: alpha.h,v 1.25 2011/02/08 20:20:07 rmind Exp $ */ +/* $NetBSD: alpha.h,v 1.26 2011/06/07 00:48:31 matt Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -60,6 +60,8 @@ #include <machine/bus.h> #include <machine/stdarg.h> +#include <sys/pcu.h> + struct pcb; struct lwp; struct reg; @@ -107,8 +109,29 @@ void enable_nsio_ide(bus_space_tag_t); char * dot_conv(unsigned long); -void fpusave_cpu(struct cpu_info *, int); -void fpusave_proc(struct lwp *, int); +extern const pcu_ops_t fpu_ops; + +void fpu_state_load(struct lwp *, bool); +void fpu_state_save(struct lwp *); +void fpu_state_release(struct lwp *); + +static inline void +fpu_load(void) +{ + pcu_load(&fpu_ops); +} + +static inline void +fpu_save(void) +{ + pcu_save(&fpu_ops); +} + +static inline void +fpu_discard(void) +{ + pcu_discard(&fpu_ops); +} void alpha_patch(bool); @@ -139,7 +162,6 @@ u_int64_t alpha_read_fp_c(struct lwp *); void alpha_write_fp_c(struct lwp *, u_int64_t); -void alpha_enable_fp(struct lwp *, int); int alpha_fp_complete(u_long, u_long, struct lwp *, u_int64_t *); /* Security sensitive rate limiting printf */ Index: src/sys/arch/alpha/include/intr.h diff -u src/sys/arch/alpha/include/intr.h:1.68 src/sys/arch/alpha/include/intr.h:1.69 --- src/sys/arch/alpha/include/intr.h:1.68 Tue Jun 22 18:29:02 2010 +++ src/sys/arch/alpha/include/intr.h Tue Jun 7 00:48:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.68 2010/06/22 18:29:02 rmind Exp $ */ +/* $NetBSD: intr.h,v 1.69 2011/06/07 00:48:31 matt Exp $ */ /*- * Copyright (c) 2000, 2001, 2002 The NetBSD Foundation, Inc. @@ -162,12 +162,10 @@ #define ALPHA_IPI_SHOOTDOWN (1UL << 2) #define ALPHA_IPI_IMB (1UL << 3) #define ALPHA_IPI_AST (1UL << 4) -#define ALPHA_IPI_SYNCH_FPU (1UL << 5) -#define ALPHA_IPI_DISCARD_FPU (1UL << 6) -#define ALPHA_IPI_PAUSE (1UL << 7) -#define ALPHA_IPI_XCALL (1UL << 8) +#define ALPHA_IPI_PAUSE (1UL << 5) +#define ALPHA_IPI_XCALL (1UL << 6) -#define ALPHA_NIPIS 9 /* must not exceed 64 */ +#define ALPHA_NIPIS 7 /* must not exceed 64 */ struct cpu_info; struct trapframe; Index: src/sys/arch/alpha/include/pcb.h diff -u src/sys/arch/alpha/include/pcb.h:1.19 src/sys/arch/alpha/include/pcb.h:1.20 --- src/sys/arch/alpha/include/pcb.h:1.19 Tue May 24 20:26:35 2011 +++ src/sys/arch/alpha/include/pcb.h Tue Jun 7 00:48:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pcb.h,v 1.19 2011/05/24 20:26:35 rmind Exp $ */ +/* $NetBSD: pcb.h,v 1.20 2011/06/07 00:48:31 matt Exp $ */ /* * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. @@ -60,8 +60,6 @@ struct fpreg pcb_fp; /* FP registers [SW] */ unsigned long pcb_onfault; /* for copy faults [SW] */ unsigned long pcb_accessaddr; /* for [fs]uswintr [SW] */ - struct cpu_info * volatile pcb_fpcpu; /* CPU with our FP state[SW] */ - kmutex_t pcb_fpcpu_lock; /* lock on fpcpu [SW] */ }; #define FPCPU_LOCK(pcb) mutex_enter(&(pcb)->pcb_fpcpu_lock) Index: src/sys/arch/alpha/include/proc.h diff -u src/sys/arch/alpha/include/proc.h:1.19 src/sys/arch/alpha/include/proc.h:1.20 --- src/sys/arch/alpha/include/proc.h:1.19 Fri Jan 14 02:06:22 2011 +++ src/sys/arch/alpha/include/proc.h Tue Jun 7 00:48:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: proc.h,v 1.19 2011/01/14 02:06:22 rmind Exp $ */ +/* $NetBSD: proc.h,v 1.20 2011/06/07 00:48:31 matt Exp $ */ /* * Copyright (c) 1994, 1995 Carnegie-Mellon University. @@ -37,31 +37,33 @@ * Machine-dependent part of the lwp struct for the Alpha. */ struct mdlwp { - u_long md_flags; - struct trapframe *md_tf; /* trap/syscall registers */ + u_long md_flags; /* see below */ + struct trapframe *md_tf; /* trap/syscall registers */ struct pcb *md_pcbpaddr; /* phys addr of the pcb */ - volatile int md_astpending; /* AST pending for this process */ + volatile int md_astpending; /* AST pending for this thread */ }; + /* * md_flags usage * -------------- - * MDP_FPUSED + * MDLWP_FPUSED * A largely unused bit indicating the presence of FPU history. * Cleared on exec. Set but not used by the fpu context switcher * itself. * - * MDP_FP_C + * MDLWP_FP_C * The architected FP Control word. It should forever begin at bit 1, * as the bits are AARM specified and this way it doesn't need to be * shifted. * * Until C99 there was never an IEEE 754 API, making most of the * standard useless. Because of overlapping AARM, OSF/1, NetBSD, and - * C99 API's, the use of the MDP_FP_C bits is defined variously in + * C99 API's, the use of the MDLWP_FP_C bits is defined variously in * ieeefp.h and fpu.h. */ -#define MDP_FPUSED 0x00000001 /* Process used the FPU */ -#define MDP_FP_C 0x007ffffe /* Extended FP_C Quadword bits */ +#define MDLWP_FPUSED 0x00000001 /* LWP used the FPU */ +#define MDLWP_FP_C 0x007ffffe /* Extended FP_C Quadword bits */ +#define MDLWP_FPACTIVE __BIT(63) /* FPU is active on LWP's PCU CPU */ /* * Machine-dependent part of the proc struct for the Alpha. @@ -72,5 +74,10 @@ void (*md_syscall)(struct lwp *, u_int64_t, struct trapframe *); }; +#ifdef _KERNEL +#define fpu_used_p(l) (((l)->l_md.md_flags & MDLWP_FPUSED) != 0) +#define fpu_mark_used(l) ((void)((l)->l_md.md_flags |= MDLWP_FPUSED)) +#endif + #endif /* !_ALPHA_PROC_H_ */ Index: src/sys/arch/alpha/include/types.h diff -u src/sys/arch/alpha/include/types.h:1.45 src/sys/arch/alpha/include/types.h:1.46 --- src/sys/arch/alpha/include/types.h:1.45 Thu Mar 31 15:30:31 2011 +++ src/sys/arch/alpha/include/types.h Tue Jun 7 00:48:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: types.h,v 1.45 2011/03/31 15:30:31 skrll Exp $ */ +/* $NetBSD: types.h,v 1.46 2011/06/07 00:48:31 matt Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -84,4 +84,9 @@ #define __HAVE_RAS #endif +#if defined(_KERNEL) || defined(_KMEMUSER) +#define PCU_FPU 0 /* FPU */ +#define PCU_UNIT_COUNT 1 +#endif + #endif /* _MACHTYPES_H_ */ Index: src/sys/arch/mips/mips/mips_machdep.c diff -u src/sys/arch/mips/mips/mips_machdep.c:1.240 src/sys/arch/mips/mips/mips_machdep.c:1.241 --- src/sys/arch/mips/mips/mips_machdep.c:1.240 Fri Apr 29 22:04:42 2011 +++ src/sys/arch/mips/mips/mips_machdep.c Tue Jun 7 00:48:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: mips_machdep.c,v 1.240 2011/04/29 22:04:42 matt Exp $ */ +/* $NetBSD: mips_machdep.c,v 1.241 2011/06/07 00:48:31 matt Exp $ */ /* * Copyright 2002 Wasabi Systems, Inc. @@ -112,7 +112,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.240 2011/04/29 22:04:42 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.241 2011/06/07 00:48:31 matt Exp $"); #define __INTR_PRIVATE #include "opt_cputype.h" @@ -1498,8 +1498,6 @@ tf->tf_regs[_R_A2] = 0; tf->tf_regs[_R_A3] = p->p_psstrp; - fpu_discard(); - memset(&pcb->pcb_fpregs, 0, sizeof(struct fpreg)); l->l_md.md_ss_addr = 0; } Index: src/sys/arch/powerpc/powerpc/fpu.c diff -u src/sys/arch/powerpc/powerpc/fpu.c:1.29 src/sys/arch/powerpc/powerpc/fpu.c:1.30 --- src/sys/arch/powerpc/powerpc/fpu.c:1.29 Mon May 2 02:01:33 2011 +++ src/sys/arch/powerpc/powerpc/fpu.c Tue Jun 7 00:48:32 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: fpu.c,v 1.29 2011/05/02 02:01:33 matt Exp $ */ +/* $NetBSD: fpu.c,v 1.30 2011/06/07 00:48:32 matt Exp $ */ /* * Copyright (C) 1996 Wolfgang Solfrank. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.29 2011/05/02 02:01:33 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.30 2011/06/07 00:48:32 matt Exp $"); #include "opt_multiprocessor.h" @@ -80,6 +80,10 @@ { struct pcb * const pcb = lwp_getpcb(l); + if (__predict_false(!used)) { + memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu)); + } + const register_t msr = mfmsr(); mtmsr((msr & ~PSL_EE) | PSL_FP); __asm volatile ("isync"); Index: src/sys/arch/powerpc/powerpc/powerpc_machdep.c diff -u src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.49 src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.50 --- src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.49 Sun Jun 5 16:52:26 2011 +++ src/sys/arch/powerpc/powerpc/powerpc_machdep.c Tue Jun 7 00:48:32 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: powerpc_machdep.c,v 1.49 2011/06/05 16:52:26 matt Exp $ */ +/* $NetBSD: powerpc_machdep.c,v 1.50 2011/06/07 00:48:32 matt Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.49 2011/06/05 16:52:26 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.50 2011/06/07 00:48:32 matt Exp $"); #include "opt_altivec.h" #include "opt_modular.h" @@ -127,10 +127,6 @@ tf->tf_vrsave = 0; #endif pcb->pcb_flags = PSL_FE_DFLT; - memset(&pcb->pcb_fpu, 0, sizeof(&pcb->pcb_fpu)); -#if defined(ALTIVEC) || defined(PPC_SAVE_SPE) - memset(&pcb->pcb_vr, 0, sizeof(&pcb->pcb_vr)); -#endif } /*