|
15 | 15 | #include <asm/cpu.h>
|
16 | 16 | #include <asm/intel-family.h>
|
17 | 17 | #include <asm/microcode_intel.h>
|
| 18 | +#include <asm/hwcap2.h> |
| 19 | +#include <asm/elf.h> |
18 | 20 |
|
19 | 21 | #ifdef CONFIG_X86_64
|
20 | 22 | #include <linux/topology.h>
|
@@ -62,6 +64,46 @@ void check_mpx_erratum(struct cpuinfo_x86 *c)
|
62 | 64 | }
|
63 | 65 | }
|
64 | 66 |
|
| 67 | +static bool ring3mwait_disabled __read_mostly; |
| 68 | + |
| 69 | +static int __init ring3mwait_disable(char *__unused) |
| 70 | +{ |
| 71 | + ring3mwait_disabled = true; |
| 72 | + return 0; |
| 73 | +} |
| 74 | +__setup("ring3mwait=disable", ring3mwait_disable); |
| 75 | + |
| 76 | +static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c) |
| 77 | +{ |
| 78 | + /* |
| 79 | + * Ring 3 MONITOR/MWAIT feature cannot be detected without |
| 80 | + * cpu model and family comparison. |
| 81 | + */ |
| 82 | + if (c->x86 != 6) |
| 83 | + return; |
| 84 | + switch (c->x86_model) { |
| 85 | + case INTEL_FAM6_XEON_PHI_KNL: |
| 86 | + case INTEL_FAM6_XEON_PHI_KNM: |
| 87 | + break; |
| 88 | + default: |
| 89 | + return; |
| 90 | + } |
| 91 | + |
| 92 | + if (ring3mwait_disabled) { |
| 93 | + msr_clear_bit(MSR_MISC_FEATURE_ENABLES, |
| 94 | + MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT); |
| 95 | + return; |
| 96 | + } |
| 97 | + |
| 98 | + msr_set_bit(MSR_MISC_FEATURE_ENABLES, |
| 99 | + MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT); |
| 100 | + |
| 101 | + set_cpu_cap(c, X86_FEATURE_RING3MWAIT); |
| 102 | + |
| 103 | + if (c == &boot_cpu_data) |
| 104 | + ELF_HWCAP2 |= HWCAP2_RING3MWAIT; |
| 105 | +} |
| 106 | + |
65 | 107 | static void early_init_intel(struct cpuinfo_x86 *c)
|
66 | 108 | {
|
67 | 109 | u64 misc_enable;
|
@@ -562,6 +604,8 @@ static void init_intel(struct cpuinfo_x86 *c)
|
562 | 604 | detect_vmx_virtcap(c);
|
563 | 605 |
|
564 | 606 | init_intel_energy_perf(c);
|
| 607 | + |
| 608 | + probe_xeon_phi_r3mwait(c); |
565 | 609 | }
|
566 | 610 |
|
567 | 611 | #ifdef CONFIG_X86_32
|
|
0 commit comments