lkml.org 
[lkml]   [2020]   [Feb]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 130/173] KVM: x86: Fix potential put_fpu() w/o load_fpu() on MPX platform
    Date
    From: Sean Christopherson <sean.j.christopherson@intel.com>

    [ Upstream commit f958bd2314d117f8c29f4821401bc1925bc2e5ef ]

    Unlike most state managed by XSAVE, MPX is initialized to zero on INIT.
    Because INITs are usually recognized in the context of a VCPU_RUN call,
    kvm_vcpu_reset() puts the guest's FPU so that the FPU state is resident
    in memory, zeros the MPX state, and reloads FPU state to hardware. But,
    in the unlikely event that an INIT is recognized during
    kvm_arch_vcpu_ioctl_get_mpstate() via kvm_apic_accept_events(),
    kvm_vcpu_reset() will call kvm_put_guest_fpu() without a preceding
    kvm_load_guest_fpu() and corrupt the guest's FPU state (and possibly
    userspace's FPU state as well).

    Given that MPX is being removed from the kernel[*], fix the bug with the
    simple-but-ugly approach of loading the guest's FPU during
    KVM_GET_MP_STATE.

    [*] See commit f240652b6032b ("x86/mpx: Remove MPX APIs").

    Fixes: f775b13eedee2 ("x86,kvm: move qemu/guest FPU switching out to vcpu_run")
    Cc: stable@vger.kernel.org
    Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/x86/kvm/x86.c | 5 +++++
    1 file changed, 5 insertions(+)

    diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
    index b6d80c0190563..d915ea0e69cfd 100644
    --- a/arch/x86/kvm/x86.c
    +++ b/arch/x86/kvm/x86.c
    @@ -7677,6 +7677,9 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
    int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
    struct kvm_mp_state *mp_state)
    {
    + if (kvm_mpx_supported())
    + kvm_load_guest_fpu(vcpu);
    +
    kvm_apic_accept_events(vcpu);
    if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED &&
    vcpu->arch.pv.pv_unhalted)
    @@ -7684,6 +7687,8 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
    else
    mp_state->mp_state = vcpu->arch.mp_state;

    + if (kvm_mpx_supported())
    + kvm_put_guest_fpu(vcpu);
    return 0;
    }

    --
    2.20.1


    \
     
     \ /
      Last update: 2020-02-13 16:54    [W:4.484 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site