+#if defined(CONFIG_KVM_VIRT_SUSPEND_TIMING) || \
+ defined(CONFIG_KVM_VIRT_SUSPEND_TIMING_GUEST)
+#define VIRT_SUSPEND_TIMING_VECTOR 0xec
+#endif
+static void kvm_make_suspend_time_interrupt(struct kvm_vcpu *vcpu)
+{
+ kvm_queue_interrupt(vcpu, VIRT_SUSPEND_TIMING_VECTOR, false);
+ kvm_make_request(KVM_REQ_EVENT, vcpu);
+}
+#ifdef CONFIG_KVM_VIRT_SUSPEND_TIMING
+ if (kvm->suspend_injection_requested &&
+ kvm_vcpu_ready_for_interrupt_injection(vcpu)) {
+ kvm_write_suspend_time(kvm);
+ kvm_make_suspend_time_interrupt(vcpu);
+ kvm->suspend_injection_requested = false;
+ }
+#endif
+ mutex_lock(&kvm_lock);
+ list_for_each_entry(kvm, &vm_list, vm_list) {
+ if (!(kvm->arch.msr_suspend_time & KVM_MSR_ENABLED))
+ continue;
+
+ kvm_for_each_vcpu(i, vcpu, kvm)
+ vcpu->arch.tsc_offset_adjustment -= adj;
+
+ /*
+ * Move the offset of kvm_clock here as if it is stopped
+ * during the suspension.
+ */
+ kvm->arch.kvmclock_offset -= suspend_time_ns;
+
+ /* suspend_time is accumulated per VM. */
+ kvm->suspend_time_ns += suspend_time_ns;
+ kvm->suspend_injection_requested = true;
+ /*
+ * This adjustment will be reflected to the struct provided
+ * from the guest via MSR_KVM_HOST_SUSPEND_TIME before
+ * the notification interrupt is injected.
+ */
+ }
+ mutex_unlock(&kvm_lock);
+}