KVM: SVM: include CR3 in initial VMSA state for SEV-ES guests
[linux-block.git] / arch / x86 / kvm / svm / svm.c
index 5557867dcb6950c596f5bbdc5aec517ee02acfe0..c3d9006478a424c5bfad6a2cc29baa3d3b8cdf83 100644 (file)
@@ -1801,6 +1801,24 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
        vmcb_mark_dirty(svm->vmcb, VMCB_DT);
 }
 
+static void svm_post_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
+{
+       struct vcpu_svm *svm = to_svm(vcpu);
+
+       /*
+        * For guests that don't set guest_state_protected, the cr3 update is
+        * handled via kvm_mmu_load() while entering the guest. For guests
+        * that do (SEV-ES/SEV-SNP), the cr3 update needs to be written to
+        * VMCB save area now, since the save area will become the initial
+        * contents of the VMSA, and future VMCB save area updates won't be
+        * seen.
+        */
+       if (sev_es_guest(vcpu->kvm)) {
+               svm->vmcb->save.cr3 = cr3;
+               vmcb_mark_dirty(svm->vmcb, VMCB_CR);
+       }
+}
+
 void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
@@ -4624,6 +4642,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
        .get_cpl = svm_get_cpl,
        .get_cs_db_l_bits = kvm_get_cs_db_l_bits,
        .set_cr0 = svm_set_cr0,
+       .post_set_cr3 = svm_post_set_cr3,
        .is_valid_cr4 = svm_is_valid_cr4,
        .set_cr4 = svm_set_cr4,
        .set_efer = svm_set_efer,