static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
                                      bool has_error_code, u32 error_code);
 
+enum {
+       VMCB_DIRTY_MAX,
+};
+
+#define VMCB_ALWAYS_DIRTY_MASK 0U
+
+static inline void mark_all_dirty(struct vmcb *vmcb)
+{
+       vmcb->control.clean = 0;
+}
+
+static inline void mark_all_clean(struct vmcb *vmcb)
+{
+       vmcb->control.clean = ((1 << VMCB_DIRTY_MAX) - 1)
+                              & ~VMCB_ALWAYS_DIRTY_MASK;
+}
+
+static inline void mark_dirty(struct vmcb *vmcb, int bit)
+{
+       vmcb->control.clean &= ~(1 << bit);
+}
+
 static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
 {
        return container_of(vcpu, struct vcpu_svm, vcpu);
                set_intercept(svm, INTERCEPT_PAUSE);
        }
 
+       mark_all_dirty(svm->vmcb);
+
        enable_gif(svm);
 }
 
 
        if (unlikely(cpu != vcpu->cpu)) {
                svm->asid_generation = 0;
+               mark_all_dirty(svm->vmcb);
        }
 
 #ifdef CONFIG_X86_64
        svm->vmcb->save.cpl = 0;
        svm->vmcb->control.exit_int_info = 0;
 
+       mark_all_dirty(svm->vmcb);
+
        nested_svm_unmap(page);
 
        nested_svm_uninit_mmu_context(&svm->vcpu);
 
        enable_gif(svm);
 
+       mark_all_dirty(svm->vmcb);
+
        return true;
 }
 
        if (unlikely(svm->vmcb->control.exit_code ==
                     SVM_EXIT_EXCP_BASE + MC_VECTOR))
                svm_handle_mce(svm);
+
+       mark_all_clean(svm->vmcb);
 }
 
 #undef R