Previously, KVM didn't record the vmcb01 G_PAT (i.e. the IA32_PAT MSR)
in the serialized nested state. It didn't have to, because it ignored
the vmcb12 g_pat field entirely. L1 and L2 simply shared the same PAT.
To preserve legacy behavior, copy the current value of the IA32_PAT
MSR to the location of the vmcb01 G_PAT in the serialized nested
state. (On restore, KVM_SET_MSRS should be called before
KVM_SET_NESTED_STATE, so the value of the shared IA32_PAT MSR should
be available.)
Signed-off-by: Jim Mattson <jmattson@google.com>
---
arch/x86/kvm/svm/nested.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index ed24e08d2d21..c751be470364 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -1884,6 +1884,13 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
if (((cr0 & X86_CR0_CD) == 0) && (cr0 & X86_CR0_NW))
goto out_free;
+ /*
+ * If kvm_state doesn't have a valid saved L1 g_pat, use the
+ * PAT MSR instead. This preserves the legacy behavior.
+ */
+ if (!(kvm_state->hdr.svm.flags & KVM_STATE_SVM_VALID_GPAT))
+ save->g_pat = vcpu->arch.pat;
+
/*
* Validate host state saved from before VMRUN (see
* nested_svm_check_permissions).
--
2.52.0.457.g6b5491de43-goog