• Liran Alon's avatar
    KVM: nVMX: Verify eVMCS revision id match supported eVMCS version on eVMCS VMPTRLD · 72aeb60c
    Liran Alon authored
    According to TLFS section 16.11.2 Enlightened VMCS, the first u32
    field of eVMCS should specify eVMCS VersionNumber.
    
    This version should be in the range of supported eVMCS versions exposed
    to guest via CPUID.0x4000000A.EAX[0:15].
    The range which KVM expose to guest in this CPUID field should be the
    same as the value returned in vmcs_version by nested_enable_evmcs().
    
    According to the above, eVMCS VMPTRLD should verify that version specified
    in given eVMCS is in the supported range. However, current code
    mistakenly verfies this field against VMCS12_REVISION.
    
    One can also see that when KVM use eVMCS, it makes sure that
    alloc_vmcs_cpu() sets allocated eVMCS revision_id to KVM_EVMCS_VERSION.
    
    Obvious fix should just change eVMCS VMPTRLD to verify first u32 field
    of eVMCS is equal to KVM_EVMCS_VERSION.
    However, it turns out that Microsoft Hyper-V fails to comply to their
    own invented interface: When Hyper-V use eVMCS, it just sets first u32
    field of eVMCS to revision_id specified in MSR_IA32_VMX_BASIC (In our
    case: VMCS12_REVISION). Instead of used eVMCS version number which is
    one of the supported versions specified in CPUID.0x4000000A.EAX[0:15].
    To overcome Hyper-V bug, we accept either a supported eVMCS version
    or VMCS12_REVISION as valid values for first u32 field of eVMCS.
    
    Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
    Reviewed-by: default avatarNikita Leshenko <nikita.leshchenko@oracle.com>
    Reviewed-by: default avatarMark Kanda <mark.kanda@oracle.com>
    Signed-off-by: default avatarLiran Alon <liran.alon@oracle.com>
    Reviewed-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    72aeb60c
vmx.c 436 KB