|
@@ -659,6 +659,16 @@ void cpu_detect(struct cpuinfo_x86 *c)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void apply_forced_caps(struct cpuinfo_x86 *c)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < NCAPINTS; i++) {
|
|
|
|
+ c->x86_capability[i] &= ~cpu_caps_cleared[i];
|
|
|
|
+ c->x86_capability[i] |= cpu_caps_set[i];
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
void get_cpu_cap(struct cpuinfo_x86 *c)
|
|
void get_cpu_cap(struct cpuinfo_x86 *c)
|
|
{
|
|
{
|
|
u32 eax, ebx, ecx, edx;
|
|
u32 eax, ebx, ecx, edx;
|
|
@@ -752,6 +762,13 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
|
|
c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a);
|
|
c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a);
|
|
|
|
|
|
init_scattered_cpuid_features(c);
|
|
init_scattered_cpuid_features(c);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Clear/Set all flags overridden by options, after probe.
|
|
|
|
+ * This needs to happen each time we re-probe, which may happen
|
|
|
|
+ * several times during CPU initialization.
|
|
|
|
+ */
|
|
|
|
+ apply_forced_caps(c);
|
|
}
|
|
}
|
|
|
|
|
|
static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
|
|
static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
|
|
@@ -805,14 +822,12 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
|
|
memset(&c->x86_capability, 0, sizeof c->x86_capability);
|
|
memset(&c->x86_capability, 0, sizeof c->x86_capability);
|
|
c->extended_cpuid_level = 0;
|
|
c->extended_cpuid_level = 0;
|
|
|
|
|
|
- if (!have_cpuid_p())
|
|
|
|
- identify_cpu_without_cpuid(c);
|
|
|
|
-
|
|
|
|
/* cyrix could have cpuid enabled via c_identify()*/
|
|
/* cyrix could have cpuid enabled via c_identify()*/
|
|
if (have_cpuid_p()) {
|
|
if (have_cpuid_p()) {
|
|
cpu_detect(c);
|
|
cpu_detect(c);
|
|
get_cpu_vendor(c);
|
|
get_cpu_vendor(c);
|
|
get_cpu_cap(c);
|
|
get_cpu_cap(c);
|
|
|
|
+ setup_force_cpu_cap(X86_FEATURE_CPUID);
|
|
|
|
|
|
if (this_cpu->c_early_init)
|
|
if (this_cpu->c_early_init)
|
|
this_cpu->c_early_init(c);
|
|
this_cpu->c_early_init(c);
|
|
@@ -822,6 +837,9 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
|
|
|
|
|
|
if (this_cpu->c_bsp_init)
|
|
if (this_cpu->c_bsp_init)
|
|
this_cpu->c_bsp_init(c);
|
|
this_cpu->c_bsp_init(c);
|
|
|
|
+ } else {
|
|
|
|
+ identify_cpu_without_cpuid(c);
|
|
|
|
+ setup_clear_cpu_cap(X86_FEATURE_CPUID);
|
|
}
|
|
}
|
|
|
|
|
|
setup_force_cpu_cap(X86_FEATURE_ALWAYS);
|
|
setup_force_cpu_cap(X86_FEATURE_ALWAYS);
|
|
@@ -1039,10 +1057,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
|
|
this_cpu->c_identify(c);
|
|
this_cpu->c_identify(c);
|
|
|
|
|
|
/* Clear/Set all flags overridden by options, after probe */
|
|
/* Clear/Set all flags overridden by options, after probe */
|
|
- for (i = 0; i < NCAPINTS; i++) {
|
|
|
|
- c->x86_capability[i] &= ~cpu_caps_cleared[i];
|
|
|
|
- c->x86_capability[i] |= cpu_caps_set[i];
|
|
|
|
- }
|
|
|
|
|
|
+ apply_forced_caps(c);
|
|
|
|
|
|
#ifdef CONFIG_X86_64
|
|
#ifdef CONFIG_X86_64
|
|
c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
|
|
c->apicid = apic->phys_pkg_id(c->initial_apicid, 0);
|
|
@@ -1103,10 +1118,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
|
|
* Clear/Set all flags overridden by options, need do it
|
|
* Clear/Set all flags overridden by options, need do it
|
|
* before following smp all cpus cap AND.
|
|
* before following smp all cpus cap AND.
|
|
*/
|
|
*/
|
|
- for (i = 0; i < NCAPINTS; i++) {
|
|
|
|
- c->x86_capability[i] &= ~cpu_caps_cleared[i];
|
|
|
|
- c->x86_capability[i] |= cpu_caps_set[i];
|
|
|
|
- }
|
|
|
|
|
|
+ apply_forced_caps(c);
|
|
|
|
|
|
/*
|
|
/*
|
|
* On SMP, boot_cpu_data holds the common feature set between
|
|
* On SMP, boot_cpu_data holds the common feature set between
|