From 538e7cf74d52ea5533bb4c713b7b56d673f839e4 Mon Sep 17 00:00:00 2001 From: liujunming Date: Mon, 10 Aug 2020 17:07:10 +0800 Subject: [PATCH] hv:cpu-caps:refine processor family and model info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v3 -> v4: Refine commit message and code stype 1. SDM Vol. 2A 3-211 states DisplayFamily = Extended_Family_ID + Family_ID when Family_ID == 0FH. So it should be family += ((eax >> 20U) & 0xffU) when Family_ID == 0FH. 2. IF (Family_ID = 06H or Family_ID = 0FH) THEN DisplayModel = (Extended_Model_ID « 4) + Model_ID; While previous code this logic: IF (DisplayFamily = 06H or DisplayFamily = 0FH) Fix the bug about calculation of display family and display model according to SDM definition. 3. use variable name to distinguish Family ID/Display Family/Model ID/Display Model, then the code is more clear to avoid some mistake Tracked-On:#3675 Signed-off-by: liujunming Reviewed-by: Wu Xiangyang Acked-by: Eddie Dong --- hypervisor/arch/x86/cpu_caps.c | 28 +++++++++++++++----------- hypervisor/arch/x86/lapic.c | 4 ++-- hypervisor/arch/x86/security.c | 4 ++-- hypervisor/include/arch/x86/cpu_caps.h | 5 ++++- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/hypervisor/arch/x86/cpu_caps.c b/hypervisor/arch/x86/cpu_caps.c index 07150514f..759f7d675 100644 --- a/hypervisor/arch/x86/cpu_caps.c +++ b/hypervisor/arch/x86/cpu_caps.c @@ -61,7 +61,7 @@ bool monitor_cap_buggy(void) { bool buggy = false; - if ((boot_cpu_data.family == 0x6U) && (boot_cpu_data.model == 0x5cU)) { + if ((boot_cpu_data.displayfamily == 0x6U) && (boot_cpu_data.displaymodel == 0x5cU)) { buggy = true; } @@ -118,7 +118,7 @@ bool is_apl_platform(void) { bool ret = false; - if ((boot_cpu_data.family == 0x6U) && (boot_cpu_data.model == 0x92U)) { + if ((boot_cpu_data.displayfamily == 0x6U) && (boot_cpu_data.displaymodel == 0x92U)) { ret = true; } @@ -251,7 +251,7 @@ static uint64_t get_address_mask(uint8_t limit) void init_pcpu_capabilities(void) { uint32_t eax, unused; - uint32_t family, model; + uint32_t family_id, model_id, displayfamily, displaymodel; cpuid_subleaf(CPUID_VENDORSTRING, 0x0U, &boot_cpu_data.cpuid_level, @@ -260,17 +260,21 @@ void init_pcpu_capabilities(void) cpuid_subleaf(CPUID_FEATURES, 0x0U, &eax, &unused, &boot_cpu_data.cpuid_leaves[FEAT_1_ECX], &boot_cpu_data.cpuid_leaves[FEAT_1_EDX]); - family = (eax >> 8U) & 0xfU; - if (family == 0xFU) { - family += ((eax >> 20U) & 0xffU) << 4U; - } - boot_cpu_data.family = (uint8_t)family; - model = (eax >> 4U) & 0xfU; - if (family == 0x06U || family == 0xFU) { - model += ((eax >> 16U) & 0xfU) << 4U; + /* SDM Vol.2A 3-211 states the algorithm to calculate DisplayFamily and DisplayModel */ + family_id = (eax >> 8U) & 0xfU; + displayfamily = family_id; + if (family_id == 0xFU) { + displayfamily += ((eax >> 20U) & 0xffU); } - boot_cpu_data.model = (uint8_t)model; + boot_cpu_data.displayfamily = (uint8_t)displayfamily; + + model_id = (eax >> 4U) & 0xfU; + displaymodel = model_id; + if ((family_id == 0x06U) || (family_id == 0xFU)) { + displaymodel += ((eax >> 16U) & 0xfU) << 4U; + } + boot_cpu_data.displaymodel = (uint8_t)displaymodel; cpuid_subleaf(CPUID_EXTEND_FEATURE, 0x0U, &unused, diff --git a/hypervisor/arch/x86/lapic.c b/hypervisor/arch/x86/lapic.c index 3b92d2715..2ff017ea6 100644 --- a/hypervisor/arch/x86/lapic.c +++ b/hypervisor/arch/x86/lapic.c @@ -187,7 +187,7 @@ send_startup_ipi(uint16_t dest_pcpu_id, uint64_t cpu_startup_start_address) * and first Startup IPI, so on Modern processors (family == 6) * setting a delay value of 10us. */ - if (cpu_info->family != 6U) { + if (cpu_info->displayfamily != 6U) { /* delay 10ms */ udelay(10000U); } else { @@ -201,7 +201,7 @@ send_startup_ipi(uint16_t dest_pcpu_id, uint64_t cpu_startup_start_address) icr.bits.vector = (uint8_t)(cpu_startup_start_address >> 12U); msr_write(MSR_IA32_EXT_APIC_ICR, icr.value); - if (cpu_info->family == 6U) { + if (cpu_info->displayfamily == 6U) { udelay(10U); /* 10us is enough for Modern processors */ } else { udelay(200U); /* 200us for old processors */ diff --git a/hypervisor/arch/x86/security.c b/hypervisor/arch/x86/security.c index 28a765543..a065c19e0 100644 --- a/hypervisor/arch/x86/security.c +++ b/hypervisor/arch/x86/security.c @@ -197,8 +197,8 @@ bool is_ept_force_4k_ipage(void) const struct cpuinfo_x86 *info = get_pcpu_info(); uint64_t x86_arch_capabilities; - if (info->family == 0x6U) { - switch (info->model) { + if (info->displayfamily == 0x6U) { + switch (info->displaymodel) { case 0x26U: case 0x27U: case 0x35U: diff --git a/hypervisor/include/arch/x86/cpu_caps.h b/hypervisor/include/arch/x86/cpu_caps.h index 1e608e401..39a40f755 100644 --- a/hypervisor/include/arch/x86/cpu_caps.h +++ b/hypervisor/include/arch/x86/cpu_caps.h @@ -32,7 +32,10 @@ #define FEATURE_WORDS 15U struct cpuinfo_x86 { - uint8_t family, model; + /* SDM 2-2 Vol.4 Table 2-1 uses DisplayFamily_DisplayModel to + * distinguish Processor Families/Processor Number Series. + */ + uint8_t displayfamily, displaymodel; uint8_t virt_bits; uint8_t phys_bits; uint32_t cpuid_level;