diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index b77a376c4..45ca2b6be 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -869,6 +869,11 @@ bool is_ept_supported(void) return (cpu_caps.ept_features != 0U); } +bool is_apicv_reg_virtualization_supported(void) +{ + return ((cpu_caps.apicv_features & VAPIC_FEATURE_VIRT_REG) != 0U); +} + bool is_apicv_intr_delivery_supported(void) { return ((cpu_caps.apicv_features & VAPIC_FEATURE_INTR_DELIVERY) != 0U); diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index e6e03b3d2..61ab6f6b2 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -469,18 +469,28 @@ void update_msr_bitmap_x2apic_apicv(struct acrn_vcpu *vcpu) uint8_t *msr_bitmap; msr_bitmap = vcpu->vm->arch_vm.msr_bitmap; - intercept_x2apic_msrs(msr_bitmap, WRITE); - enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_CUR_COUNT, READ); /* - * Open read-only interception for write-only - * registers to inject gp on reads. EOI and Self-IPI - * Writes are disabled for EOI, TPR and Self-IPI as - * writes to them are virtualized with Register Virtualization - * Refer to Section 29.1 in Intel SDM Vol. 3 + * For platforms that do not support register virtualization + * all x2APIC MSRs need to intercepted. So no need to update + * the MSR bitmap. + * + * TPR is virtualized even when register virtualization is not + * supported */ - enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_TPR, DISABLE); - enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_EOI, READ); - enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_SELF_IPI, READ); + if (is_apicv_reg_virtualization_supported()) { + intercept_x2apic_msrs(msr_bitmap, WRITE); + enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_CUR_COUNT, READ); + /* + * Open read-only interception for write-only + * registers to inject gp on reads. EOI and Self-IPI + * Writes are disabled for EOI, TPR and Self-IPI as + * writes to them are virtualized with Register Virtualization + * Refer to Section 29.1 in Intel SDM Vol. 3 + */ + enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_TPR, DISABLE); + enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_EOI, READ); + enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_SELF_IPI, READ); + } } void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu) diff --git a/hypervisor/include/arch/x86/cpu.h b/hypervisor/include/arch/x86/cpu.h index ffcdce466..179764e34 100644 --- a/hypervisor/include/arch/x86/cpu.h +++ b/hypervisor/include/arch/x86/cpu.h @@ -311,6 +311,7 @@ extern struct cpuinfo_x86 boot_cpu_data; void cpu_do_idle(void); void cpu_dead(uint16_t pcpu_id); void trampoline_start16(void); +bool is_apicv_reg_virtualization_supported(void); bool is_apicv_intr_delivery_supported(void); bool is_apicv_posted_intr_supported(void); bool is_ept_supported(void);