Skip to content

Commit c85e35d

Browse files
Sainath Grandhilijinxia
authored andcommitted
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>
1 parent cf4d191 commit c85e35d

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,7 @@ vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new)
17181718
if ((new & APICBASE_X2APIC) == APICBASE_X2APIC) {
17191719
vlapic->msr_apicbase = new;
17201720
vlapic_build_x2apic_id(vlapic);
1721+
switch_apicv_mode_x2apic(vlapic->vcpu);
17211722
return 0;
17221723
}
17231724
}

hypervisor/arch/x86/guest/vmsr.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,22 @@ int wrmsr_vmexit_handler(struct vcpu *vcpu)
427427

428428
return err;
429429
}
430+
431+
void update_msr_bitmap_x2apic_apicv(struct vcpu *vcpu)
432+
{
433+
uint8_t *msr_bitmap;
434+
435+
msr_bitmap = vcpu->vm->arch_vm.msr_bitmap;
436+
intercept_x2apic_msrs(msr_bitmap, WRITE);
437+
enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_CUR_COUNT, READ);
438+
/*
439+
* Open read-only interception for write-only
440+
* registers to inject gp on reads. EOI and Self-IPI
441+
* Writes are disabled for EOI, TPR and Self-IPI as
442+
* writes to them are virtualized with Register Virtualization
443+
* Refer to Section 29.1 in Intel SDM Vol. 3
444+
*/
445+
enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_TPR, DISABLE);
446+
enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_EOI, READ);
447+
enable_msr_interception(msr_bitmap, MSR_IA32_EXT_APIC_SELF_IPI, READ);
448+
}

hypervisor/arch/x86/vmx.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ static uint64_t cr4_host_mask;
2626
static uint64_t cr4_always_on_mask;
2727
static uint64_t cr4_always_off_mask;
2828

29+
void update_msr_bitmap_x2apic_apicv(struct vcpu *vcpu);
30+
2931
bool is_vmx_disabled(void)
3032
{
3133
uint64_t msr_val;
@@ -1052,3 +1054,13 @@ void init_vmcs(struct vcpu *vcpu)
10521054
init_entry_ctrl(vcpu);
10531055
init_exit_ctrl();
10541056
}
1057+
1058+
void switch_apicv_mode_x2apic(struct vcpu *vcpu)
1059+
{
1060+
uint32_t value32;
1061+
value32 = exec_vmread32(VMX_PROC_VM_EXEC_CONTROLS2);
1062+
value32 &= ~VMX_PROCBASED_CTLS2_VAPIC;
1063+
value32 |= VMX_PROCBASED_CTLS2_VX2APIC;
1064+
exec_vmwrite32(VMX_PROC_VM_EXEC_CONTROLS2, value32);
1065+
update_msr_bitmap_x2apic_apicv(vcpu);
1066+
}

hypervisor/include/arch/x86/vmx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ int vmx_wrmsr_pat(struct vcpu *vcpu, uint64_t value);
464464
void vmx_write_cr0(struct vcpu *vcpu, uint64_t cr0);
465465
void vmx_write_cr4(struct vcpu *vcpu, uint64_t cr4);
466466
bool is_vmx_disabled(void);
467+
void switch_apicv_mode_x2apic(struct vcpu *vcpu);
467468

468469
static inline enum vm_cpu_mode get_vcpu_mode(const struct vcpu *vcpu)
469470
{

0 commit comments

Comments
 (0)