History

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.

Jim Mattson committed 6 years ago

Commit 93dff2f1 parent ada00983 files · +15 −0Browse files

Unified · Split

3 files
  1. arch/x86/include/asm/kvm_host.h +2 −0
  2. arch/x86/kvm/irq.c +2 −0
  3. arch/x86/kvm/vmx/vmx.c +11 −0
arch/x86/include/asm/kvm_host.h+2−0
@@ -1247,6 +1247,8 @@ struct kvm_x86_ops { · 1246 unmodified lines
1247 1247
1248 bool (*apic_init_signal_blocked)(struct kvm_vcpu *vcpu);1248 bool (*apic_init_signal_blocked)(struct kvm_vcpu *vcpu);
1249 int (*enable_direct_tlbflush)(struct kvm_vcpu *vcpu);1249 int (*enable_direct_tlbflush)(struct kvm_vcpu *vcpu);
1250
1251 void (*migrate_timers)(struct kvm_vcpu *vcpu);
1250};1252};
1251 1253
1252struct kvm_x86_nested_ops {1254struct kvm_x86_nested_ops {
arch/x86/kvm/irq.c+2−0
@@ -159,6 +159,8 @@ void __kvm_migrate_timers(struct kvm_vcpu *vcpu) · 158 unmodified lines
159{159{
160 __kvm_migrate_apic_timer(vcpu);160 __kvm_migrate_apic_timer(vcpu);
161 __kvm_migrate_pit_timer(vcpu);161 __kvm_migrate_pit_timer(vcpu);
162 if (kvm_x86_ops.migrate_timers)
163 kvm_x86_ops.migrate_timers(vcpu);
162}164}
163 165
164bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)166bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)
arch/x86/kvm/vmx/vmx.c+11−0
@@ -7814,6 +7814,16 @@ static bool vmx_apic_init_signal_blocked(struct kvm_vcpu *vcpu) · 7813 unmodified lines
7814 return to_vmx(vcpu)->nested.vmxon;7814 return to_vmx(vcpu)->nested.vmxon;
7815}7815}
7816 7816
7817static void vmx_migrate_timers(struct kvm_vcpu *vcpu)
7818{
7819 if (is_guest_mode(vcpu)) {
7820 struct hrtimer *timer = &to_vmx(vcpu)->nested.preemption_timer;
7821
7822 if (hrtimer_try_to_cancel(timer) == 1)
7823 hrtimer_start_expires(timer, HRTIMER_MODE_ABS_PINNED);
7824 }
7825}
7826
7817static void hardware_unsetup(void)7827static void hardware_unsetup(void)
7818{7828{
7819 if (nested)7829 if (nested)
@@ -7957,6 +7967,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { · 137 unmodified lines
7957 7967
7958 .need_emulation_on_page_fault = vmx_need_emulation_on_page_fault,7968 .need_emulation_on_page_fault = vmx_need_emulation_on_page_fault,
7959 .apic_init_signal_blocked = vmx_apic_init_signal_blocked,7969 .apic_init_signal_blocked = vmx_apic_init_signal_blocked,
7970 .migrate_timers = vmx_migrate_timers,
7960};7971};
7961 7972
7962static __init int hardware_setup(void)7973static __init int hardware_setup(void)