Skip to content

Commit d94a155

Browse files
kirylKAGA-KOKO
authored andcommitted
x86/cpu: Prevent cpuinfo_x86::x86_phys_bits adjustment corruption
Some features (Intel MKTME, AMD SME) reduce the number of effectively available physical address bits. cpuinfo_x86::x86_phys_bits is adjusted accordingly during the early cpu feature detection. Though if get_cpu_cap() is called later again then this adjustement is overwritten. That happens in setup_pku(), which is called after detect_tme(). To address this, extract the address sizes enumeration into a separate function, which is only called only from early_identify_cpu() and from generic_identify(). This makes get_cpu_cap() safe to be called later during boot proccess without overwriting cpuinfo_x86::x86_phys_bits. [ tglx: Massaged changelog ] Fixes: cb06d8e ("x86/tme: Detect if TME and MKTME is activated by BIOS") Reported-by: Kai Huang <[email protected]> Signed-off-by: Kirill A. Shutemov <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: Tom Lendacky <[email protected]> Cc: Dave Hansen <[email protected]> Cc: [email protected] Cc: "H. Peter Anvin" <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 92e830f commit d94a155

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

arch/x86/kernel/cpu/common.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -848,18 +848,6 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
848848
c->x86_power = edx;
849849
}
850850

851-
if (c->extended_cpuid_level >= 0x80000008) {
852-
cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
853-
854-
c->x86_virt_bits = (eax >> 8) & 0xff;
855-
c->x86_phys_bits = eax & 0xff;
856-
c->x86_capability[CPUID_8000_0008_EBX] = ebx;
857-
}
858-
#ifdef CONFIG_X86_32
859-
else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
860-
c->x86_phys_bits = 36;
861-
#endif
862-
863851
if (c->extended_cpuid_level >= 0x8000000a)
864852
c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a);
865853

@@ -874,6 +862,23 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
874862
apply_forced_caps(c);
875863
}
876864

865+
static void get_cpu_address_sizes(struct cpuinfo_x86 *c)
866+
{
867+
u32 eax, ebx, ecx, edx;
868+
869+
if (c->extended_cpuid_level >= 0x80000008) {
870+
cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
871+
872+
c->x86_virt_bits = (eax >> 8) & 0xff;
873+
c->x86_phys_bits = eax & 0xff;
874+
c->x86_capability[CPUID_8000_0008_EBX] = ebx;
875+
}
876+
#ifdef CONFIG_X86_32
877+
else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
878+
c->x86_phys_bits = 36;
879+
#endif
880+
}
881+
877882
static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
878883
{
879884
#ifdef CONFIG_X86_32
@@ -965,6 +970,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
965970
cpu_detect(c);
966971
get_cpu_vendor(c);
967972
get_cpu_cap(c);
973+
get_cpu_address_sizes(c);
968974
setup_force_cpu_cap(X86_FEATURE_CPUID);
969975

970976
if (this_cpu->c_early_init)
@@ -1097,6 +1103,8 @@ static void generic_identify(struct cpuinfo_x86 *c)
10971103

10981104
get_cpu_cap(c);
10991105

1106+
get_cpu_address_sizes(c);
1107+
11001108
if (c->cpuid_level >= 0x00000001) {
11011109
c->initial_apicid = (cpuid_ebx(1) >> 24) & 0xFF;
11021110
#ifdef CONFIG_X86_32

0 commit comments

Comments
 (0)