Extend using the vmcb12 control clean field to determine which vmcb12.save registers were marked dirty in order to minimize register copies by including the CR bit. This patch also fixes the init of last_vmcb12_gpa by using an invalid physical address instead of 0. Tested: kvm-unit-tests kvm selftests Fedora L1 L2 Signed-off-by: Cathy Avery <cavery@xxxxxxxxxx> --- arch/x86/kvm/svm/nested.c | 9 ++++++--- arch/x86/kvm/svm/svm.c | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 8523f60adb92..6f9a40e002bc 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -449,9 +449,12 @@ static void nested_vmcb02_prepare_save(struct vcpu_svm *svm, struct vmcb *vmcb12 } kvm_set_rflags(&svm->vcpu, vmcb12->save.rflags | X86_EFLAGS_FIXED); - svm_set_efer(&svm->vcpu, vmcb12->save.efer); - svm_set_cr0(&svm->vcpu, vmcb12->save.cr0); - svm_set_cr4(&svm->vcpu, vmcb12->save.cr4); + + if (unlikely(new_vmcb12 || vmcb_is_dirty(vmcb12, VMCB_CR))) { + svm_set_efer(&svm->vcpu, vmcb12->save.efer); + svm_set_cr0(&svm->vcpu, vmcb12->save.cr0); + svm_set_cr4(&svm->vcpu, vmcb12->save.cr4); + } svm->vcpu.arch.cr2 = vmcb12->save.cr2; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 271196400495..41f5cd1009ca 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1234,7 +1234,7 @@ static void init_vmcb(struct kvm_vcpu *vcpu) svm->asid = 0; svm->nested.vmcb12_gpa = 0; - svm->nested.last_vmcb12_gpa = 0; + svm->nested.last_vmcb12_gpa = -1; vcpu->arch.hflags = 0; if (!kvm_pause_in_guest(vcpu->kvm)) { -- 2.26.2