Skip to content

Commit baebc2c

Browse files
sean-jcjfvogel
authored andcommitted
KVM: x86: Blindly get current x2APIC reg value on "nodecode write" traps
When emulating a x2APIC write in response to an APICv/AVIC trap, get the the written value from the vAPIC page without checking that reads are allowed for the target register. AVIC can generate trap-like VM-Exits on writes to EOI, and so KVM needs to get the written value from the backing page without running afoul of EOI's write-only behavior. Alternatively, EOI could be special cased to always write '0', e.g. so that the sanity check could be preserved, but x2APIC on AMD is actually supposed to disallow non-zero writes (not emulated by KVM), and the sanity check was a byproduct of how the KVM code was written, i.e. wasn't added to guard against anything in particular. Fixes: 70c8327 ("KVM: x86: Bug the VM if an accelerated x2APIC trap occurs on a "bad" reg") Fixes: 1bd9dfe ("KVM: x86: Do not block APIC write for non ICR registers") Reported-by: Alejandro Jimenez <[email protected]> Cc: [email protected] Signed-off-by: Sean Christopherson <[email protected]> Orabug: 34817119 Signed-off-by: Alejandro Jimenez <[email protected]> Reviewed-by: Boris Ostrovsky <[email protected]> Taken from upstream mailing list: KVM: x86: Blindly get current x2APIC reg value on "nodecode write" traps https://lore.kernel.org/kvm/[email protected]/ (cherry picked from commit ea0ddb98af1d3fc90cd28fe07aa43a6690b8286c) Signed-off-by: Jack Vogel <[email protected]>
1 parent 5ed2803 commit baebc2c

File tree

1 file changed

+2
-7
lines changed

1 file changed

+2
-7
lines changed

arch/x86/kvm/lapic.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2260,23 +2260,18 @@ void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset)
22602260
struct kvm_lapic *apic = vcpu->arch.apic;
22612261
u64 val;
22622262

2263-
if (apic_x2apic_mode(apic)) {
2264-
if (KVM_BUG_ON(kvm_lapic_msr_read(apic, offset, &val), vcpu->kvm))
2265-
return;
2266-
} else {
2267-
val = kvm_lapic_get_reg(apic, offset);
2268-
}
2269-
22702263
/*
22712264
* ICR is a single 64-bit register when x2APIC is enabled. For legacy
22722265
* xAPIC, ICR writes need to go down the common (slightly slower) path
22732266
* to get the upper half from ICR2.
22742267
*/
22752268
if (apic_x2apic_mode(apic) && offset == APIC_ICR) {
2269+
val = kvm_lapic_get_reg64(apic, APIC_ICR);
22762270
kvm_apic_send_ipi(apic, (u32)val, (u32)(val >> 32));
22772271
trace_kvm_apic_write(APIC_ICR, val);
22782272
} else {
22792273
/* TODO: optimize to just emulate side effect w/o one more write */
2274+
val = kvm_lapic_get_reg(apic, offset);
22802275
kvm_lapic_reg_write(apic, offset, (u32)val);
22812276
}
22822277
}

0 commit comments

Comments
 (0)