diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f1af71851919..25581dcb280e 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -124,18 +124,25 @@ static inline int flag_is_changeable_p(u32 flag) | |||
124 | { | 124 | { |
125 | u32 f1, f2; | 125 | u32 f1, f2; |
126 | 126 | ||
127 | asm("pushfl\n\t" | 127 | /* |
128 | "pushfl\n\t" | 128 | * Cyrix and IDT cpus allow disabling of CPUID |
129 | "popl %0\n\t" | 129 | * so the code below may return different results |
130 | "movl %0,%1\n\t" | 130 | * when it is executed before and after enabling |
131 | "xorl %2,%0\n\t" | 131 | * the CPUID. Add "volatile" to not allow gcc to |
132 | "pushl %0\n\t" | 132 | * optimize the subsequent calls to this function. |
133 | "popfl\n\t" | 133 | */ |
134 | "pushfl\n\t" | 134 | asm volatile ("pushfl\n\t" |
135 | "popl %0\n\t" | 135 | "pushfl\n\t" |
136 | "popfl\n\t" | 136 | "popl %0\n\t" |
137 | : "=&r" (f1), "=&r" (f2) | 137 | "movl %0,%1\n\t" |
138 | : "ir" (flag)); | 138 | "xorl %2,%0\n\t" |
139 | "pushl %0\n\t" | ||
140 | "popfl\n\t" | ||
141 | "pushfl\n\t" | ||
142 | "popl %0\n\t" | ||
143 | "popfl\n\t" | ||
144 | : "=&r" (f1), "=&r" (f2) | ||
145 | : "ir" (flag)); | ||
139 | 146 | ||
140 | return ((f1^f2) & flag) != 0; | 147 | return ((f1^f2) & flag) != 0; |
141 | } | 148 | } |