Re: [v2 PATCH 3/4] x86/kvm: Add host side support for virtual suspend time injection

From: Paolo Bonzini
Date: Sat Aug 14 2021 - 03:22:31 EST


On 06/08/21 12:07, Hikaru Nishida wrote:
+#if defined(CONFIG_KVM_VIRT_SUSPEND_TIMING) || \
+ defined(CONFIG_KVM_VIRT_SUSPEND_TIMING_GUEST)
+#define VIRT_SUSPEND_TIMING_VECTOR 0xec
+#endif

No need to use a new vector. You can rename the existing MSR_KVM_ASYNC_PF_INT to MSR_KVM_HYPERVISOR_CALLBACK_INT or something like that, and add the code to sysvec_kvm_asyncpf_interrupt.

+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);
+}

Use kvm_apic_set_irq which will inject the interrupt as soon as possible, so you do not even need to check kvm_vcpu_ready_for_interrupt_injection.

+#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

Do not read variables in vcpu_run; There is KVM_REQ_* if you need to do work in the vCPU run loop.

+ 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);
+}

As pointed out by Thomas, this should be a work item.

Paolo