diff options
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 2346c95c6ab1..1cd4a1a44b95 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -646,6 +646,30 @@ void get_cpu_cap(struct cpuinfo_x86 *c) | |||
646 | c->x86_capability[10] = eax; | 646 | c->x86_capability[10] = eax; |
647 | } | 647 | } |
648 | 648 | ||
649 | /* Additional Intel-defined flags: level 0x0000000F */ | ||
650 | if (c->cpuid_level >= 0x0000000F) { | ||
651 | u32 eax, ebx, ecx, edx; | ||
652 | |||
653 | /* QoS sub-leaf, EAX=0Fh, ECX=0 */ | ||
654 | cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx); | ||
655 | c->x86_capability[11] = edx; | ||
656 | if (cpu_has(c, X86_FEATURE_CQM_LLC)) { | ||
657 | /* will be overridden if occupancy monitoring exists */ | ||
658 | c->x86_cache_max_rmid = ebx; | ||
659 | |||
660 | /* QoS sub-leaf, EAX=0Fh, ECX=1 */ | ||
661 | cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx); | ||
662 | c->x86_capability[12] = edx; | ||
663 | if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) { | ||
664 | c->x86_cache_max_rmid = ecx; | ||
665 | c->x86_cache_occ_scale = ebx; | ||
666 | } | ||
667 | } else { | ||
668 | c->x86_cache_max_rmid = -1; | ||
669 | c->x86_cache_occ_scale = -1; | ||
670 | } | ||
671 | } | ||
672 | |||
649 | /* AMD-defined flags: level 0x80000001 */ | 673 | /* AMD-defined flags: level 0x80000001 */ |
650 | xlvl = cpuid_eax(0x80000000); | 674 | xlvl = cpuid_eax(0x80000000); |
651 | c->extended_cpuid_level = xlvl; | 675 | c->extended_cpuid_level = xlvl; |
@@ -834,6 +858,20 @@ static void generic_identify(struct cpuinfo_x86 *c) | |||
834 | detect_nopl(c); | 858 | detect_nopl(c); |
835 | } | 859 | } |
836 | 860 | ||
861 | static void x86_init_cache_qos(struct cpuinfo_x86 *c) | ||
862 | { | ||
863 | /* | ||
864 | * The heavy lifting of max_rmid and cache_occ_scale are handled | ||
865 | * in get_cpu_cap(). Here we just set the max_rmid for the boot_cpu | ||
866 | * in case CQM bits really aren't there in this CPU. | ||
867 | */ | ||
868 | if (c != &boot_cpu_data) { | ||
869 | boot_cpu_data.x86_cache_max_rmid = | ||
870 | min(boot_cpu_data.x86_cache_max_rmid, | ||
871 | c->x86_cache_max_rmid); | ||
872 | } | ||
873 | } | ||
874 | |||
837 | /* | 875 | /* |
838 | * This does the hard work of actually picking apart the CPU stuff... | 876 | * This does the hard work of actually picking apart the CPU stuff... |
839 | */ | 877 | */ |
@@ -923,6 +961,7 @@ static void identify_cpu(struct cpuinfo_x86 *c) | |||
923 | 961 | ||
924 | init_hypervisor(c); | 962 | init_hypervisor(c); |
925 | x86_init_rdrand(c); | 963 | x86_init_rdrand(c); |
964 | x86_init_cache_qos(c); | ||
926 | 965 | ||
927 | /* | 966 | /* |
928 | * Clear/Set all flags overriden by options, need do it | 967 | * Clear/Set all flags overriden by options, need do it |