kern/98460 : [kernel] [patch] fpu_clean_state() cannot be disabled for not AMD processors, those are not vulnerable to FreeBSD-SA-06:14.fpu

Bruce Evans bde at zeta.org.au
Sun Jun 4 15:30:57 PDT 2006


The following reply was made to PR kern/98460; it has been noted by GNATS.

From: Bruce Evans <bde at zeta.org.au>
To: Rostislav Krasny <rosti.bsd at gmail.com>
Cc: freebsd-gnats-submit at FreeBSD.org
Subject: Re: kern/98460 : [kernel] [patch] fpu_clean_state() cannot be disabled
 for not AMD processors, those are not vulnerable to FreeBSD-SA-06:14.fpu
Date: Mon, 5 Jun 2006 08:25:06 +1000 (EST)

 On Sun, 4 Jun 2006, Rostislav Krasny wrote:
 
 > On Sun, 4 Jun 2006, Bruce Evans wrote:
 > > The configuration should be dynamic and automatic, so that it doesn't
 > > take changes to zillions of configuration files to implement and
 > > document an option that almost no one will know to set.  I think there
 > > is a simple feature test for the AMD misfeature.
 >
 > David Xu had proposed something like that. But from Colin Percival's
 > reply I understood that it is hard to be done effectively. See their
 > discussion by the first URL in this PR.
 
 I don't see how it can be hard.  Perhaps it is too CPU-dependent for
 tests based on cpuid to be easy or future-proof, but a runtime test
 in the probe would be easy.  Here is a userland version.  It gives the
 expected result on the following systems P2(Celeron) (mine), P3
 (freefall), P4(Xeon) (nosedive), AthlonXP (mine) and Opteron (sledge).
 It would crash on systems without FXSR.  To be complete, the userland
 version should repeat the test many times to reduce the chance of a
 misprobe due to broken context switching clobbering the pointer
 underneath it.  The kernel version can check for FXSR more easily and
 can just prevent context switching.
 
 %%%
 #include <sys/types.h>
 
 #ifdef __amd64__
 #include <machine/fpu.h>
 
 static struct savefpu xmmstate;
 #define	en_fip	en_rip
 #else
 #include <machine/npx.h>
 
 static struct savexmm xmmstate;
 #endif
 
 int
 main(void)
 {
  	/* Set up a fairly clean state with a zero last-instruction pointer. */
  	asm("fninit");
 
  	/* Set the last-instruction pointer mod 2^32 to nonzero. */
  	asm(".align 2,0x90; nop; fnop");
 
  	/* Try to see what the last-instruction pointer got changed to. */
  	asm("fxsave xmmstate");
 
  	/* Have dubious AMD optimizations iff the change didn't get saved. */
  	if (xmmstate.sv_env.en_fip == 0) {
  		printf("cpu_fxsr |= CPU_FXSR_NEEDCLEAN;\n");
  		return (1);
  	} else {
  		printf("cpu_fxsr &= ~CPU_FXSR_NEEDCLEAN;\n");
  		return (0);
  	}
 }
 %%%
 
 Bruce


More information about the freebsd-bugs mailing list