• Liran Alon's avatar
    KVM: nVMX: Update vmcs01 TPR_THRESHOLD if L2 changed L1 TPR · 02d496cf
    Liran Alon authored
    When L1 don't use TPR-Shadow to run L2, L0 configures vmcs02 without
    TPR-Shadow and install intercepts on CR8 access (load and store).
    
    If L1 do not intercept L2 CR8 access, L0 intercepts on those accesses
    will emulate load/store on L1's LAPIC TPR. If in this case L2 lowers
    TPR such that there is now an injectable interrupt to L1,
    apic_update_ppr() will request a KVM_REQ_EVENT which will trigger a call
    to update_cr8_intercept() to update TPR-Threshold to highest pending IRR
    priority.
    
    However, this update to TPR-Threshold is done while active vmcs is
    vmcs02 instead of vmcs01. Thus, when later at some point L0 will
    emulate an exit from L2 to L1, L1 will still run with high
    TPR-Threshold. This will result in every VMEntry to L1 to immediately
    exit on TPR_BELOW_THRESHOLD and continue to do so infinitely until
    some condition will cause KVM_REQ_EVENT to be set.
    (Note that TPR_BELOW_THRESHOLD exit handler do not set KVM_REQ_EVENT
    until apic_update_ppr() will notice a new injectable interrupt for PPR)
    
    To fix this issue, change update_cr8_intercept() such that if L2 lowers
    L1's TPR in a way that requires to lower L1's TPR-Threshold, save update
    to TPR-Threshold and apply it to vmcs01 when L0 emulates an exit from
    L2 to L1.
    Reviewed-by: default avatarJoao Martins <joao.m.martins@oracle.com>
    Signed-off-by: default avatarLiran Alon <liran.alon@oracle.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    02d496cf
vmx.c 219 KB