@@ -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);
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(-)