From 39461ef9ddbdfd59b7f65964d4da6308fd53b369 Mon Sep 17 00:00:00 2001 From: dongshen Date: Thu, 19 Aug 2021 11:03:13 -0700 Subject: [PATCH] hv: vCAT: initialize the emulated_guest_msrs array for CAT msrs during platform initialization Initialize the emulated_guest_msrs[] array at runtime for MSR_IA32_type_MASK_n and MSR_IA32_PQR_ASSOC msrs, there is no good way to do this initialization statically at build time Tracked-On: #5917 Signed-off-by: dongshen Acked-by: Eddie Dong --- hypervisor/arch/x86/cpu.c | 4 + hypervisor/arch/x86/guest/vmsr.c | 88 +++++++++++++++++++- hypervisor/include/arch/x86/asm/guest/vcpu.h | 23 ++++- hypervisor/include/arch/x86/asm/msr.h | 1 + 4 files changed, 113 insertions(+), 3 deletions(-) diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index e1ee4770e..18c33c7d1 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -186,6 +186,10 @@ void init_pcpu_pre(bool is_bsp) panic("System IOAPIC info is incorrect!"); } +#ifdef CONFIG_VCAT_ENABLED + init_intercepted_cat_msr_list(); +#endif + #ifdef CONFIG_RDT_ENABLED init_rdt_info(); #endif diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index daa385a50..a6b26196e 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -28,7 +28,7 @@ #define INTERCEPT_WRITE (1U << 1U) #define INTERCEPT_READ_WRITE (INTERCEPT_READ | INTERCEPT_WRITE) -static const uint32_t emulated_guest_msrs[NUM_GUEST_MSRS] = { +static uint32_t emulated_guest_msrs[NUM_GUEST_MSRS] = { /* * MSRs that trusty may touch and need isolation between secure and normal world * This may include MSR_IA32_STAR, MSR_IA32_LSTAR, MSR_IA32_FMASK, @@ -79,6 +79,24 @@ static const uint32_t emulated_guest_msrs[NUM_GUEST_MSRS] = { #ifdef CONFIG_NVMX_ENABLED LIST_OF_VMX_MSRS, #endif + + /* The following range of elements are reserved for vCAT usage and are + * initialized dynamically by init_intercepted_cat_msr_list() during platform initialization: + * [(NUM_GUEST_MSRS - NUM_VCAT_MSRS) ... (NUM_GUEST_MSRS - 1)] = { + * The following layout of each CAT MSR entry is determined by cat_msr_to_index_of_emulated_msr(): + * MSR_IA32_L3_MASK_BASE, + * MSR_IA32_L3_MASK_BASE + 1, + * ... + * MSR_IA32_L3_MASK_BASE + NUM_VCAT_L3_MSRS - 1, + * + * MSR_IA32_L2_MASK_BASE + NUM_VCAT_L3_MSRS, + * MSR_IA32_L2_MASK_BASE + NUM_VCAT_L3_MSRS + 1, + * ... + * MSR_IA32_L2_MASK_BASE + NUM_VCAT_L3_MSRS + NUM_VCAT_L2_MSRS - 1, + * + * MSR_IA32_PQR_ASSOC + NUM_VCAT_L3_MSRS + NUM_VCAT_L2_MSRS + * } + */ }; static const uint32_t mtrr_msrs[] = { @@ -355,6 +373,74 @@ void init_emulated_msrs(struct acrn_vcpu *vcpu) vcpu_set_guest_msr(vcpu, MSR_IA32_FEATURE_CONTROL, val64); } +#ifdef CONFIG_VCAT_ENABLED +/** + * @brief Map CAT MSR address to zero based index + * + * @pre ((msr >= MSR_IA32_L3_MASK_BASE) && msr < (MSR_IA32_L3_MASK_BASE + NUM_VCAT_L3_MSRS)) + * || ((msr >= MSR_IA32_L2_MASK_BASE) && msr < (MSR_IA32_L2_MASK_BASE + NUM_VCAT_L2_MSRS)) + * || (msr == MSR_IA32_PQR_ASSOC) + */ +static uint32_t cat_msr_to_index_of_emulated_msr(uint32_t msr) +{ + uint32_t index = 0U; + + /* L3 MSRs indices assignment for MSR_IA32_L3_MASK_BASE ~ (MSR_IA32_L3_MASK_BASE + NUM_VCAT_L3_MSRS): + * 0 + * 1 + * ... + * (NUM_VCAT_L3_MSRS - 1) + * + * L2 MSRs indices assignment: + * NUM_VCAT_L3_MSRS + * ... + * NUM_VCAT_L3_MSRS + NUM_VCAT_L2_MSRS - 1 + + * PQR index assignment for MSR_IA32_PQR_ASSOC: + * NUM_VCAT_L3_MSRS + */ + + if ((msr >= MSR_IA32_L3_MASK_BASE) && (msr < (MSR_IA32_L3_MASK_BASE + NUM_VCAT_L3_MSRS))) { + index = msr - MSR_IA32_L3_MASK_BASE; + } else if ((msr >= MSR_IA32_L2_MASK_BASE) && (msr < (MSR_IA32_L2_MASK_BASE + NUM_VCAT_L2_MSRS))) { + index = msr - MSR_IA32_L2_MASK_BASE + NUM_VCAT_L3_MSRS; + } else if (msr == MSR_IA32_PQR_ASSOC) { + index = NUM_VCAT_L3_MSRS + NUM_VCAT_L2_MSRS; + } else { + ASSERT(false, "invalid CAT msr address"); + } + + return index; +} + +static void init_cat_msr_entry(uint32_t msr) +{ + /* Get index into the emulated_guest_msrs[] table for a given CAT MSR */ + uint32_t index = cat_msr_to_index_of_emulated_msr(msr) + CAT_MSR_START_INDEX; + + emulated_guest_msrs[index] = msr; +} + +/* Init emulated_guest_msrs[] dynamically for CAT MSRs */ +void init_intercepted_cat_msr_list(void) +{ + uint32_t msr; + + /* MSR_IA32_L2_MASK_n MSRs */ + for (msr = MSR_IA32_L2_MASK_BASE; msr < (MSR_IA32_L2_MASK_BASE + NUM_VCAT_L2_MSRS); msr++) { + init_cat_msr_entry(msr); + } + + /* MSR_IA32_L3_MASK_n MSRs */ + for (msr = MSR_IA32_L3_MASK_BASE; msr < (MSR_IA32_L3_MASK_BASE + NUM_VCAT_L3_MSRS); msr++) { + init_cat_msr_entry(msr); + } + + /* MSR_IA32_PQR_ASSOC */ + init_cat_msr_entry(MSR_IA32_PQR_ASSOC); +} +#endif + /** * @pre vcpu != NULL */ diff --git a/hypervisor/include/arch/x86/asm/guest/vcpu.h b/hypervisor/include/arch/x86/asm/guest/vcpu.h index 65ec52203..06128d59c 100644 --- a/hypervisor/include/arch/x86/asm/guest/vcpu.h +++ b/hypervisor/include/arch/x86/asm/guest/vcpu.h @@ -29,6 +29,7 @@ #include #include #include +#include /** * @brief vcpu @@ -173,11 +174,29 @@ enum reset_mode; #define NUM_WORLD_MSRS 2U #define NUM_COMMON_MSRS 23U + +#ifdef CONFIG_VCAT_ENABLED +#define NUM_VCAT_L2_MSRS MAX_CACHE_CLOS_NUM_ENTRIES +#define NUM_VCAT_L3_MSRS MAX_CACHE_CLOS_NUM_ENTRIES +/* L2/L3 mask MSRs plus MSR_IA32_PQR_ASSOC */ +#define NUM_VCAT_MSRS (NUM_VCAT_L2_MSRS + NUM_VCAT_L3_MSRS + 1U) + #ifdef CONFIG_NVMX_ENABLED -#define NUM_GUEST_MSRS (NUM_WORLD_MSRS + NUM_COMMON_MSRS + NUM_VMX_MSRS) +#define CAT_MSR_START_INDEX (NUM_WORLD_MSRS + NUM_COMMON_MSRS + NUM_VMX_MSRS) #else -#define NUM_GUEST_MSRS (NUM_WORLD_MSRS + NUM_COMMON_MSRS) +#define CAT_MSR_START_INDEX (NUM_WORLD_MSRS + NUM_COMMON_MSRS) #endif +#else +#define NUM_VCAT_MSRS 0U +#endif + +/* For detailed layout of the emulated guest MSRs, see emulated_guest_msrs[NUM_GUEST_MSRS] in vmsr.c */ +#ifdef CONFIG_NVMX_ENABLED +#define NUM_GUEST_MSRS (NUM_WORLD_MSRS + NUM_COMMON_MSRS + NUM_VMX_MSRS + NUM_VCAT_MSRS) +#else +#define NUM_GUEST_MSRS (NUM_WORLD_MSRS + NUM_COMMON_MSRS + NUM_VCAT_MSRS) +#endif + #define EOI_EXIT_BITMAP_SIZE 256U diff --git a/hypervisor/include/arch/x86/asm/msr.h b/hypervisor/include/arch/x86/asm/msr.h index 9c9b56bf7..6556267f5 100644 --- a/hypervisor/include/arch/x86/asm/msr.h +++ b/hypervisor/include/arch/x86/asm/msr.h @@ -617,6 +617,7 @@ static inline bool is_x2apic_msr(uint32_t msr) struct acrn_vcpu; void init_msr_emulation(struct acrn_vcpu *vcpu); +void init_intercepted_cat_msr_list(void); uint32_t vmsr_get_guest_msr_index(uint32_t msr); void update_msr_bitmap_x2apic_apicv(struct acrn_vcpu *vcpu); void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu);