[PATCH v3 5/6] KVM: x86: Support interrupt dispatch in x2APIC mode with APIC-write VM exit

Zeng Guang
2021-08-05T15:39:57Z

Since IA x86 platform introduce features of IPI virtualization and
User Interrupts, new behavior applies to the execution of WRMSR ICR
register that causes APIC-write VM exit instead of MSR-write VM exit
in x2APIC mode.

This requires KVM to emulate writing 64-bit value to offset 300H on
the virtual-APIC page(VICR) for guest running in x2APIC mode when
APIC-wrtie VM exit occurs. Prevoisely KVM doesn't consider this
situation as CPU never produce APIC-write VM exit in x2APIC mode before.

Signed-off-by: Zeng Guang <guang.zeng@intel.com>
---
arch/x86/kvm/lapic.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index ba5a27879f1d..0b0f0ce96679 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -2188,7 +2188,14 @@ void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset)
/* hw has done the conditional check and inst decode */
offset &= 0xff0;

- kvm_lapic_reg_read(vcpu->arch.apic, offset, 4, &val);
+ if (apic_x2apic_mode(vcpu->arch.apic) && (offset == APIC_ICR)) {
+ u64 icr_val = *((u64 *)(vcpu->arch.apic->regs + offset));
+
+ kvm_lapic_reg_write(vcpu->arch.apic, APIC_ICR2, (u32)(icr_val>>32));
+ val = (u32)icr_val;
+ } else {
+ kvm_lapic_reg_read(vcpu->arch.apic, offset, 4, &val);
+ }

/* TODO: optimize to just emulate side effect w/o one more write */
kvm_lapic_reg_write(vcpu->arch.apic, offset, val);
--
2.25.1