x86/cpuid: Replace set/clear_bit32()
authorThomas Gleixner <tglx@linutronix.de>
Thu, 2 Nov 2017 12:22:35 +0000 (13:22 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 2 Nov 2017 13:56:43 +0000 (14:56 +0100)
Peter pointed out that the set/clear_bit32() variants are broken in various
aspects.

Replace them with open coded set/clear_bit() and type cast
cpu_info::x86_capability as it's done in all other places throughout x86.

Fixes: 0b00de857a64 ("x86/cpuid: Add generic table for CPUID dependencies")
Reported-by: Peter Ziljstra <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andi Kleen <ak@linux.intel.com>
arch/x86/kernel/cpu/cpuid-deps.c

index c21f22d..904b0a3 100644 (file)
@@ -62,23 +62,19 @@ const static struct cpuid_dep cpuid_deps[] = {
        {}
 };
 
-static inline void __clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit)
-{
-       clear_bit32(bit, c->x86_capability);
-}
-
-static inline void __setup_clear_cpu_cap(unsigned int bit)
-{
-       clear_cpu_cap(&boot_cpu_data, bit);
-       set_bit32(bit, cpu_caps_cleared);
-}
-
 static inline void clear_feature(struct cpuinfo_x86 *c, unsigned int feature)
 {
-       if (!c)
-               __setup_clear_cpu_cap(feature);
-       else
-               __clear_cpu_cap(c, feature);
+       /*
+        * Note: This could use the non atomic __*_bit() variants, but the
+        * rest of the cpufeature code uses atomics as well, so keep it for
+        * consistency. Cleanup all of it separately.
+        */
+       if (!c) {
+               clear_cpu_cap(&boot_cpu_data, feature);
+               set_bit(feature, (unsigned long *)cpu_caps_cleared);
+       } else {
+               clear_bit(feature, (unsigned long *)c->x86_capability);
+       }
 }
 
 /* Take the capabilities and the BUG bits into account */