Commit 93dff2fe authored by Jim Mattson's avatar Jim Mattson Committed by Paolo Bonzini
Browse files

KVM: nVMX: Migrate the VMX-preemption timer



The hrtimer used to emulate the VMX-preemption timer must be pinned to
the same logical processor as the vCPU thread to be interrupted if we
want to have any hope of adhering to the architectural specification
of the VMX-preemption timer. Even with this change, the emulated
VMX-preemption timer VM-exit occasionally arrives too late.

Signed-off-by: default avatarJim Mattson <jmattson@google.com>
Reviewed-by: default avatarPeter Shier <pshier@google.com>
Reviewed-by: default avatarOliver Upton <oupton@google.com>
Message-Id: <20200508203643.85477-4-jmattson@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent ada0098d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1247,6 +1247,8 @@ struct kvm_x86_ops {

	bool (*apic_init_signal_blocked)(struct kvm_vcpu *vcpu);
	int (*enable_direct_tlbflush)(struct kvm_vcpu *vcpu);

	void (*migrate_timers)(struct kvm_vcpu *vcpu);
};

struct kvm_x86_nested_ops {
+2 −0
Original line number Diff line number Diff line
@@ -159,6 +159,8 @@ void __kvm_migrate_timers(struct kvm_vcpu *vcpu)
{
	__kvm_migrate_apic_timer(vcpu);
	__kvm_migrate_pit_timer(vcpu);
	if (kvm_x86_ops.migrate_timers)
		kvm_x86_ops.migrate_timers(vcpu);
}

bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)
+11 −0
Original line number Diff line number Diff line
@@ -7814,6 +7814,16 @@ static bool vmx_apic_init_signal_blocked(struct kvm_vcpu *vcpu)
	return to_vmx(vcpu)->nested.vmxon;
}

static void vmx_migrate_timers(struct kvm_vcpu *vcpu)
{
	if (is_guest_mode(vcpu)) {
		struct hrtimer *timer = &to_vmx(vcpu)->nested.preemption_timer;

		if (hrtimer_try_to_cancel(timer) == 1)
			hrtimer_start_expires(timer, HRTIMER_MODE_ABS_PINNED);
	}
}

static void hardware_unsetup(void)
{
	if (nested)
@@ -7957,6 +7967,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {

	.need_emulation_on_page_fault = vmx_need_emulation_on_page_fault,
	.apic_init_signal_blocked = vmx_apic_init_signal_blocked,
	.migrate_timers = vmx_migrate_timers,
};

static __init int hardware_setup(void)