Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/x86 Fix MXCSR_MASK, it needs to be detected dynamic...
details: https://anonhg.NetBSD.org/src/rev/4bdbed8292c8
branches: trunk
changeset: 357255:4bdbed8292c8
user: maxv <maxv%NetBSD.org@localhost>
date: Fri Nov 03 07:14:24 2017 +0000
description:
Fix MXCSR_MASK, it needs to be detected dynamically, otherwise when masking
MXCSR we are losing some features (eg DAZ).
diffstat:
sys/arch/x86/include/fpu.h | 3 ++-
sys/arch/x86/x86/fpu.c | 43 ++++++++++++++++++++++++++++++++++++++-----
sys/arch/x86/x86/identcpu.c | 6 ++++--
3 files changed, 44 insertions(+), 8 deletions(-)
diffs (136 lines):
diff -r eaf542c63a0c -r 4bdbed8292c8 sys/arch/x86/include/fpu.h
--- a/sys/arch/x86/include/fpu.h Fri Nov 03 05:31:38 2017 +0000
+++ b/sys/arch/x86/include/fpu.h Fri Nov 03 07:14:24 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.h,v 1.6 2014/02/25 22:16:52 dsl Exp $ */
+/* $NetBSD: fpu.h,v 1.7 2017/11/03 07:14:24 maxv Exp $ */
#ifndef _X86_FPU_H_
#define _X86_FPU_H_
@@ -12,6 +12,7 @@
struct trapframe;
void fpuinit(struct cpu_info *);
+void fpuinit_mxcsr_mask(void);
void fpusave_lwp(struct lwp *, bool);
void fpusave_cpu(bool);
diff -r eaf542c63a0c -r 4bdbed8292c8 sys/arch/x86/x86/fpu.c
--- a/sys/arch/x86/x86/fpu.c Fri Nov 03 05:31:38 2017 +0000
+++ b/sys/arch/x86/x86/fpu.c Fri Nov 03 07:14:24 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.c,v 1.20 2017/10/31 18:23:29 maxv Exp $ */
+/* $NetBSD: fpu.c,v 1.21 2017/11/03 07:14:24 maxv Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc. All
@@ -96,7 +96,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.20 2017/10/31 18:23:29 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.21 2017/11/03 07:14:24 maxv Exp $");
#include "opt_multiprocessor.h"
@@ -125,6 +125,8 @@
#define stts() HYPERVISOR_fpu_taskswitch(1)
#endif
+static uint32_t x86_fpu_mxcsr_mask __read_mostly = 0;
+
static inline union savefpu *
process_fpframe(struct lwp *lwp)
{
@@ -226,6 +228,37 @@
}
/*
+ * Get the value of MXCSR_MASK supported by the CPU.
+ */
+void
+fpuinit_mxcsr_mask(void)
+{
+ union savefpu fpusave __aligned(16);
+ u_long cr0, psl;
+
+ memset(&fpusave, 0, sizeof(fpusave));
+
+ /* Disable interrupts, and enable FPU */
+ psl = x86_read_psl();
+ x86_disable_intr();
+ cr0 = rcr0();
+ lcr0(cr0 & ~(CR0_EM|CR0_TS));
+
+ /* Fill in the FPU area */
+ fxsave(&fpusave);
+
+ /* Restore previous state */
+ lcr0(cr0);
+ x86_write_psl(psl);
+
+ if (fpusave.sv_xmm.fx_mxcsr_mask == 0) {
+ x86_fpu_mxcsr_mask = __INITIAL_MXCSR_MASK__;
+ } else {
+ x86_fpu_mxcsr_mask = fpusave.sv_xmm.fx_mxcsr_mask;
+ }
+}
+
+/*
* This is a synchronous trap on either an x87 instruction (due to an
* unmasked error on the previous x87 instruction) or on an SSE/SSE2 etc
* instruction due to an error on the instruction itself.
@@ -515,7 +548,7 @@
if (i386_use_fxsave) {
memset(&fpu_save->sv_xmm, 0, x86_fpu_save_size);
fpu_save->sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
- fpu_save->sv_xmm.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
+ fpu_save->sv_xmm.fx_mxcsr_mask = x86_fpu_mxcsr_mask;
fpu_save->sv_xmm.fx_cw = x87_cw;
} else {
memset(&fpu_save->sv_87, 0, x86_fpu_save_size);
@@ -537,7 +570,7 @@
*/
if (i386_use_fxsave) {
fpu_save->sv_xmm.fx_mxcsr = __INITIAL_MXCSR__;
- fpu_save->sv_xmm.fx_mxcsr_mask = __INITIAL_MXCSR_MASK__;
+ fpu_save->sv_xmm.fx_mxcsr_mask = x86_fpu_mxcsr_mask;
fpu_save->sv_xmm.fx_tw = 0;
fpu_save->sv_xmm.fx_cw = pcb->pcb_fpu_dflt_cw;
} else {
@@ -576,7 +609,7 @@
/*
* Invalid bits in mxcsr or mxcsr_mask will cause faults.
*/
- fpu_save->sv_xmm.fx_mxcsr_mask &= __INITIAL_MXCSR_MASK__;
+ fpu_save->sv_xmm.fx_mxcsr_mask &= x86_fpu_mxcsr_mask;
fpu_save->sv_xmm.fx_mxcsr &= fpu_save->sv_xmm.fx_mxcsr_mask;
/*
diff -r eaf542c63a0c -r 4bdbed8292c8 sys/arch/x86/x86/identcpu.c
--- a/sys/arch/x86/x86/identcpu.c Fri Nov 03 05:31:38 2017 +0000
+++ b/sys/arch/x86/x86/identcpu.c Fri Nov 03 07:14:24 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: identcpu.c,v 1.61 2017/10/31 11:37:05 maxv Exp $ */
+/* $NetBSD: identcpu.c,v 1.62 2017/11/03 07:14:24 maxv Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.61 2017/10/31 11:37:05 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.62 2017/11/03 07:14:24 maxv Exp $");
#include "opt_xen.h"
@@ -752,6 +752,8 @@
x86_fpu_save = FPU_SAVE_FXSAVE;
+ fpuinit_mxcsr_mask();
+
/* See if xsave (for AVX) is supported */
if ((ci->ci_feat_val[1] & CPUID2_XSAVE) == 0)
return;
Home |
Main Index |
Thread Index |
Old Index