diff options
author | Josh Triplett <josh@joshtriplett.org> | 2013-08-20 20:20:14 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2014-01-18 22:34:08 -0500 |
commit | 2b92865e648ce04a39fda4f903784a5d01ecb0dc (patch) | |
tree | 258e2dae597dcb2278760c0aee97188b803ea5cf /tools | |
parent | 2e9c6bc7fb6ffc32d83bc133e4a7389125e8eb0a (diff) |
turbostat: Use GCC's CPUID functions to support PIC
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: Josh Triplett <josh@joshtriplett.org>
Cc: stable@vger.kernel.org
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index dbcbf27a4d8b..51741a1b7021 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <string.h> | 35 | #include <string.h> |
36 | #include <ctype.h> | 36 | #include <ctype.h> |
37 | #include <sched.h> | 37 | #include <sched.h> |
38 | #include <cpuid.h> | ||
38 | 39 | ||
39 | char *proc_stat = "/proc/stat"; | 40 | char *proc_stat = "/proc/stat"; |
40 | unsigned int interval_sec = 5; /* set with -i interval_sec */ | 41 | unsigned int interval_sec = 5; /* set with -i interval_sec */ |
@@ -1978,7 +1979,7 @@ void check_cpuid() | |||
1978 | 1979 | ||
1979 | eax = ebx = ecx = edx = 0; | 1980 | eax = ebx = ecx = edx = 0; |
1980 | 1981 | ||
1981 | asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0)); | 1982 | __get_cpuid(0, &max_level, &ebx, &ecx, &edx); |
1982 | 1983 | ||
1983 | if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) | 1984 | if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) |
1984 | genuine_intel = 1; | 1985 | genuine_intel = 1; |
@@ -1987,7 +1988,7 @@ void check_cpuid() | |||
1987 | fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", | 1988 | fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", |
1988 | (char *)&ebx, (char *)&edx, (char *)&ecx); | 1989 | (char *)&ebx, (char *)&edx, (char *)&ecx); |
1989 | 1990 | ||
1990 | asm("cpuid" : "=a" (fms), "=c" (ecx), "=d" (edx) : "a" (1) : "ebx"); | 1991 | __get_cpuid(1, &fms, &ebx, &ecx, &edx); |
1991 | family = (fms >> 8) & 0xf; | 1992 | family = (fms >> 8) & 0xf; |
1992 | model = (fms >> 4) & 0xf; | 1993 | model = (fms >> 4) & 0xf; |
1993 | stepping = fms & 0xf; | 1994 | stepping = fms & 0xf; |
@@ -2009,7 +2010,7 @@ void check_cpuid() | |||
2009 | * This check is valid for both Intel and AMD. | 2010 | * This check is valid for both Intel and AMD. |
2010 | */ | 2011 | */ |
2011 | ebx = ecx = edx = 0; | 2012 | ebx = ecx = edx = 0; |
2012 | asm("cpuid" : "=a" (max_level), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000000)); | 2013 | __get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx); |
2013 | 2014 | ||
2014 | if (max_level < 0x80000007) { | 2015 | if (max_level < 0x80000007) { |
2015 | fprintf(stderr, "CPUID: no invariant TSC (max_level 0x%x)\n", max_level); | 2016 | fprintf(stderr, "CPUID: no invariant TSC (max_level 0x%x)\n", max_level); |
@@ -2020,7 +2021,7 @@ void check_cpuid() | |||
2020 | * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8 | 2021 | * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8 |
2021 | * this check is valid for both Intel and AMD | 2022 | * this check is valid for both Intel and AMD |
2022 | */ | 2023 | */ |
2023 | asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000007)); | 2024 | __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx); |
2024 | has_invariant_tsc = edx & (1 << 8); | 2025 | has_invariant_tsc = edx & (1 << 8); |
2025 | 2026 | ||
2026 | if (!has_invariant_tsc) { | 2027 | if (!has_invariant_tsc) { |
@@ -2033,7 +2034,7 @@ void check_cpuid() | |||
2033 | * this check is valid for both Intel and AMD | 2034 | * this check is valid for both Intel and AMD |
2034 | */ | 2035 | */ |
2035 | 2036 | ||
2036 | asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6)); | 2037 | __get_cpuid(0x6, &eax, &ebx, &ecx, &edx); |
2037 | has_aperf = ecx & (1 << 0); | 2038 | has_aperf = ecx & (1 << 0); |
2038 | do_dts = eax & (1 << 0); | 2039 | do_dts = eax & (1 << 0); |
2039 | do_ptm = eax & (1 << 6); | 2040 | do_ptm = eax & (1 << 6); |