Commit 4c6544f6 authored by Josh Triplett's avatar Josh Triplett Committed by Greg Kroah-Hartman

turbostat: Use GCC's CPUID functions to support PIC

commit 2b92865e upstream.

turbostat uses inline assembly to call cpuid.  On 32-bit x86, on systems
that have certain security features enabled by default that make -fPIC
the default, this causes a build error:

turbostat.c: In function ‘check_cpuid’:
turbostat.c:1906:2: error: PIC register clobbered by ‘ebx’ in ‘asm’
  asm("cpuid" : "=a" (fms), "=c" (ecx), "=d" (edx) : "a" (1) : "ebx");
  ^

GCC provides a header cpuid.h, containing a __get_cpuid function that
works with both PIC and non-PIC.  (On PIC, it saves and restores ebx
around the cpuid instruction.)  Use that instead.
Signed-off-by: default avatarJosh Triplett <josh@joshtriplett.org>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b06c0a0c
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <sched.h> #include <sched.h>
#include <cpuid.h>
#define MSR_TSC 0x10 #define MSR_TSC 0x10
#define MSR_NEHALEM_PLATFORM_INFO 0xCE #define MSR_NEHALEM_PLATFORM_INFO 0xCE
...@@ -932,7 +933,7 @@ void check_cpuid() ...@@ -932,7 +933,7 @@ void check_cpuid()
eax = ebx = ecx = edx = 0; eax = ebx = ecx = edx = 0;
asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0)); __get_cpuid(0, &max_level, &ebx, &ecx, &edx);
if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
genuine_intel = 1; genuine_intel = 1;
...@@ -941,7 +942,7 @@ void check_cpuid() ...@@ -941,7 +942,7 @@ void check_cpuid()
fprintf(stderr, "%.4s%.4s%.4s ", fprintf(stderr, "%.4s%.4s%.4s ",
(char *)&ebx, (char *)&edx, (char *)&ecx); (char *)&ebx, (char *)&edx, (char *)&ecx);
asm("cpuid" : "=a" (fms), "=c" (ecx), "=d" (edx) : "a" (1) : "ebx"); __get_cpuid(1, &fms, &ebx, &ecx, &edx);
family = (fms >> 8) & 0xf; family = (fms >> 8) & 0xf;
model = (fms >> 4) & 0xf; model = (fms >> 4) & 0xf;
stepping = fms & 0xf; stepping = fms & 0xf;
...@@ -963,7 +964,7 @@ void check_cpuid() ...@@ -963,7 +964,7 @@ void check_cpuid()
* This check is valid for both Intel and AMD. * This check is valid for both Intel and AMD.
*/ */
ebx = ecx = edx = 0; ebx = ecx = edx = 0;
asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000000)); __get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx);
if (max_level < 0x80000007) { if (max_level < 0x80000007) {
fprintf(stderr, "CPUID: no invariant TSC (max_level 0x%x)\n", max_level); fprintf(stderr, "CPUID: no invariant TSC (max_level 0x%x)\n", max_level);
...@@ -974,7 +975,7 @@ void check_cpuid() ...@@ -974,7 +975,7 @@ void check_cpuid()
* Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8 * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
* this check is valid for both Intel and AMD * this check is valid for both Intel and AMD
*/ */
asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000007)); __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
has_invariant_tsc = edx & (1 << 8); has_invariant_tsc = edx & (1 << 8);
if (!has_invariant_tsc) { if (!has_invariant_tsc) {
...@@ -987,7 +988,7 @@ void check_cpuid() ...@@ -987,7 +988,7 @@ void check_cpuid()
* this check is valid for both Intel and AMD * this check is valid for both Intel and AMD
*/ */
asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6)); __get_cpuid(0x6, &eax, &ebx, &ecx, &edx);
has_aperf = ecx & (1 << 0); has_aperf = ecx & (1 << 0);
if (!has_aperf) { if (!has_aperf) {
fprintf(stderr, "No APERF MSR\n"); fprintf(stderr, "No APERF MSR\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment