• Sean Christopherson's avatar
    KVM: SVM: Update EFER software model on CR0 trap for SEV-ES · 4cdf351d
    Sean Christopherson authored
    In general, activating long mode involves setting the EFER_LME bit in
    the EFER register and then enabling the X86_CR0_PG bit in the CR0
    register. At this point, the EFER_LMA bit will be set automatically by
    hardware.
    
    In the case of SVM/SEV guests where writes to CR0 are intercepted, it's
    necessary for the host to set EFER_LMA on behalf of the guest since
    hardware does not see the actual CR0 write.
    
    In the case of SEV-ES guests where writes to CR0 are trapped instead of
    intercepted, the hardware *does* see/record the write to CR0 before
    exiting and passing the value on to the host, so as part of enabling
    SEV-ES support commit f1c6366e ("KVM: SVM: Add required changes to
    support intercepts under SEV-ES") dropped special handling of the
    EFER_LMA bit with the understanding that it would be set automatically.
    
    However, since the guest never explicitly sets the EFER_LMA bit, the
    host never becomes aware that it has been set. This becomes problematic
    when userspace tries to get/set the EFER values via
    KVM_GET_SREGS/KVM_SET_SREGS, since the EFER contents tracked by the host
    will be missing the EFER_LMA bit, and when userspace attempts to pass
    the EFER value back via KVM_SET_SREGS it will fail a sanity check that
    asserts that EFER_LMA should always be set when X86_CR0_PG and EFER_LME
    are set.
    
    Fix this by always inferring the value of EFER_LMA based on X86_CR0_PG
    and EFER_LME, regardless of whether or not SEV-ES is enabled.
    
    Fixes: f1c6366e ("KVM: SVM: Add required changes to support intercepts under SEV-ES")
    Reported-by: default avatarPeter Gonda <pgonda@google.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
    Message-Id: <20210507165947.2502412-2-seanjc@google.com>
    [A two year old patch that was revived after we noticed the failure in
     KVM_SET_SREGS and a similar patch was posted by Michael Roth.  This is
     Sean's patch, but with Michael's more complete commit message. - Paolo]
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    4cdf351d
svm.c 147 KB