Re: [PATCH v2 1/5] KVM: x86: Move irq mask notifiers from x86 to generic KVM

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

 



Hi Dmytro,
On 8/5/22 21:39, Dmytro Maluka wrote:
> Currently irq mask notifiers are used only internally in the x86 code
> for PIT emulation. However they are not really arch specific. We are
> going to use them in the generic irqfd code, for postponing resampler
> irqfd notification until the interrupt is unmasked. So move the
> implementation of mask notifiers to the generic code, to allow irqfd to
> register its mask notifiers.
>
> Note that calling mask notifiers via calling kvm_fire_mask_notifiers()
> is still implemented for x86 only, so registering mask notifiers on
> other architectures will have no effect for now.
>
> Signed-off-by: Dmytro Maluka <dmy@xxxxxxxxxxxx>
Reviewed-by: Eric Auger <eric.auger@xxxxxxxxxx>

Eric
> ---
>  arch/x86/include/asm/kvm_host.h | 16 ----------------
>  arch/x86/kvm/irq_comm.c         | 33 ---------------------------------
>  arch/x86/kvm/x86.c              |  1 -
>  include/linux/kvm_host.h        | 15 +++++++++++++++
>  virt/kvm/eventfd.c              | 33 +++++++++++++++++++++++++++++++++
>  virt/kvm/kvm_main.c             |  1 +
>  6 files changed, 49 insertions(+), 50 deletions(-)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 9217bd6cf0d1..dc76617f11c1 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1198,9 +1198,6 @@ struct kvm_arch {
>  
>  	struct kvm_xen_hvm_config xen_hvm_config;
>  
> -	/* reads protected by irq_srcu, writes by irq_lock */
> -	struct hlist_head mask_notifier_list;
> -
>  	struct kvm_hv hyperv;
>  	struct kvm_xen xen;
>  
> @@ -1688,19 +1685,6 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
>  int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
>  			  const void *val, int bytes);
>  
> -struct kvm_irq_mask_notifier {
> -	void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked);
> -	int irq;
> -	struct hlist_node link;
> -};
> -
> -void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
> -				    struct kvm_irq_mask_notifier *kimn);
> -void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
> -				      struct kvm_irq_mask_notifier *kimn);
> -void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
> -			     bool mask);
> -
>  extern bool tdp_enabled;
>  
>  u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu);
> diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
> index 0687162c4f22..f27e4c9c403e 100644
> --- a/arch/x86/kvm/irq_comm.c
> +++ b/arch/x86/kvm/irq_comm.c
> @@ -234,39 +234,6 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
>  	mutex_unlock(&kvm->irq_lock);
>  }
>  
> -void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
> -				    struct kvm_irq_mask_notifier *kimn)
> -{
> -	mutex_lock(&kvm->irq_lock);
> -	kimn->irq = irq;
> -	hlist_add_head_rcu(&kimn->link, &kvm->arch.mask_notifier_list);
> -	mutex_unlock(&kvm->irq_lock);
> -}
> -
> -void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
> -				      struct kvm_irq_mask_notifier *kimn)
> -{
> -	mutex_lock(&kvm->irq_lock);
> -	hlist_del_rcu(&kimn->link);
> -	mutex_unlock(&kvm->irq_lock);
> -	synchronize_srcu(&kvm->irq_srcu);
> -}
> -
> -void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
> -			     bool mask)
> -{
> -	struct kvm_irq_mask_notifier *kimn;
> -	int idx, gsi;
> -
> -	idx = srcu_read_lock(&kvm->irq_srcu);
> -	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
> -	if (gsi != -1)
> -		hlist_for_each_entry_rcu(kimn, &kvm->arch.mask_notifier_list, link)
> -			if (kimn->irq == gsi)
> -				kimn->func(kimn, mask);
> -	srcu_read_unlock(&kvm->irq_srcu, idx);
> -}
> -
>  bool kvm_arch_can_set_irq_routing(struct kvm *kvm)
>  {
>  	return irqchip_in_kernel(kvm);
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e5fa335a4ea7..a0a776f5c42f 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -11818,7 +11818,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>  	if (ret)
>  		goto out_page_track;
>  
> -	INIT_HLIST_HEAD(&kvm->arch.mask_notifier_list);
>  	INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
>  	atomic_set(&kvm->arch.noncoherent_dma_count, 0);
>  
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 90a45ef7203b..dd5f14e31996 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -760,7 +760,10 @@ struct kvm {
>  	struct kvm_irq_routing_table __rcu *irq_routing;
>  #endif
>  #ifdef CONFIG_HAVE_KVM_IRQFD
> +	/* reads protected by irq_srcu, writes by irq_lock */
>  	struct hlist_head irq_ack_notifier_list;
> +	/* reads protected by irq_srcu, writes by irq_lock */
> +	struct hlist_head irq_mask_notifier_list;
>  #endif
>  
>  #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
> @@ -1581,6 +1584,12 @@ struct kvm_irq_ack_notifier {
>  	void (*irq_acked)(struct kvm_irq_ack_notifier *kian);
>  };
>  
> +struct kvm_irq_mask_notifier {
> +	void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked);
> +	int irq;
> +	struct hlist_node link;
> +};
> +
>  int kvm_irq_map_gsi(struct kvm *kvm,
>  		    struct kvm_kernel_irq_routing_entry *entries, int gsi);
>  int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin);
> @@ -1599,6 +1608,12 @@ void kvm_register_irq_ack_notifier(struct kvm *kvm,
>  				   struct kvm_irq_ack_notifier *kian);
>  void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
>  				   struct kvm_irq_ack_notifier *kian);
> +void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
> +				    struct kvm_irq_mask_notifier *kimn);
> +void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
> +				      struct kvm_irq_mask_notifier *kimn);
> +void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
> +			     bool mask);
>  int kvm_request_irq_source_id(struct kvm *kvm);
>  void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
>  bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args);
> diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
> index 2a3ed401ce46..39403d9fbdcc 100644
> --- a/virt/kvm/eventfd.c
> +++ b/virt/kvm/eventfd.c
> @@ -518,6 +518,39 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
>  	synchronize_srcu(&kvm->irq_srcu);
>  	kvm_arch_post_irq_ack_notifier_list_update(kvm);
>  }
> +
> +void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
> +				    struct kvm_irq_mask_notifier *kimn)
> +{
> +	mutex_lock(&kvm->irq_lock);
> +	kimn->irq = irq;
> +	hlist_add_head_rcu(&kimn->link, &kvm->irq_mask_notifier_list);
> +	mutex_unlock(&kvm->irq_lock);
> +}
> +
> +void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
> +				      struct kvm_irq_mask_notifier *kimn)
> +{
> +	mutex_lock(&kvm->irq_lock);
> +	hlist_del_rcu(&kimn->link);
> +	mutex_unlock(&kvm->irq_lock);
> +	synchronize_srcu(&kvm->irq_srcu);
> +}
> +
> +void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
> +			     bool mask)
> +{
> +	struct kvm_irq_mask_notifier *kimn;
> +	int idx, gsi;
> +
> +	idx = srcu_read_lock(&kvm->irq_srcu);
> +	gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
> +	if (gsi != -1)
> +		hlist_for_each_entry_rcu(kimn, &kvm->irq_mask_notifier_list, link)
> +			if (kimn->irq == gsi)
> +				kimn->func(kimn, mask);
> +	srcu_read_unlock(&kvm->irq_srcu, idx);
> +}
>  #endif
>  
>  void
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index a49df8988cd6..5ca7fb0b8257 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -1144,6 +1144,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
>  
>  #ifdef CONFIG_HAVE_KVM_IRQFD
>  	INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list);
> +	INIT_HLIST_HEAD(&kvm->irq_mask_notifier_list);
>  #endif
>  
>  	r = kvm_init_mmu_notifier(kvm);




[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