KVM doesn't implement a separate G_PAT register to hold the guest's PAT in guest mode with nested NPT enabled. Consequently, L1's IA32_PAT MSR must be restored on emulated #VMEXIT from L2 to L1.
Note: if L2 uses shadow paging, L1 and L2 share the same IA32_PAT MSR.
Signed-off-by: Jim Mattson jmattson@google.com --- arch/x86/kvm/svm/nested.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index c751be470364..9aec836ac04c 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -1292,6 +1292,16 @@ int nested_svm_vmexit(struct vcpu_svm *svm) kvm_rsp_write(vcpu, vmcb01->save.rsp); kvm_rip_write(vcpu, vmcb01->save.rip);
+ /* + * KVM doesn't implement a separate guest PAT + * register. Instead, the guest PAT lives in vcpu->arch.pat + * while in guest mode with nested NPT enabled. Hence, the + * IA32_PAT MSR has to be restored from the vmcb01 g_pat at + * #VMEXIT. + */ + if (nested_npt_enabled(svm)) + vcpu->arch.pat = vmcb01->save.g_pat; + svm->vcpu.arch.dr7 = DR7_FIXED_1; kvm_update_dr7(&svm->vcpu);