kern/98460: [PATCH] fpu_clean_state() cannot be disabled for not
AMD processors, those are not vulnerable to FreeBSD-SA-06:14.fpu
Rostislav Krasny
rosti.bsd at FreeBSD.org
Sat Jun 3 12:00:52 PDT 2006
>Number: 98460
>Category: kern
>Synopsis: [PATCH] fpu_clean_state() cannot be disabled for not AMD processors, those are not vulnerable to FreeBSD-SA-06:14.fpu
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Sat Jun 03 19:00:35 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Rostislav Krasny
>Release: 6.1-STABLE
>Organization:
>Environment:
>Description:
When FreeBSD is running on any non AMD processor an fpu_clean_state() function
adds unneeded operations to a context switch. My patch makes it possible
to disable the fpu_clean_state() by rebuilding a kernel with
"options CPU_FXSAVE_NO_LEAK".
Colin Percival has nothing against my idea in general:
http://lists.freebsd.org/pipermail/freebsd-current/2006-May/062683.html
and David Xu as well:
http://lists.freebsd.org/pipermail/freebsd-current/2006-May/063206.html
Following message is a beginning of that thread:
http://lists.freebsd.org/pipermail/freebsd-current/2006-April/062662.html
>How-To-Repeat:
You can use following command to check how your kernel has been builded:
objdump -x /boot/kernel/kernel | grep fpu_clean_state
>Fix:
diff -ru src/sys.orig/amd64/amd64/fpu.c src/sys/amd64/amd64/fpu.c
--- src/sys.orig/amd64/amd64/fpu.c Wed Apr 19 10:00:35 2006
+++ src/sys/amd64/amd64/fpu.c Sat Jun 3 21:14:06 2006
@@ -33,6 +33,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/amd64/amd64/fpu.c,v 1.157.2.1 2006/04/19 07:00:35 cperciva Exp $");
+#include "opt_cpu.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -96,7 +98,9 @@
typedef u_char bool_t;
+#ifndef CPU_FXSAVE_NO_LEAK
static void fpu_clean_state(void);
+#endif
int hw_float = 1;
SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
@@ -409,7 +413,9 @@
PCPU_SET(fpcurthread, curthread);
pcb = PCPU_GET(curpcb);
+#ifndef CPU_FXSAVE_NO_LEAK
fpu_clean_state();
+#endif
if ((pcb->pcb_flags & PCB_FPUINITDONE) == 0) {
/*
@@ -478,7 +484,9 @@
s = intr_disable();
if (td == PCPU_GET(fpcurthread)) {
+#ifndef CPU_FXSAVE_NO_LEAK
fpu_clean_state();
+#endif
fxrstor(addr);
intr_restore(s);
} else {
@@ -488,6 +496,7 @@
curthread->td_pcb->pcb_flags |= PCB_FPUINITDONE;
}
+#ifndef CPU_FXSAVE_NO_LEAK
/*
* On AuthenticAMD processors, the fxrstor instruction does not restore
* the x87's stored last instruction pointer, last data pointer, and last
@@ -518,6 +527,7 @@
*/
__asm __volatile("ffree %%st(7); fld %0" : : "m" (dummy_variable));
}
+#endif /* !CPU_FXSAVE_NO_LEAK */
/*
* This really sucks. We want the acpi version only, but it requires
diff -ru src/sys.orig/amd64/conf/NOTES src/sys/amd64/conf/NOTES
--- src/sys.orig/amd64/conf/NOTES Sun Apr 30 20:39:43 2006
+++ src/sys/amd64/conf/NOTES Sat Jun 3 21:14:06 2006
@@ -57,6 +57,12 @@
# Options for CPU features.
#
+# CPU_FXSAVE_NO_LEAK disables security workaround of FPU registers leak by
+# FXSAVE and FXRSTOR instructions of "7th generation" and "8th generation"
+# processors manufactured by AMD. For more information read a
+# FreeBSD-SA-06:14.fpu security advisory.
+options CPU_FXSAVE_NO_LEAK
+
#
# PERFMON causes the driver for Pentium/Pentium Pro performance counters
# to be compiled. See perfmon(4) for more information.
diff -ru src/sys.orig/conf/options.amd64 src/sys/conf/options.amd64
--- src/sys.orig/conf/options.amd64 Thu Jun 30 02:23:16 2005
+++ src/sys/conf/options.amd64 Sat Jun 3 21:14:06 2006
@@ -49,6 +49,7 @@
# EOF
# -------------------------------
HAMMER opt_cpu.h
+CPU_FXSAVE_NO_LEAK opt_cpu.h
PPC_PROBE_CHIPSET opt_ppc.h
PPC_DEBUG opt_ppc.h
PSM_HOOKRESUME opt_psm.h
diff -ru src/sys.orig/conf/options.i386 src/sys/conf/options.i386
--- src/sys.orig/conf/options.i386 Sat Jul 2 23:06:42 2005
+++ src/sys/conf/options.i386 Sat Jun 3 21:14:06 2006
@@ -52,6 +52,7 @@
CPU_ELAN_XTAL opt_cpu.h
CPU_ENABLE_LONGRUN opt_cpu.h
CPU_FASTER_5X86_FPU opt_cpu.h
+CPU_FXSAVE_NO_LEAK opt_cpu.h
CPU_GEODE opt_cpu.h
CPU_I486_ON_386 opt_cpu.h
CPU_IORT opt_cpu.h
diff -ru src/sys.orig/i386/conf/NOTES src/sys/i386/conf/NOTES
--- src/sys.orig/i386/conf/NOTES Wed May 10 17:26:03 2006
+++ src/sys/i386/conf/NOTES Sat Jun 3 21:14:06 2006
@@ -118,6 +118,11 @@
#
# CPU_FASTER_5X86_FPU enables faster FPU exception handler.
#
+# CPU_FXSAVE_NO_LEAK disables security workaround of FPU registers leak by
+# FXSAVE and FXRSTOR instructions of "7th generation" and "8th generation"
+# processors manufactured by AMD. For more information read a
+# FreeBSD-SA-06:14.fpu security advisory.
+#
# CPU_GEODE is for the SC1100 Geode embedded processor. This option
# is necessary because the i8254 timecounter is toast.
#
@@ -192,6 +197,7 @@
options CPU_ELAN_XTAL=32768000
options CPU_ENABLE_LONGRUN
options CPU_FASTER_5X86_FPU
+options CPU_FXSAVE_NO_LEAK
options CPU_GEODE
options CPU_I486_ON_386
options CPU_IORT
diff -ru src/sys.orig/i386/isa/npx.c src/sys/i386/isa/npx.c
--- src/sys.orig/i386/isa/npx.c Sun Apr 30 08:15:20 2006
+++ src/sys/i386/isa/npx.c Sat Jun 3 21:14:06 2006
@@ -142,7 +142,7 @@
typedef u_char bool_t;
-#ifdef CPU_ENABLE_SSE
+#if defined(CPU_ENABLE_SSE) && !defined(CPU_FXSAVE_NO_LEAK)
static void fpu_clean_state(void);
#endif
@@ -956,7 +956,7 @@
fnsave(addr);
}
-#ifdef CPU_ENABLE_SSE
+#if defined(CPU_ENABLE_SSE) && !defined(CPU_FXSAVE_NO_LEAK)
/*
* On AuthenticAMD processors, the fxrstor instruction does not restore
* the x87's stored last instruction pointer, last data pointer, and last
@@ -987,7 +987,7 @@
*/
__asm __volatile("ffree %%st(7); fld %0" : : "m" (dummy_variable));
}
-#endif /* CPU_ENABLE_SSE */
+#endif /* CPU_ENABLE_SSE && !CPU_FXSAVE_NO_LEAK */
static void
fpurstor(addr)
@@ -996,7 +996,9 @@
#ifdef CPU_ENABLE_SSE
if (cpu_fxsr) {
+#ifndef CPU_FXSAVE_NO_LEAK
fpu_clean_state();
+#endif
fxrstor(addr);
} else
#endif
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list