hv: Modify enable_msr_interception API

Extending enable_msr_interception to accept mode as input. Mode specifies
if the API user wants ACRN to intercept on read-only or write-only or both
read and write or disable MSR interception altogether.

Tracked-On: #1626
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Reviewed-by: Xu Anthony <anthony.xu@intel.com>
This commit is contained in:
Sainath Grandhi 2018-11-01 14:32:35 -07:00 committed by lijinxia
parent 64f61961bf
commit 7ecc521cf5

View File

@ -7,6 +7,13 @@
#include <hypervisor.h> #include <hypervisor.h>
#include <ucode.h> #include <ucode.h>
enum rw_mode {
DISABLE = 0U,
READ,
WRITE,
READ_WRITE
};
/*MRS need to be emulated, the order in this array better as freq of ops*/ /*MRS need to be emulated, the order in this array better as freq of ops*/
static const uint32_t emulated_msrs[] = { static const uint32_t emulated_msrs[] = {
MSR_IA32_TSC_DEADLINE, /* Enable TSC_DEADLINE VMEXIT */ MSR_IA32_TSC_DEADLINE, /* Enable TSC_DEADLINE VMEXIT */
@ -72,12 +79,13 @@ static const uint32_t x2apic_msrs[] = {
MSR_IA32_EXT_APIC_SELF_IPI, MSR_IA32_EXT_APIC_SELF_IPI,
}; };
static void enable_msr_interception(uint8_t *bitmap, uint32_t msr_arg) static void enable_msr_interception(uint8_t *bitmap, uint32_t msr_arg, enum rw_mode mode)
{ {
uint8_t *read_map; uint8_t *read_map;
uint8_t *write_map; uint8_t *write_map;
uint8_t value;
uint32_t msr = msr_arg; uint32_t msr = msr_arg;
uint8_t msr_bit;
uint32_t msr_index;
/* low MSR */ /* low MSR */
if (msr < 0x1FFFU) { if (msr < 0x1FFFU) {
read_map = bitmap; read_map = bitmap;
@ -91,11 +99,20 @@ static void enable_msr_interception(uint8_t *bitmap, uint32_t msr_arg)
} }
msr &= 0x1FFFU; msr &= 0x1FFFU;
value = read_map[(msr >> 3U)]; msr_bit = 1U << (msr & 0x7U);
value |= 1U << (msr & 0x7U); msr_index = msr >> 3U;
/* right now we trap for both r/w */
read_map[(msr >> 3U)] = value; if ((mode & READ) == READ) {
write_map[(msr >> 3U)] = value; read_map[msr_index] |= msr_bit;
} else {
read_map[msr_index] &= ~msr_bit;
}
if ((mode & WRITE) == WRITE) {
write_map[msr_index] |= msr_bit;
} else {
write_map[msr_index] &= ~msr_bit;
}
} }
/* /*
@ -105,13 +122,13 @@ static void enable_msr_interception(uint8_t *bitmap, uint32_t msr_arg)
* 0x802 and 0x83F, are not intercepted * 0x802 and 0x83F, are not intercepted
*/ */
static void intercept_x2apic_msrs(uint8_t *msr_bitmap_arg) 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 < ARRAY_SIZE(x2apic_msrs); i++) { for (i = 0U; i < ARRAY_SIZE(x2apic_msrs); i++) {
enable_msr_interception(msr_bitmap, x2apic_msrs[i]); enable_msr_interception(msr_bitmap, x2apic_msrs[i], mode);
} }
} }
@ -130,35 +147,35 @@ void init_msr_emulation(struct vcpu *vcpu)
msr_bitmap = vcpu->vm->arch_vm.msr_bitmap; msr_bitmap = vcpu->vm->arch_vm.msr_bitmap;
for (i = 0U; i < msrs_count; i++) { for (i = 0U; i < msrs_count; i++) {
enable_msr_interception(msr_bitmap, emulated_msrs[i]); enable_msr_interception(msr_bitmap, emulated_msrs[i], READ_WRITE);
} }
enable_msr_interception(msr_bitmap, MSR_IA32_PERF_CTL); enable_msr_interception(msr_bitmap, MSR_IA32_PERF_CTL, READ_WRITE);
/* below MSR protected from guest OS, if access to inject gp*/ /* below MSR protected from guest OS, if access to inject gp*/
enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_CAP); enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_CAP, READ_WRITE);
enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_DEF_TYPE); enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_DEF_TYPE, READ_WRITE);
for (i = MSR_IA32_MTRR_PHYSBASE_0; for (i = MSR_IA32_MTRR_PHYSBASE_0;
i <= MSR_IA32_MTRR_PHYSMASK_9; i++) { i <= MSR_IA32_MTRR_PHYSMASK_9; i++) {
enable_msr_interception(msr_bitmap, i); enable_msr_interception(msr_bitmap, i, READ_WRITE);
} }
enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_FIX64K_00000); enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_FIX64K_00000, READ_WRITE);
enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_FIX16K_80000); enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_FIX16K_80000, READ_WRITE);
enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_FIX16K_A0000); enable_msr_interception(msr_bitmap, MSR_IA32_MTRR_FIX16K_A0000, READ_WRITE);
for (i = MSR_IA32_MTRR_FIX4K_C0000; for (i = MSR_IA32_MTRR_FIX4K_C0000;
i <= MSR_IA32_MTRR_FIX4K_F8000; i++) { i <= MSR_IA32_MTRR_FIX4K_F8000; i++) {
enable_msr_interception(msr_bitmap, i); enable_msr_interception(msr_bitmap, i, READ_WRITE);
} }
for (i = MSR_IA32_VMX_BASIC; for (i = MSR_IA32_VMX_BASIC;
i <= MSR_IA32_VMX_TRUE_ENTRY_CTLS; i++) { i <= MSR_IA32_VMX_TRUE_ENTRY_CTLS; i++) {
enable_msr_interception(msr_bitmap, i); enable_msr_interception(msr_bitmap, i, READ_WRITE);
} }
intercept_x2apic_msrs(msr_bitmap); intercept_x2apic_msrs(msr_bitmap, READ_WRITE);
} }
/* Set up MSR bitmap - pg 2904 24.6.9 */ /* Set up MSR bitmap - pg 2904 24.6.9 */