When nested NPT is enabled and KVM_SET_NESTED_STATE is used to restore an old checkpoint (without a valid gPAT), the current IA32_PAT value must be copied to vmcb02->save.g_pat.
Unfortunately, the current IA32_PAT value may be restored by KVM_SET_MSRS after KVM_SET_NESTED_STATE. Introduce a new boolean, svm->nested.restore_gpat_from_pat. If set, svm_vcpu_pre_run() will copy vcpu->arch.pat to vmcb02->save.g_pat and clear the boolean. Signed-off-by: Jim Mattson <[email protected]> --- arch/x86/kvm/svm/nested.c | 9 ++++++--- arch/x86/kvm/svm/svm.c | 8 ++++++++ arch/x86/kvm/svm/svm.h | 6 ++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index c50fb7172672..61a3e7226cde 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1958,9 +1958,12 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu, if (ret) goto out_free; - if (is_guest_mode(vcpu) && nested_npt_enabled(svm) && - (kvm_state.hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT)) - svm->vmcb->save.g_pat = save_cached.g_pat; + if (is_guest_mode(vcpu) && nested_npt_enabled(svm)) { + svm->nested.restore_gpat_from_pat = + !(kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT); + if (kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT) + svm->vmcb->save.g_pat = save_cached.g_pat; + } svm->nested.force_msr_bitmap_recalc = true; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 3f8581adf0c1..5dceab9f4c3f 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4217,9 +4217,17 @@ static void svm_cancel_injection(struct kvm_vcpu *vcpu) static int svm_vcpu_pre_run(struct kvm_vcpu *vcpu) { + struct vcpu_svm *svm = to_svm(vcpu); + if (to_kvm_sev_info(vcpu->kvm)->need_init) return -EINVAL; + if (svm->nested.restore_gpat_from_pat) { + svm->vmcb->save.g_pat = vcpu->arch.pat; + vmcb_mark_dirty(svm->vmcb, VMCB_NPT); + svm->nested.restore_gpat_from_pat = false; + } + return 1; } diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 39138378531e..1964ab6e45f4 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -219,6 +219,12 @@ struct svm_nested_state { * on its side. */ bool force_msr_bitmap_recalc; + + /* + * Indicates that vcpu->arch.pat should be copied to + * vmcb02->save.g_pat at the next vcpu_run. + */ + bool restore_gpat_from_pat; }; struct vcpu_sev_es_state { -- 2.52.0.457.g6b5491de43-goog

