On 08/05/20 22:36, Jim Mattson wrote: > 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: Jim Mattson <jmattson@xxxxxxxxxx> > Reviewed-by: Peter Shier <pshier@xxxxxxxxxx> > Reviewed-by: Oliver Upton <oupton@xxxxxxxxxx> > --- > arch/x86/include/asm/kvm_host.h | 2 ++ > arch/x86/kvm/irq.c | 2 ++ > arch/x86/kvm/vmx/vmx.c | 11 +++++++++++ > 3 files changed, 15 insertions(+) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index 42a2d0d3984a..a47c71d13039 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -1254,6 +1254,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_init_ops { > diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c > index e330e7d125f7..54f7ea68083b 100644 > --- a/arch/x86/kvm/irq.c > +++ b/arch/x86/kvm/irq.c > @@ -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) > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c > index c2c6335a998c..3896dea72082 100644 > --- a/arch/x86/kvm/vmx/vmx.c > +++ b/arch/x86/kvm/vmx/vmx.c > @@ -7687,6 +7687,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) > @@ -7838,6 +7848,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = { > .nested_get_evmcs_version = NULL, > .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) > Queued all, thanks. Paolo