• Liran Alon's avatar
    KVM: SVM: Fix detection of AMD Errata 1096 · 118154bd
    Liran Alon authored
    When CPU raise #NPF on guest data access and guest CR4.SMAP=1, it is
    possible that CPU microcode implementing DecodeAssist will fail
    to read bytes of instruction which caused #NPF. This is AMD errata
    1096 and it happens because CPU microcode reading instruction bytes
    incorrectly attempts to read code as implicit supervisor-mode data
    accesses (that is, just like it would read e.g. a TSS), which are
    susceptible to SMAP faults. The microcode reads CS:RIP and if it is
    a user-mode address according to the page tables, the processor
    gives up and returns no instruction bytes.  In this case,
    GuestIntrBytes field of the VMCB on a VMEXIT will incorrectly
    return 0 instead of the correct guest instruction bytes.
    
    Current KVM code attemps to detect and workaround this errata, but it
    has multiple issues:
    
    1) It mistakenly checks if guest CR4.SMAP=0 instead of guest CR4.SMAP=1,
    which is required for encountering a SMAP fault.
    
    2) It assumes SMAP faults can only occur when guest CPL==3.
    However, in case guest CR4.SMEP=0, the guest can execute an instruction
    which reside in a user-accessible page with CPL<3 priviledge. If this
    instruction raise a #NPF on it's data access, then CPU DecodeAssist
    microcode will still encounter a SMAP violation.  Even though no sane
    OS will do so (as it's an obvious priviledge escalation vulnerability),
    we still need to handle this semanticly correct in KVM side.
    
    Note that (2) *is* a useful optimization, because CR4.SMAP=1 is an easy
    triggerable condition and guests usually enable SMAP together with SMEP.
    If the vCPU has CR4.SMEP=1, the errata could indeed be encountered onlt
    at guest CPL==3; otherwise, the CPU would raise a SMEP fault to guest
    instead of #NPF.  We keep this condition to avoid false positives in
    the detection of the errata.
    
    In addition, to avoid future confusion and improve code readbility,
    include details of the errata in code and not just in commit message.
    
    Fixes: 05d5a486 ("KVM: SVM: Workaround errata#1096 (insn_len maybe zero on SMAP violation)")
    Cc: Singh Brijesh <brijesh.singh@amd.com>
    Cc: Sean Christopherson <sean.j.christopherson@intel.com>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Reviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
    Signed-off-by: default avatarLiran Alon <liran.alon@oracle.com>
    Reviewed-by: default avatarBrijesh Singh <brijesh.singh@amd.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    118154bd
svm.c 187 KB