mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-22 17:01:14 +00:00
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>
This commit is contained in:
parent
2e9c6bc7fb
commit
2b92865e64
1 changed files with 6 additions and 5 deletions
|
@ -35,6 +35,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
#include <cpuid.h>
|
||||||
|
|
||||||
char *proc_stat = "/proc/stat";
|
char *proc_stat = "/proc/stat";
|
||||||
unsigned int interval_sec = 5; /* set with -i interval_sec */
|
unsigned int interval_sec = 5; /* set with -i interval_sec */
|
||||||
|
@ -1978,7 +1979,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;
|
||||||
|
@ -1987,7 +1988,7 @@ void check_cpuid()
|
||||||
fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
|
fprintf(stderr, "CPUID(0): %.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;
|
||||||
|
@ -2009,7 +2010,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);
|
||||||
|
@ -2020,7 +2021,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) {
|
||||||
|
@ -2033,7 +2034,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);
|
||||||
do_dts = eax & (1 << 0);
|
do_dts = eax & (1 << 0);
|
||||||
do_ptm = eax & (1 << 6);
|
do_ptm = eax & (1 << 6);
|
||||||
|
|
Loading…
Reference in a new issue