Author: jhb
Date: Mon Jul  9 20:55:39 2012
New Revision: 238311
URL: http://svn.freebsd.org/changeset/base/238311

Log:
  Add a clts() wrapper around the 'clts' instruction to <machine/cpufunc.h>
  on x86 and use that to implement stop_emulating() in the fpu/npx code.
  Reimplement start_emulating() in the non-XEN case by using load_cr0() and
  rcr0() instead of the 'lmsw' and 'smsw' instructions.  Intel explicitly
  discourages the use of 'lmsw' and 'smsw' on 80386 and later processors in
  the description of these instructions in Volume 2 of the ADM.
  
  Reviewed by:  kib
  MFC after:    1 month

Modified:
  head/sys/amd64/amd64/fpu.c
  head/sys/amd64/include/cpufunc.h
  head/sys/i386/include/cpufunc.h
  head/sys/i386/isa/npx.c

Modified: head/sys/amd64/amd64/fpu.c
==============================================================================
--- head/sys/amd64/amd64/fpu.c  Mon Jul  9 20:42:08 2012        (r238310)
+++ head/sys/amd64/amd64/fpu.c  Mon Jul  9 20:55:39 2012        (r238311)
@@ -73,10 +73,6 @@ __FBSDID("$FreeBSD$");
 #define        fxrstor(addr)           __asm __volatile("fxrstor %0" : : "m" 
(*(addr)))
 #define        fxsave(addr)            __asm __volatile("fxsave %0" : "=m" 
(*(addr)))
 #define        ldmxcsr(csr)            __asm __volatile("ldmxcsr %0" : : "m" 
(csr))
-#define        start_emulating()       __asm __volatile( \
-                                   "smsw %%ax; orb %0,%%al; lmsw %%ax" \
-                                   : : "n" (CR0_TS) : "ax")
-#define        stop_emulating()        __asm __volatile("clts")
 
 static __inline void
 xrstor(char *addr, uint64_t mask)
@@ -109,13 +105,14 @@ void      fnstsw(caddr_t addr);
 void   fxsave(caddr_t addr);
 void   fxrstor(caddr_t addr);
 void   ldmxcsr(u_int csr);
-void   start_emulating(void);
-void   stop_emulating(void);
 void   xrstor(char *addr, uint64_t mask);
 void   xsave(char *addr, uint64_t mask);
 
 #endif /* __GNUCLIKE_ASM && !lint */
 
+#define        start_emulating()       load_cr0(rcr0() | CR0_TS)
+#define        stop_emulating()        clts()
+
 #define GET_FPU_CW(thread) ((thread)->td_pcb->pcb_save->sv_env.en_cw)
 #define GET_FPU_SW(thread) ((thread)->td_pcb->pcb_save->sv_env.en_sw)
 

Modified: head/sys/amd64/include/cpufunc.h
==============================================================================
--- head/sys/amd64/include/cpufunc.h    Mon Jul  9 20:42:08 2012        
(r238310)
+++ head/sys/amd64/include/cpufunc.h    Mon Jul  9 20:55:39 2012        
(r238311)
@@ -107,6 +107,13 @@ clflush(u_long addr)
 }
 
 static __inline void
+clts(void)
+{
+
+       __asm __volatile("clts");
+}
+
+static __inline void
 disable_intr(void)
 {
        __asm __volatile("cli" : : : "memory");
@@ -702,6 +709,9 @@ intr_restore(register_t rflags)
 int    breakpoint(void);
 u_int  bsfl(u_int mask);
 u_int  bsrl(u_int mask);
+void   clflush(u_long addr);
+void   clts(void);
+void   cpuid_count(u_int ax, u_int cx, u_int *p);
 void   disable_intr(void);
 void   do_cpuid(u_int ax, u_int *p);
 void   enable_intr(void);

Modified: head/sys/i386/include/cpufunc.h
==============================================================================
--- head/sys/i386/include/cpufunc.h     Mon Jul  9 20:42:08 2012        
(r238310)
+++ head/sys/i386/include/cpufunc.h     Mon Jul  9 20:55:39 2012        
(r238311)
@@ -97,6 +97,13 @@ clflush(u_long addr)
 }
 
 static __inline void
+clts(void)
+{
+
+       __asm __volatile("clts");
+}
+
+static __inline void
 disable_intr(void)
 {
 #ifdef XEN
@@ -688,6 +695,9 @@ intr_restore(register_t eflags)
 int    breakpoint(void);
 u_int  bsfl(u_int mask);
 u_int  bsrl(u_int mask);
+void   clflush(u_long addr);
+void   clts(void);
+void   cpuid_count(u_int ax, u_int cx, u_int *p);
 void   disable_intr(void);
 void   do_cpuid(u_int ax, u_int *p);
 void   enable_intr(void);

Modified: head/sys/i386/isa/npx.c
==============================================================================
--- head/sys/i386/isa/npx.c     Mon Jul  9 20:42:08 2012        (r238310)
+++ head/sys/i386/isa/npx.c     Mon Jul  9 20:55:39 2012        (r238311)
@@ -100,15 +100,6 @@ __FBSDID("$FreeBSD$");
 #define        fxrstor(addr)           __asm __volatile("fxrstor %0" : : "m" 
(*(addr)))
 #define        fxsave(addr)            __asm __volatile("fxsave %0" : "=m" 
(*(addr)))
 #endif
-#ifdef XEN
-#define        start_emulating()       (HYPERVISOR_fpu_taskswitch(1))
-#define        stop_emulating()        (HYPERVISOR_fpu_taskswitch(0))
-#else
-#define        start_emulating()       __asm __volatile( \
-                                   "smsw %%ax; orb %0,%%al; lmsw %%ax" \
-                                   : : "n" (CR0_TS) : "ax")
-#define        stop_emulating()        __asm __volatile("clts")
-#endif
 #else  /* !(__GNUCLIKE_ASM && !lint) */
 
 void   fldcw(u_short cw);
@@ -123,11 +114,17 @@ void      frstor(caddr_t addr);
 void   fxsave(caddr_t addr);
 void   fxrstor(caddr_t addr);
 #endif
-void   start_emulating(void);
-void   stop_emulating(void);
 
 #endif /* __GNUCLIKE_ASM && !lint */
 
+#ifdef XEN
+#define        start_emulating()       (HYPERVISOR_fpu_taskswitch(1))
+#define        stop_emulating()        (HYPERVISOR_fpu_taskswitch(0))
+#else
+#define        start_emulating()       load_cr0(rcr0() | CR0_TS)
+#define        stop_emulating()        clts()
+#endif
+
 #ifdef CPU_ENABLE_SSE
 #define GET_FPU_CW(thread) \
        (cpu_fxsr ? \
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to