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 <dongsheng.x.zhang@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
dongshen 2021-08-19 11:03:13 -07:00 committed by wenlingz
parent cb2bb78b6f
commit 39461ef9dd
4 changed files with 113 additions and 3 deletions

View File

@ -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

View File

@ -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
*/

View File

@ -29,6 +29,7 @@
#include <asm/guest/instr_emul.h>
#include <asm/guest/nested.h>
#include <asm/vmx.h>
#include <asm/vm_config.h>
/**
* @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

View File

@ -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);