lkml.org 
[lkml]   [2022]   [Sep]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v4 01/32] KVM: x86: Blindly get current x2APIC reg value on "nodecode write" traps
    From
    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: 70c8327c11c6 ("KVM: x86: Bug the VM if an accelerated x2APIC trap occurs on a "bad" reg")
    Fixes: 1bd9dfec9fd4 ("KVM: x86: Do not block APIC write for non ICR registers")
    Reported-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: Sean Christopherson <seanjc@google.com>
    ---
    arch/x86/kvm/lapic.c | 9 ++-------
    1 file changed, 2 insertions(+), 7 deletions(-)

    diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
    index d7639d126e6c..05d079fc2c66 100644
    --- a/arch/x86/kvm/lapic.c
    +++ b/arch/x86/kvm/lapic.c
    @@ -2284,23 +2284,18 @@ void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset)
    struct kvm_lapic *apic = vcpu->arch.apic;
    u64 val;

    - if (apic_x2apic_mode(apic)) {
    - if (KVM_BUG_ON(kvm_lapic_msr_read(apic, offset, &val), vcpu->kvm))
    - return;
    - } else {
    - val = kvm_lapic_get_reg(apic, offset);
    - }
    -
    /*
    * ICR is a single 64-bit register when x2APIC is enabled. For legacy
    * xAPIC, ICR writes need to go down the common (slightly slower) path
    * to get the upper half from ICR2.
    */
    if (apic_x2apic_mode(apic) && offset == APIC_ICR) {
    + val = kvm_lapic_get_reg64(apic, APIC_ICR);
    kvm_apic_send_ipi(apic, (u32)val, (u32)(val >> 32));
    trace_kvm_apic_write(APIC_ICR, val);
    } else {
    /* TODO: optimize to just emulate side effect w/o one more write */
    + val = kvm_lapic_get_reg(apic, offset);
    kvm_lapic_reg_write(apic, offset, (u32)val);
    }
    }
    --
    2.38.0.rc1.362.ged0d419d3c-goog
    \
     
     \ /
      Last update: 2022-10-01 03:00    [W:4.107 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site