mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-01 07:49:39 +00:00
hv: Switch APICv from MMIO to MSR for x2APIC mode of guest vLAPIC
When guest switches from xAPIC mode to x2APIC mode of vLAPIC operation, MSRs are used to access vLAPIC. This patch adds APICv support for MSR accesses to vLAPIC. Switching from xAPIC to x2APIC is supported via APIC BASE MSR. Other modifications like disabling and switching back to xAPIC are not supported. 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:
parent
cf4d191272
commit
c85e35d31b
@ -1718,6 +1718,7 @@ vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new)
|
||||
if ((new & APICBASE_X2APIC) == APICBASE_X2APIC) {
|
||||
vlapic->msr_apicbase = new;
|
||||
vlapic_build_x2apic_id(vlapic);
|
||||
switch_apicv_mode_x2apic(vlapic->vcpu);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -427,3 +427,22 @@ int wrmsr_vmexit_handler(struct vcpu *vcpu)
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void update_msr_bitmap_x2apic_apicv(struct 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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ static uint64_t cr4_host_mask;
|
||||
static uint64_t cr4_always_on_mask;
|
||||
static uint64_t cr4_always_off_mask;
|
||||
|
||||
void update_msr_bitmap_x2apic_apicv(struct vcpu *vcpu);
|
||||
|
||||
bool is_vmx_disabled(void)
|
||||
{
|
||||
uint64_t msr_val;
|
||||
@ -1052,3 +1054,13 @@ void init_vmcs(struct vcpu *vcpu)
|
||||
init_entry_ctrl(vcpu);
|
||||
init_exit_ctrl();
|
||||
}
|
||||
|
||||
void switch_apicv_mode_x2apic(struct vcpu *vcpu)
|
||||
{
|
||||
uint32_t value32;
|
||||
value32 = exec_vmread32(VMX_PROC_VM_EXEC_CONTROLS2);
|
||||
value32 &= ~VMX_PROCBASED_CTLS2_VAPIC;
|
||||
value32 |= VMX_PROCBASED_CTLS2_VX2APIC;
|
||||
exec_vmwrite32(VMX_PROC_VM_EXEC_CONTROLS2, value32);
|
||||
update_msr_bitmap_x2apic_apicv(vcpu);
|
||||
}
|
||||
|
@ -464,6 +464,7 @@ int vmx_wrmsr_pat(struct vcpu *vcpu, uint64_t value);
|
||||
void vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0);
|
||||
void vmx_write_cr4(struct vcpu *vcpu, uint64_t cr4);
|
||||
bool is_vmx_disabled(void);
|
||||
void switch_apicv_mode_x2apic(struct vcpu *vcpu);
|
||||
|
||||
static inline enum vm_cpu_mode get_vcpu_mode(const struct vcpu *vcpu)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user