Re: [PATCH 3/3] KVM: nVMX: Migrate the VMX-preemption timer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux