• Maxim Levitsky's avatar
    KVM: nSVM: improve SYSENTER emulation on AMD · adc2a237
    Maxim Levitsky authored
    Currently to support Intel->AMD migration, if CPU vendor is GenuineIntel,
    we emulate the full 64 value for MSR_IA32_SYSENTER_{EIP|ESP}
    msrs, and we also emulate the sysenter/sysexit instruction in long mode.
    
    (Emulator does still refuse to emulate sysenter in 64 bit mode, on the
    ground that the code for that wasn't tested and likely has no users)
    
    However when virtual vmload/vmsave is enabled, the vmload instruction will
    update these 32 bit msrs without triggering their msr intercept,
    which will lead to having stale values in kvm's shadow copy of these msrs,
    which relies on the intercept to be up to date.
    
    Fix/optimize this by doing the following:
    
    1. Enable the MSR intercepts for SYSENTER MSRs iff vendor=GenuineIntel
       (This is both a tiny optimization and also ensures that in case
       the guest cpu vendor is AMD, the msrs will be 32 bit wide as
       AMD defined).
    
    2. Store only high 32 bit part of these msrs on interception and combine
       it with hardware msr value on intercepted read/writes
       iff vendor=GenuineIntel.
    
    3. Disable vmload/vmsave virtualization if vendor=GenuineIntel.
       (It is somewhat insane to set vendor=GenuineIntel and still enable
       SVM for the guest but well whatever).
       Then zero the high 32 bit parts when kvm intercepts and emulates vmload.
    
    Thanks a lot to Paulo Bonzini for helping me with fixing this in the most
    correct way.
    
    This patch fixes nested migration of 32 bit nested guests, that was
    broken because incorrect cached values of SYSENTER msrs were stored in
    the migration stream if L1 changed these msrs with
    vmload prior to L2 entry.
    Signed-off-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
    Message-Id: <20210401111928.996871-3-mlevitsk@redhat.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    adc2a237
svm.c 123 KB