From owner-freebsd-bugs@FreeBSD.ORG Sat Jun 3 19:00:51 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C99D616A501 for ; Sat, 3 Jun 2006 19:00:51 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id C0A3843D58 for ; Sat, 3 Jun 2006 19:00:36 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k53J0aTN057296 for ; Sat, 3 Jun 2006 19:00:36 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k53J0asj057293; Sat, 3 Jun 2006 19:00:36 GMT (envelope-from gnats) Resent-Date: Sat, 3 Jun 2006 19:00:36 GMT Resent-Message-Id: <200606031900.k53J0asj057293@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Rostislav Krasny Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AC77C16A41F for ; Sat, 3 Jun 2006 18:53:52 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6AE0943D45 for ; Sat, 3 Jun 2006 18:53:52 +0000 (GMT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k53Irq1d015999 for ; Sat, 3 Jun 2006 18:53:52 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id k53IrqiA015998; Sat, 3 Jun 2006 18:53:52 GMT (envelope-from nobody) Message-Id: <200606031853.k53IrqiA015998@www.freebsd.org> Date: Sat, 3 Jun 2006 18:53:52 GMT From: Rostislav Krasny To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-2.3 Cc: Subject: kern/98460: [PATCH] fpu_clean_state() cannot be disabled for not AMD processors, those are not vulnerable to FreeBSD-SA-06:14.fpu X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 03 Jun 2006 19:00:52 -0000 >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 __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 #include #include @@ -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: