According to section 15.29.9.2 - AVIC Access to un-accelerated vAPIC register of the AMD APM [1]: "A guest access to an APIC register that is not accelerated by AVIC results in a #VMEXIT with the exit code of AVIC_NOACCEL. This fault is also generated if an EOI is attempted when the highest priority in-service interrupt is set for level-triggered mode." This is also stated in Table 15-22 - Guest vAPIC Register Access Behavior, confirming that AVIC hardware traps on EOI writes for level triggered interrupts, and leading to the following call stack: avic_unaccelerated_access_interception() -> avic_unaccel_trap_write() -> kvm_apic_write_nodecode() -> kvm_lapic_msr_read() -> kvm_lapic_reg_read() In kvm_lapic_reg_read(), the APIC_EOI offset (0xb0) is not allowed as valid, so the error returned triggers the assertion introduced by 'commit 70c8327c11c6 ("KVM: x86: Bug the VM if an accelerated x2APIC trap occurs on a "bad" reg")' and kills the VM. Add APIC_EOI offset to the valid mask in kvm_lapic_reg_read() to allow the emulation of EOI behavior for level triggered interrupts. [1] https://www.amd.com/system/files/TechDocs/24593.pdf Fixes: 0105d1a52640 ("KVM: x2apic interface to lapic") Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@xxxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx --- I am unsure as to the proper commit to use for the Fixes: tag. Technically the issue was introduced by the initial SVM AVIC commits in 2016, since they failed to add the EOI offset to the valid mask. To be safe, I used the commit that introduces the valid mask, but that is somewhat misleading since at the time AVIC was not available, and I believe that Intel posted interrupts implementation does not require access to EOI offset in this code. Please correct Fixes: tag if necessary. --- arch/x86/kvm/lapic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 9dda989a1cf0..61041fecfa89 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1452,6 +1452,7 @@ static int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len, APIC_REG_MASK(APIC_LVR) | APIC_REG_MASK(APIC_TASKPRI) | APIC_REG_MASK(APIC_PROCPRI) | + APIC_REG_MASK(APIC_EOI) | APIC_REG_MASK(APIC_LDR) | APIC_REG_MASK(APIC_DFR) | APIC_REG_MASK(APIC_SPIV) | -- 2.34.2