Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Feb 2019 13:53:11 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r344118 - head/sys/i386/include
Message-ID:  <201902141353.x1EDrB0Z076223@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Feb 14 13:53:11 2019
New Revision: 344118
URL: https://svnweb.freebsd.org/changeset/base/344118

Log:
  Provide userspace versions of do_cpuid() and cpuid_count() on i386.
  
  Some older compilers, when generating PIC code, cannot handle inline
  asm that clobbers %ebx (because %ebx is used as the GOT offset
  register).  Userspace versions avoid clobbering %ebx by saving it to
  stack before executing the CPUID instruction.
  
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/i386/include/cpufunc.h

Modified: head/sys/i386/include/cpufunc.h
==============================================================================
--- head/sys/i386/include/cpufunc.h	Thu Feb 14 09:50:59 2019	(r344117)
+++ head/sys/i386/include/cpufunc.h	Thu Feb 14 13:53:11 2019	(r344118)
@@ -108,21 +108,47 @@ disable_intr(void)
 	__asm __volatile("cli" : : : "memory");
 }
 
+#ifdef _KERNEL
 static __inline void
 do_cpuid(u_int ax, u_int *p)
 {
 	__asm __volatile("cpuid"
-			 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
-			 :  "0" (ax));
+	    : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+	    :  "0" (ax));
 }
 
 static __inline void
 cpuid_count(u_int ax, u_int cx, u_int *p)
 {
 	__asm __volatile("cpuid"
-			 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
-			 :  "0" (ax), "c" (cx));
+	    : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+	    :  "0" (ax), "c" (cx));
 }
+#else
+static __inline void
+do_cpuid(u_int ax, u_int *p)
+{
+	__asm __volatile(
+	    "pushl\t%%ebx\n\t"
+	    "cpuid\n\t"
+	    "movl\t%%ebx,%1\n\t"
+	    "popl\t%%ebx"
+	    : "=a" (p[0]), "=DS" (p[1]), "=c" (p[2]), "=d" (p[3])
+	    :  "0" (ax));
+}
+
+static __inline void
+cpuid_count(u_int ax, u_int cx, u_int *p)
+{
+	__asm __volatile(
+	    "pushl\t%%ebx\n\t"
+	    "cpuid\n\t"
+	    "movl\t%%ebx,%1\n\t"
+	    "popl\t%%ebx"
+	    : "=a" (p[0]), "=DS" (p[1]), "=c" (p[2]), "=d" (p[3])
+	    :  "0" (ax), "c" (cx));
+}
+#endif
 
 static __inline void
 enable_intr(void)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902141353.x1EDrB0Z076223>