hv: rearrange data structure for emulated MSRs

Create two arrays for emulated MSRs:
- guest_msrs[] in struct acrn_vcpu_arch: emulation for all MSRs that are
  included in emulated_guest_msrs[].
- world_msrs[] in struct cpu_context: it has separate copies for secure and
  normal world for those MSRs that are in the first NUM_WORLD_MSRS entries
  in emulated_guest_msrs[].

Split vmsr.c/emulated_msrs[] into 3 smaller arrays:
- emulated_guest_msrs[]: corresponding MSRs are emulated in guest_msrs[]
- mtrr_msrs[]: emulated MTRRs are saved in vMTRR module
- unsupported_msrs[]: GP for any guest accesses

Tracked-On: #1867
Signed-off-by: Zide Chen <zide.chen@intel.com>
This commit is contained in:
Zide Chen 2018-09-22 23:30:29 -07:00 committed by wenlingz
parent 7fce2462a0
commit 92bbb545cf
2 changed files with 46 additions and 20 deletions

View File

@ -14,24 +14,30 @@ enum rw_mode {
READ_WRITE READ_WRITE
}; };
/* static const uint32_t emulated_guest_msrs[NUM_GUEST_MSRS] = {
* List of intercepted MSRs. /*
* If any MSRs appear in this array but not handled in any swith statements * MSRs that trusty may touch and need isolation between secure and normal world
* in either rdmsr_vmexit_handler() or wrmsr_vmexit_handler(), a GP will * This may include MSR_IA32_TSC_ADJUST, MSR_IA32_STAR, MSR_IA32_LSTAR, MSR_IA32_FMASK,
* be thrown to the guest for any R/W accesses. * MSR_IA32_KERNEL_GS_BASE, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP
*/ *
#define NUM_EMULATED_MSR 96U * Number of entries: NUM_WORLD_MSRS
static const uint32_t emulated_msrs[NUM_EMULATED_MSR] = { */
/* Emulated MSRs */ MSR_IA32_PAT,
/*
* MSRs don't need isolation between worlds
* Number of entries: NUM_COMMON_MSRS
*/
MSR_IA32_TSC_DEADLINE, MSR_IA32_TSC_DEADLINE,
MSR_IA32_BIOS_UPDT_TRIG, MSR_IA32_BIOS_UPDT_TRIG,
MSR_IA32_BIOS_SIGN_ID, MSR_IA32_BIOS_SIGN_ID,
MSR_IA32_TIME_STAMP_COUNTER, MSR_IA32_TIME_STAMP_COUNTER,
MSR_IA32_PAT,
MSR_IA32_APIC_BASE, MSR_IA32_APIC_BASE,
MSR_IA32_PERF_CTL
};
MSR_IA32_PERF_CTL, #define NUM_MTRR_MSRS 13U
static const uint32_t mtrr_msrs[NUM_MTRR_MSRS] = {
MSR_IA32_MTRR_CAP, MSR_IA32_MTRR_CAP,
MSR_IA32_MTRR_DEF_TYPE, MSR_IA32_MTRR_DEF_TYPE,
MSR_IA32_MTRR_FIX64K_00000, MSR_IA32_MTRR_FIX64K_00000,
@ -44,10 +50,12 @@ static const uint32_t emulated_msrs[NUM_EMULATED_MSR] = {
MSR_IA32_MTRR_FIX4K_E0000, MSR_IA32_MTRR_FIX4K_E0000,
MSR_IA32_MTRR_FIX4K_E8000, MSR_IA32_MTRR_FIX4K_E8000,
MSR_IA32_MTRR_FIX4K_F0000, MSR_IA32_MTRR_FIX4K_F0000,
MSR_IA32_MTRR_FIX4K_F8000, MSR_IA32_MTRR_FIX4K_F8000
};
/* Following MSRs intercepted, and throw GP for any access */
/* Following MSRs are intercepted, but it throws GPs for any guest accesses */
#define NUM_UNSUPPORTED_MSRS 76U
static const uint32_t unsupported_msrs[NUM_UNSUPPORTED_MSRS] = {
/* Variable MTRRs are not supported */ /* Variable MTRRs are not supported */
MSR_IA32_MTRR_PHYSBASE_0, MSR_IA32_MTRR_PHYSBASE_0,
MSR_IA32_MTRR_PHYSMASK_0, MSR_IA32_MTRR_PHYSMASK_0,
@ -145,8 +153,8 @@ static const uint32_t emulated_msrs[NUM_EMULATED_MSR] = {
/* MSR 0xC90 ... 0xD8F, not in this array */ /* MSR 0xC90 ... 0xD8F, not in this array */
}; };
#define NUM_X2APIC_MSR 44U #define NUM_X2APIC_MSRS 44U
static const uint32_t x2apic_msrs[NUM_X2APIC_MSR] = { static const uint32_t x2apic_msrs[NUM_X2APIC_MSRS] = {
MSR_IA32_EXT_XAPICID, MSR_IA32_EXT_XAPICID,
MSR_IA32_EXT_APIC_VERSION, MSR_IA32_EXT_APIC_VERSION,
MSR_IA32_EXT_APIC_TPR, MSR_IA32_EXT_APIC_TPR,
@ -241,7 +249,7 @@ static void intercept_x2apic_msrs(uint8_t *msr_bitmap_arg, enum rw_mode mode)
uint8_t *msr_bitmap = msr_bitmap_arg; uint8_t *msr_bitmap = msr_bitmap_arg;
uint32_t i; uint32_t i;
for (i = 0U; i < NUM_X2APIC_MSR; i++) { for (i = 0U; i < NUM_X2APIC_MSRS; i++) {
enable_msr_interception(msr_bitmap, x2apic_msrs[i], mode); enable_msr_interception(msr_bitmap, x2apic_msrs[i], mode);
} }
} }
@ -263,12 +271,20 @@ void init_msr_emulation(struct acrn_vcpu *vcpu)
if (is_vcpu_bsp(vcpu)) { if (is_vcpu_bsp(vcpu)) {
msr_bitmap = vcpu->vm->arch_vm.msr_bitmap; msr_bitmap = vcpu->vm->arch_vm.msr_bitmap;
for (i = 0U; i < NUM_EMULATED_MSR; i++) { for (i = 0U; i < NUM_GUEST_MSRS; i++) {
enable_msr_interception(msr_bitmap, emulated_msrs[i], READ_WRITE); enable_msr_interception(msr_bitmap, emulated_guest_msrs[i], READ_WRITE);
}
for (i = 0U; i < NUM_MTRR_MSRS; i++) {
enable_msr_interception(msr_bitmap, mtrr_msrs[i], READ_WRITE);
} }
intercept_x2apic_msrs(msr_bitmap, READ_WRITE); intercept_x2apic_msrs(msr_bitmap, READ_WRITE);
for (i = 0U; i < NUM_UNSUPPORTED_MSRS; i++) {
enable_msr_interception(msr_bitmap, unsupported_msrs[i], READ_WRITE);
}
/* RDT-A disabled: CPUID.07H.EBX[12], CPUID.10H */ /* RDT-A disabled: CPUID.07H.EBX[12], CPUID.10H */
for (msr = MSR_IA32_L3_MASK_0; msr < MSR_IA32_BNDCFGS; msr++) { for (msr = MSR_IA32_L3_MASK_0; msr < MSR_IA32_BNDCFGS; msr++) {
enable_msr_interception(msr_bitmap, msr, READ_WRITE); enable_msr_interception(msr_bitmap, msr, READ_WRITE);

View File

@ -166,6 +166,10 @@ struct ext_context {
#define NORMAL_WORLD 0 #define NORMAL_WORLD 0
#define SECURE_WORLD 1 #define SECURE_WORLD 1
#define NUM_WORLD_MSRS 1U
#define NUM_COMMON_MSRS 6U
#define NUM_GUEST_MSRS (NUM_WORLD_MSRS + NUM_COMMON_MSRS)
struct event_injection_info { struct event_injection_info {
uint32_t intr_info; uint32_t intr_info;
uint32_t error_code; uint32_t error_code;
@ -174,6 +178,9 @@ struct event_injection_info {
struct cpu_context { struct cpu_context {
struct run_context run_ctx; struct run_context run_ctx;
struct ext_context ext_ctx; struct ext_context ext_ctx;
/* per world MSRs, need isolation between secure and normal world */
uint32_t world_msrs[NUM_WORLD_MSRS];
}; };
/* Intel SDM 24.8.2, the address must be 16-byte aligned */ /* Intel SDM 24.8.2, the address must be 16-byte aligned */
@ -201,6 +208,9 @@ struct acrn_vcpu_arch {
int cur_context; int cur_context;
struct cpu_context contexts[NR_WORLD]; struct cpu_context contexts[NR_WORLD];
/* common MSRs, world_msrs[] is a subset of it */
uint64_t guest_msrs[NUM_GUEST_MSRS];
uint16_t vpid; uint16_t vpid;
/* Holds the information needed for IRQ/exception handling. */ /* Holds the information needed for IRQ/exception handling. */