Merge branch 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm
[sfrench/cifs-2.6.git] / arch / x86 / kernel / cpu / cpuid-deps.c
1 /* Declare dependencies between CPUIDs */
2 #include <linux/kernel.h>
3 #include <linux/init.h>
4 #include <linux/module.h>
5 #include <asm/cpufeature.h>
6
7 struct cpuid_dep {
8         unsigned int    feature;
9         unsigned int    depends;
10 };
11
12 /*
13  * Table of CPUID features that depend on others.
14  *
15  * This only includes dependencies that can be usefully disabled, not
16  * features part of the base set (like FPU).
17  *
18  * Note this all is not __init / __initdata because it can be
19  * called from cpu hotplug. It shouldn't do anything in this case,
20  * but it's difficult to tell that to the init reference checker.
21  */
22 const static struct cpuid_dep cpuid_deps[] = {
23         { X86_FEATURE_XSAVEOPT,         X86_FEATURE_XSAVE     },
24         { X86_FEATURE_XSAVEC,           X86_FEATURE_XSAVE     },
25         { X86_FEATURE_XSAVES,           X86_FEATURE_XSAVE     },
26         { X86_FEATURE_AVX,              X86_FEATURE_XSAVE     },
27         { X86_FEATURE_PKU,              X86_FEATURE_XSAVE     },
28         { X86_FEATURE_MPX,              X86_FEATURE_XSAVE     },
29         { X86_FEATURE_XGETBV1,          X86_FEATURE_XSAVE     },
30         { X86_FEATURE_FXSR_OPT,         X86_FEATURE_FXSR      },
31         { X86_FEATURE_XMM,              X86_FEATURE_FXSR      },
32         { X86_FEATURE_XMM2,             X86_FEATURE_XMM       },
33         { X86_FEATURE_XMM3,             X86_FEATURE_XMM2      },
34         { X86_FEATURE_XMM4_1,           X86_FEATURE_XMM2      },
35         { X86_FEATURE_XMM4_2,           X86_FEATURE_XMM2      },
36         { X86_FEATURE_XMM3,             X86_FEATURE_XMM2      },
37         { X86_FEATURE_PCLMULQDQ,        X86_FEATURE_XMM2      },
38         { X86_FEATURE_SSSE3,            X86_FEATURE_XMM2,     },
39         { X86_FEATURE_F16C,             X86_FEATURE_XMM2,     },
40         { X86_FEATURE_AES,              X86_FEATURE_XMM2      },
41         { X86_FEATURE_SHA_NI,           X86_FEATURE_XMM2      },
42         { X86_FEATURE_FMA,              X86_FEATURE_AVX       },
43         { X86_FEATURE_AVX2,             X86_FEATURE_AVX,      },
44         { X86_FEATURE_AVX512F,          X86_FEATURE_AVX,      },
45         { X86_FEATURE_AVX512IFMA,       X86_FEATURE_AVX512F   },
46         { X86_FEATURE_AVX512PF,         X86_FEATURE_AVX512F   },
47         { X86_FEATURE_AVX512ER,         X86_FEATURE_AVX512F   },
48         { X86_FEATURE_AVX512CD,         X86_FEATURE_AVX512F   },
49         { X86_FEATURE_AVX512DQ,         X86_FEATURE_AVX512F   },
50         { X86_FEATURE_AVX512BW,         X86_FEATURE_AVX512F   },
51         { X86_FEATURE_AVX512VL,         X86_FEATURE_AVX512F   },
52         { X86_FEATURE_AVX512VBMI,       X86_FEATURE_AVX512F   },
53         { X86_FEATURE_AVX512_VBMI2,     X86_FEATURE_AVX512VL  },
54         { X86_FEATURE_GFNI,             X86_FEATURE_AVX512VL  },
55         { X86_FEATURE_VAES,             X86_FEATURE_AVX512VL  },
56         { X86_FEATURE_VPCLMULQDQ,       X86_FEATURE_AVX512VL  },
57         { X86_FEATURE_AVX512_VNNI,      X86_FEATURE_AVX512VL  },
58         { X86_FEATURE_AVX512_BITALG,    X86_FEATURE_AVX512VL  },
59         { X86_FEATURE_AVX512_4VNNIW,    X86_FEATURE_AVX512F   },
60         { X86_FEATURE_AVX512_4FMAPS,    X86_FEATURE_AVX512F   },
61         { X86_FEATURE_AVX512_VPOPCNTDQ, X86_FEATURE_AVX512F   },
62         {}
63 };
64
65 static inline void clear_feature(struct cpuinfo_x86 *c, unsigned int feature)
66 {
67         /*
68          * Note: This could use the non atomic __*_bit() variants, but the
69          * rest of the cpufeature code uses atomics as well, so keep it for
70          * consistency. Cleanup all of it separately.
71          */
72         if (!c) {
73                 clear_cpu_cap(&boot_cpu_data, feature);
74                 set_bit(feature, (unsigned long *)cpu_caps_cleared);
75         } else {
76                 clear_bit(feature, (unsigned long *)c->x86_capability);
77         }
78 }
79
80 /* Take the capabilities and the BUG bits into account */
81 #define MAX_FEATURE_BITS ((NCAPINTS + NBUGINTS) * sizeof(u32) * 8)
82
83 static void do_clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
84 {
85         DECLARE_BITMAP(disable, MAX_FEATURE_BITS);
86         const struct cpuid_dep *d;
87         bool changed;
88
89         if (WARN_ON(feature >= MAX_FEATURE_BITS))
90                 return;
91
92         clear_feature(c, feature);
93
94         /* Collect all features to disable, handling dependencies */
95         memset(disable, 0, sizeof(disable));
96         __set_bit(feature, disable);
97
98         /* Loop until we get a stable state. */
99         do {
100                 changed = false;
101                 for (d = cpuid_deps; d->feature; d++) {
102                         if (!test_bit(d->depends, disable))
103                                 continue;
104                         if (__test_and_set_bit(d->feature, disable))
105                                 continue;
106
107                         changed = true;
108                         clear_feature(c, d->feature);
109                 }
110         } while (changed);
111 }
112
113 void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int feature)
114 {
115         do_clear_cpu_cap(c, feature);
116 }
117
118 void setup_clear_cpu_cap(unsigned int feature)
119 {
120         do_clear_cpu_cap(NULL, feature);
121 }