Linux IOMMU Development
 help / color / mirror / Atom feed
  • * [Patch Part1 v7 08/38] irq_remapping: Introduce new interfaces to support hierarchy irqdomain
           [not found] <1421723321-8386-1-git-send-email-jiang.liu@linux.intel.com>
           [not found] ` <1421723321-8386-1-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
    @ 2015-01-20  3:08 ` Jiang Liu
      2015-01-20  3:08 ` [Patch Part1 v7 13/38] x86/MSI: Use hierarchy irqdomain to manage MSI interrupts Jiang Liu
      2 siblings, 0 replies; 11+ messages in thread
    From: Jiang Liu @ 2015-01-20  3:08 UTC (permalink / raw)
      To: Bjorn Helgaas, Benjamin Herrenschmidt, Thomas Gleixner,
    	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Randy Dunlap,
    	Yinghai Lu, Borislav Petkov, Dimitri Sivanich, x86, Joerg Roedel,
    	Jiang Liu
      Cc: Konrad Rzeszutek Wilk, David Cohen, Sander Eikelenboom,
    	David Vrabel, Andrew Morton, Tony Luck, Greg Kroah-Hartman,
    	linux-kernel, linux-pci, linux-acpi, iommu, Joerg Roedel
    
    Introduce new interfaces for interrupt remapping drivers to support
    hierarchy irqdomain:
    1) irq_remapping_get_ir_irq_domain(): get irqdomain associated with an
       interrupt remapping unit. IOAPIC/HPET drivers use this interface to
       get parent interrupt remapping irqdomain.
    2) irq_remapping_get_irq_domain(): get irqdomain for an IRQ allocation.
       This is mainly used to support MSI irqdomain. We must build one MSI
       irqdomain for each interrupt remapping unit. MSI driver calls this
       interface to get MSI irqdomain associated with an IR irqdomain which
       manages the PCI devices. In a further step we will store the irqdomain
       pointer in the device struct to avoid this call in the irq allocation
       path.
    
    Architecture specific needs to implement two hooks:
    1) arch_get_ir_parent_domain(): get parent irqdomain for IR irqdomain,
       which is x86_vector_domain on x86 platforms.
    2) arch_create_msi_irq_domain(): create an MSI irqdomain associated with
       the interrupt remapping unit.
    
    We also add following callbacks into struct irq_remap_ops:
    	struct irq_domain *(*get_ir_irq_domain)(struct irq_alloc_info *);
    	struct irq_domain *(*get_irq_domain)(struct irq_alloc_info *);
    
    Once all clients of IR have been converted to new hierarchy irqdomain
    interfaces, we will:
    1) Remove set_ioapic_entry, set_affinity, free_irq, compose_msi_msg,
       msi_alloc_irq, msi_setup_irq, setup_hpet_msi from struct remap_osp
    2) Kill setup_ioapic_remapped_entry, free_remapped_irq,
       compose_remapped_msi_msg, setup_hpet_msi_remapped, setup_remapped_irq.
    3) Simplify x86_io_apic_ops and x86_msi.
    
    We could achieve a much more clear architecture with all these changes
    applied.
    
    Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
    Acked-by: Joerg Roedel <jroedel@suse.de>
    Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    Cc: Tony Luck <tony.luck@intel.com>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: iommu@lists.linux-foundation.org
    Cc: Bjorn Helgaas <bhelgaas@google.com>
    Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
    Cc: Randy Dunlap <rdunlap@infradead.org>
    Cc: Yinghai Lu <yinghai@kernel.org>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Joerg Roedel <joro@8bytes.org>
    Link: http://lkml.kernel.org/r/1416894816-23245-9-git-send-email-jiang.liu@linux.intel.com
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    ---
     arch/x86/include/asm/hw_irq.h        |   37 +++++++++++++++++++++++++
     arch/x86/include/asm/irq_remapping.h |   36 ++++++++++++++++++++++++
     drivers/iommu/irq_remapping.c        |   50 +++++++++++++++++++++++++++++++++-
     drivers/iommu/irq_remapping.h        |   10 +++++++
     4 files changed, 132 insertions(+), 1 deletion(-)
    
    diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
    index eb7692c9ab93..bd7881c5a57a 100644
    --- a/arch/x86/include/asm/hw_irq.h
    +++ b/arch/x86/include/asm/hw_irq.h
    @@ -113,10 +113,47 @@ struct irq_2_irte {
     #ifdef	CONFIG_X86_LOCAL_APIC
     struct irq_data;
     struct irq_domain;
    +struct pci_dev;
    +struct msi_desc;
    +
    +enum irq_alloc_type {
    +	X86_IRQ_ALLOC_TYPE_IOAPIC = 1,
    +	X86_IRQ_ALLOC_TYPE_HPET,
    +	X86_IRQ_ALLOC_TYPE_MSI,
    +	X86_IRQ_ALLOC_TYPE_MSIX,
    +};
     
     struct irq_alloc_info {
    +	enum irq_alloc_type	type;
     	u32			flags;
     	const struct cpumask	*mask;	/* CPU mask for vector allocation */
    +	union {
    +		int		unused;
    +#ifdef	CONFIG_HPET_TIMER
    +		struct {
    +			int		hpet_id;
    +			int		hpet_index;
    +			void		*hpet_data;
    +		};
    +#endif
    +#ifdef	CONFIG_PCI_MSI
    +		struct {
    +			struct pci_dev	*msi_dev;
    +			irq_hw_number_t	msi_hwirq;
    +		};
    +#endif
    +#ifdef	CONFIG_X86_IO_APIC
    +		struct {
    +			int		ioapic_id;
    +			int		ioapic_pin;
    +			int		ioapic_node;
    +			u32		ioapic_trigger : 1;
    +			u32		ioapic_polarity : 1;
    +			u32		ioapic_valid : 1;
    +			struct IO_APIC_route_entry *ioapic_entry;
    +		};
    +#endif
    +	};
     };
     
     enum {
    diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
    index 86d897bc15dd..2031e7abdb25 100644
    --- a/arch/x86/include/asm/irq_remapping.h
    +++ b/arch/x86/include/asm/irq_remapping.h
    @@ -22,6 +22,8 @@
     #ifndef __X86_IRQ_REMAPPING_H
     #define __X86_IRQ_REMAPPING_H
     
    +#include <linux/irqdomain.h>
    +#include <asm/hw_irq.h>
     #include <asm/io_apic.h>
     
     struct IO_APIC_route_entry;
    @@ -30,6 +32,7 @@ struct irq_chip;
     struct msi_msg;
     struct pci_dev;
     struct irq_cfg;
    +struct irq_alloc_info;
     
     #ifdef CONFIG_IRQ_REMAP
     
    @@ -56,6 +59,25 @@ extern bool setup_remapped_irq(int irq,
     
     void irq_remap_modify_chip_defaults(struct irq_chip *chip);
     
    +extern struct irq_domain *
    +irq_remapping_get_ir_irq_domain( struct irq_alloc_info *info);
    +extern struct irq_domain *
    +irq_remapping_get_irq_domain(struct irq_alloc_info *info);
    +extern void irq_remapping_print_chip(struct irq_data *data, struct seq_file *p);
    +
    +/* Create PCI MSI/MSIx irqdomain, use @parent as the parent irqdomain. */
    +static inline struct irq_domain *
    +arch_create_msi_irq_domain(struct irq_domain *parent)
    +{
    +	return NULL;
    +}
    +
    +/* Get parent irqdomain for interrupt remapping irqdomain */
    +static inline struct irq_domain *arch_get_ir_parent_domain(void)
    +{
    +	return x86_vector_domain;
    +}
    +
     #else  /* CONFIG_IRQ_REMAP */
     
     static inline void set_irq_remapping_broken(void) { }
    @@ -97,6 +119,20 @@ static inline bool setup_remapped_irq(int irq,
     {
     	return false;
     }
    +
    +static inline struct irq_domain *
    +irq_remapping_get_ir_irq_domain(struct irq_alloc_info *info)
    +{
    +	return NULL;
    +}
    +
    +static inline struct irq_domain *
    +irq_remapping_get_irq_domain(struct irq_alloc_info *info)
    +{
    +	return NULL;
    +}
    +
    +#define	irq_remapping_print_chip	NULL
     #endif /* CONFIG_IRQ_REMAP */
     
     extern int dmar_alloc_hwirq(void);
    diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
    index 5617150fd8fb..c306421d86c1 100644
    --- a/drivers/iommu/irq_remapping.c
    +++ b/drivers/iommu/irq_remapping.c
    @@ -345,7 +345,7 @@ void panic_if_irq_remap(const char *msg)
     		panic(msg);
     }
     
    -static void ir_ack_apic_edge(struct irq_data *data)
    +void ir_ack_apic_edge(struct irq_data *data)
     {
     	ack_APIC_irq();
     }
    @@ -356,6 +356,19 @@ static void ir_ack_apic_level(struct irq_data *data)
     	eoi_ioapic_irq(data->irq, irqd_cfg(data));
     }
     
    +void irq_remapping_print_chip(struct irq_data *data, struct seq_file *p)
    +{
    +	/*
    +	 * Assume interrupt is remapped if the parent irqdomain isn't the
    +	 * vector domain, which is true for MSI, HPET and IOAPIC on x86
    +	 * platforms.
    +	 */
    +	if (data->domain && data->domain->parent != arch_get_ir_parent_domain())
    +		seq_printf(p, " IR-%s", data->chip->name);
    +	else
    +		seq_printf(p, " %s", data->chip->name);
    +}
    +
     static void ir_print_prefix(struct irq_data *data, struct seq_file *p)
     {
     	seq_printf(p, " IR-%s", data->chip->name);
    @@ -377,3 +390,38 @@ bool setup_remapped_irq(int irq, struct irq_cfg *cfg, struct irq_chip *chip)
     	irq_remap_modify_chip_defaults(chip);
     	return true;
     }
    +
    +/**
    + * irq_remapping_get_ir_irq_domain - Get the irqdomain associated with the IOMMU
    + *				     device serving request @info
    + * @info: interrupt allocation information, used to identify the IOMMU device
    + *
    + * It's used to get parent irqdomain for HPET and IOAPIC irqdomains.
    + * Returns pointer to IRQ domain, or NULL on failure.
    + */
    +struct irq_domain *
    +irq_remapping_get_ir_irq_domain(struct irq_alloc_info *info)
    +{
    +	if (!remap_ops || !remap_ops->get_ir_irq_domain)
    +		return NULL;
    +
    +	return remap_ops->get_ir_irq_domain(info);
    +}
    +
    +/**
    + * irq_remapping_get_irq_domain - Get the irqdomain serving the request @info
    + * @info: interrupt allocation information, used to identify the IOMMU device
    + *
    + * There will be one PCI MSI/MSIX irqdomain associated with each interrupt
    + * remapping device, so this interface is used to retrieve the PCI MSI/MSIX
    + * irqdomain serving request @info.
    + * Returns pointer to IRQ domain, or NULL on failure.
    + */
    +struct irq_domain *
    +irq_remapping_get_irq_domain(struct irq_alloc_info *info)
    +{
    +	if (!remap_ops || !remap_ops->get_irq_domain)
    +		return NULL;
    +
    +	return remap_ops->get_irq_domain(info);
    +}
    diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h
    index c448eb48340a..32a3ad30d760 100644
    --- a/drivers/iommu/irq_remapping.h
    +++ b/drivers/iommu/irq_remapping.h
    @@ -30,6 +30,8 @@ struct irq_data;
     struct cpumask;
     struct pci_dev;
     struct msi_msg;
    +struct irq_domain;
    +struct irq_alloc_info;
     
     extern int irq_remap_broken;
     extern int disable_sourceid_checking;
    @@ -77,11 +79,19 @@ struct irq_remap_ops {
     
     	/* Setup interrupt remapping for an HPET MSI */
     	int (*alloc_hpet_msi)(unsigned int, unsigned int);
    +
    +	/* Get the irqdomain associated the IOMMU device */
    +	struct irq_domain *(*get_ir_irq_domain)(struct irq_alloc_info *);
    +
    +	/* Get the MSI irqdomain associated with the IOMMU device */
    +	struct irq_domain *(*get_irq_domain)(struct irq_alloc_info *);
     };
     
     extern struct irq_remap_ops intel_irq_remap_ops;
     extern struct irq_remap_ops amd_iommu_irq_ops;
     
    +extern void ir_ack_apic_edge(struct irq_data *data);
    +
     #else  /* CONFIG_IRQ_REMAP */
     
     #define irq_remapping_enabled 0
    -- 
    1.7.10.4
    
    ^ permalink raw reply related	[flat|nested] 11+ messages in thread
  • * [Patch Part1 v7 13/38] x86/MSI: Use hierarchy irqdomain to manage MSI interrupts
           [not found] <1421723321-8386-1-git-send-email-jiang.liu@linux.intel.com>
           [not found] ` <1421723321-8386-1-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
      2015-01-20  3:08 ` [Patch Part1 v7 08/38] irq_remapping: Introduce new interfaces to support hierarchy irqdomain Jiang Liu
    @ 2015-01-20  3:08 ` Jiang Liu
      2 siblings, 0 replies; 11+ messages in thread
    From: Jiang Liu @ 2015-01-20  3:08 UTC (permalink / raw)
      To: Bjorn Helgaas, Benjamin Herrenschmidt, Thomas Gleixner,
    	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Randy Dunlap,
    	Yinghai Lu, Borislav Petkov, Dimitri Sivanich, x86, Joerg Roedel,
    	Jiang Liu
      Cc: Konrad Rzeszutek Wilk, David Cohen, Sander Eikelenboom,
    	David Vrabel, Andrew Morton, Tony Luck, Greg Kroah-Hartman,
    	linux-kernel, linux-pci, linux-acpi, iommu, Joerg Roedel
    
    Enhance MSI code to support hierarchy irqdomain, it helps to make
    the architecture more clear.
    
    Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
    Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    Cc: Tony Luck <tony.luck@intel.com>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: iommu@lists.linux-foundation.org
    Cc: Bjorn Helgaas <bhelgaas@google.com>
    Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
    Cc: Randy Dunlap <rdunlap@infradead.org>
    Cc: Yinghai Lu <yinghai@kernel.org>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Joerg Roedel <joro@8bytes.org>
    Link: http://lkml.kernel.org/r/1416894816-23245-14-git-send-email-jiang.liu@linux.intel.com
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    ---
     arch/x86/Kconfig                     |    1 +
     arch/x86/include/asm/hw_irq.h        |    9 ++-
     arch/x86/include/asm/irq_remapping.h |    6 +-
     arch/x86/include/asm/msi.h           |    7 ++
     arch/x86/kernel/apic/msi.c           |  141 ++++++++++++++++++----------------
     arch/x86/kernel/apic/vector.c        |    2 +
     drivers/iommu/irq_remapping.c        |    1 -
     7 files changed, 94 insertions(+), 73 deletions(-)
     create mode 100644 arch/x86/include/asm/msi.h
    
    diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
    index ff7cad03d7f7..89a530a5836e 100644
    --- a/arch/x86/Kconfig
    +++ b/arch/x86/Kconfig
    @@ -884,6 +884,7 @@ config X86_LOCAL_APIC
     	depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC || PCI_MSI
     	select GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
     	select IRQ_DOMAIN_HIERARCHY
    +	select PCI_MSI_IRQ_DOMAIN if PCI_MSI
     
     config X86_IO_APIC
     	def_bool X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC
    diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
    index bd7881c5a57a..270c432971f8 100644
    --- a/arch/x86/include/asm/hw_irq.h
    +++ b/arch/x86/include/asm/hw_irq.h
    @@ -110,9 +110,10 @@ struct irq_2_irte {
     };
     #endif	/* CONFIG_IRQ_REMAP */
     
    +struct irq_domain;
    +
     #ifdef	CONFIG_X86_LOCAL_APIC
     struct irq_data;
    -struct irq_domain;
     struct pci_dev;
     struct msi_desc;
     
    @@ -214,6 +215,12 @@ static inline void lock_vector_lock(void) {}
     static inline void unlock_vector_lock(void) {}
     #endif	/* CONFIG_X86_LOCAL_APIC */
     
    +#ifdef	CONFIG_PCI_MSI
    +extern void arch_init_msi_domain(struct irq_domain *domain);
    +#else
    +static inline void arch_init_msi_domain(struct irq_domain *domain) { }
    +#endif
    +
     /* Statistics */
     extern atomic_t irq_err_count;
     extern atomic_t irq_mis_count;
    diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
    index 2031e7abdb25..9bb2614dbe25 100644
    --- a/arch/x86/include/asm/irq_remapping.h
    +++ b/arch/x86/include/asm/irq_remapping.h
    @@ -66,11 +66,7 @@ irq_remapping_get_irq_domain(struct irq_alloc_info *info);
     extern void irq_remapping_print_chip(struct irq_data *data, struct seq_file *p);
     
     /* Create PCI MSI/MSIx irqdomain, use @parent as the parent irqdomain. */
    -static inline struct irq_domain *
    -arch_create_msi_irq_domain(struct irq_domain *parent)
    -{
    -	return NULL;
    -}
    +extern struct irq_domain *arch_create_msi_irq_domain(struct irq_domain *parent);
     
     /* Get parent irqdomain for interrupt remapping irqdomain */
     static inline struct irq_domain *arch_get_ir_parent_domain(void)
    diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
    new file mode 100644
    index 000000000000..93724cc62177
    --- /dev/null
    +++ b/arch/x86/include/asm/msi.h
    @@ -0,0 +1,7 @@
    +#ifndef _ASM_X86_MSI_H
    +#define _ASM_X86_MSI_H
    +#include <asm/hw_irq.h>
    +
    +typedef struct irq_alloc_info msi_alloc_info_t;
    +
    +#endif /* _ASM_X86_MSI_H */
    diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
    index 10d9ae8f2166..e82ab7973477 100644
    --- a/arch/x86/kernel/apic/msi.c
    +++ b/arch/x86/kernel/apic/msi.c
    @@ -3,6 +3,8 @@
      *
      * Copyright (C) 1997, 1998, 1999, 2000, 2009 Ingo Molnar, Hajnalka Szabo
      *	Moved from arch/x86/kernel/apic/io_apic.c.
    + * Jiang Liu <jiang.liu@linux.intel.com>
    + *	Convert to hierarchy irqdomain
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License version 2 as
    @@ -21,6 +23,8 @@
     #include <asm/apic.h>
     #include <asm/irq_remapping.h>
     
    +static struct irq_domain *msi_default_domain;
    +
     void native_compose_msi_msg(struct pci_dev *pdev,
     			    unsigned int irq, unsigned int dest,
     			    struct msi_msg *msg, u8 hpet_id)
    @@ -114,102 +118,107 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
     	return 0;
     }
     
    -static int
    -msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
    -{
    -	struct irq_cfg *cfg = irqd_cfg(data);
    -	struct msi_msg msg;
    -	unsigned int dest;
    -	int ret;
    -
    -	ret = apic_set_affinity(data, mask, &dest);
    -	if (ret)
    -		return ret;
    -
    -	__get_cached_msi_msg(data->msi_desc, &msg);
    -
    -	msg.data &= ~MSI_DATA_VECTOR_MASK;
    -	msg.data |= MSI_DATA_VECTOR(cfg->vector);
    -	msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
    -	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
    -
    -	__pci_write_msi_msg(data->msi_desc, &msg);
    -
    -	return IRQ_SET_MASK_OK_NOCOPY;
    -}
    -
     /*
      * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
      * which implement the MSI or MSI-X Capability Structure.
      */
    -static struct irq_chip msi_chip = {
    +static struct irq_chip pci_msi_controller = {
     	.name			= "PCI-MSI",
     	.irq_unmask		= pci_msi_unmask_irq,
     	.irq_mask		= pci_msi_mask_irq,
    -	.irq_ack		= apic_ack_edge,
    -	.irq_set_affinity	= msi_set_affinity,
    -	.irq_retrigger		= apic_retrigger_irq,
    +	.irq_ack		= irq_chip_ack_parent,
    +	.irq_set_affinity	= msi_domain_set_affinity,
    +	.irq_retrigger		= irq_chip_retrigger_hierarchy,
    +	.irq_print_chip		= irq_remapping_print_chip,
    +	.irq_compose_msi_msg	= irq_msi_compose_msg,
    +	.irq_write_msi_msg	= pci_msi_domain_write_msg,
     	.flags			= IRQCHIP_SKIP_SET_WAKE,
     };
     
    -int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
    -		  unsigned int irq_base, unsigned int irq_offset)
    +int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
     {
    -	struct irq_chip *chip = &msi_chip;
    -	struct msi_msg msg;
    -	unsigned int irq = irq_base + irq_offset;
    -	int ret;
    +	struct irq_domain *domain;
    +	struct irq_alloc_info info;
     
    -	ret = msi_compose_msg(dev, irq, &msg, -1);
    -	if (ret < 0)
    -		return ret;
    +	init_irq_alloc_info(&info, NULL);
    +	info.type = X86_IRQ_ALLOC_TYPE_MSI;
    +	info.msi_dev = dev;
     
    -	irq_set_msi_desc_off(irq_base, irq_offset, msidesc);
    +	domain = irq_remapping_get_irq_domain(&info);
    +	if (domain == NULL)
    +		domain = msi_default_domain;
    +	if (domain == NULL)
    +		return -ENOSYS;
     
    -	/*
    -	 * MSI-X message is written per-IRQ, the offset is always 0.
    -	 * MSI message denotes a contiguous group of IRQs, written for 0th IRQ.
    -	 */
    -	if (!irq_offset)
    -		pci_write_msi_msg(irq, &msg);
    +	return pci_msi_domain_alloc_irqs(domain, dev, nvec, type);
    +}
     
    -	setup_remapped_irq(irq, irq_cfg(irq), chip);
    +void native_teardown_msi_irq(unsigned int irq)
    +{
    +	irq_domain_free_irqs(irq, 1);
    +}
     
    -	irq_set_chip_and_handler_name(irq, chip, handle_edge_irq, "edge");
    +static irq_hw_number_t pci_msi_get_hwirq(struct msi_domain_info *info,
    +					 msi_alloc_info_t *arg)
    +{
    +	return arg->msi_hwirq;
    +}
     
    -	dev_dbg(&dev->dev, "irq %d for MSI/MSI-X\n", irq);
    +static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
    +			   int nvec, msi_alloc_info_t *arg)
    +{
    +	struct pci_dev *pdev = to_pci_dev(dev);
    +	struct msi_desc *desc = first_pci_msi_entry(pdev);
    +
    +	init_irq_alloc_info(arg, NULL);
    +	arg->msi_dev = pdev;
    +	if (desc->msi_attrib.is_msix) {
    +		arg->type = X86_IRQ_ALLOC_TYPE_MSIX;
    +	} else {
    +		arg->type = X86_IRQ_ALLOC_TYPE_MSI;
    +		arg->flags |= X86_IRQ_ALLOC_CONTIGOUS_VECTORS;
    +	}
     
     	return 0;
     }
     
    -int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
    +static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
     {
    -	struct msi_desc *msidesc;
    -	int irq, ret;
    +	arg->msi_hwirq = pci_msi_domain_calc_hwirq(arg->msi_dev, desc);
    +}
     
    -	/* Multiple MSI vectors only supported with interrupt remapping */
    -	if (type == PCI_CAP_ID_MSI && nvec > 1)
    -		return 1;
    +static struct msi_domain_ops pci_msi_domain_ops = {
    +	.get_hwirq	= pci_msi_get_hwirq,
    +	.msi_prepare	= pci_msi_prepare,
    +	.set_desc	= pci_msi_set_desc,
    +};
     
    -	list_for_each_entry(msidesc, &dev->msi_list, list) {
    -		irq = irq_domain_alloc_irqs(NULL, 1, NUMA_NO_NODE, NULL);
    -		if (irq <= 0)
    -			return -ENOSPC;
    +static struct msi_domain_info pci_msi_domain_info = {
    +	.flags		= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
    +			  MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX,
    +	.ops		= &pci_msi_domain_ops,
    +	.chip		= &pci_msi_controller,
    +	.handler	= handle_edge_irq,
    +	.handler_name	= "edge",
    +};
     
    -		ret = setup_msi_irq(dev, msidesc, irq, 0);
    -		if (ret < 0) {
    -			irq_domain_free_irqs(irq, 1);
    -			return ret;
    -		}
    +void arch_init_msi_domain(struct irq_domain *parent)
    +{
    +	if (disable_apic)
    +		return;
     
    -	}
    -	return 0;
    +	msi_default_domain = pci_msi_create_irq_domain(NULL,
    +					&pci_msi_domain_info, parent);
    +	if (!msi_default_domain)
    +		pr_warn("failed to initialize irqdomain for MSI/MSI-x.\n");
     }
     
    -void native_teardown_msi_irq(unsigned int irq)
    +#ifdef CONFIG_IRQ_REMAP
    +struct irq_domain *arch_create_msi_irq_domain(struct irq_domain *parent)
     {
    -	irq_domain_free_irqs(irq, 1);
    +	return msi_create_irq_domain(NULL, &pci_msi_domain_info, parent);
     }
    +#endif
     
     #ifdef CONFIG_DMAR_TABLE
     static int
    diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
    index f8340c72546f..e971c87f7858 100644
    --- a/arch/x86/kernel/apic/vector.c
    +++ b/arch/x86/kernel/apic/vector.c
    @@ -364,6 +364,8 @@ int __init arch_early_irq_init(void)
     	BUG_ON(x86_vector_domain == NULL);
     	irq_set_default_host(x86_vector_domain);
     
    +	arch_init_msi_domain(x86_vector_domain);
    +
     	return arch_early_ioapic_init();
     }
     
    diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
    index c306421d86c1..d77e3711c2aa 100644
    --- a/drivers/iommu/irq_remapping.c
    +++ b/drivers/iommu/irq_remapping.c
    @@ -170,7 +170,6 @@ static void __init irq_remapping_modify_x86_ops(void)
     	x86_io_apic_ops.set_affinity	= set_remapped_irq_affinity;
     	x86_io_apic_ops.setup_entry	= setup_ioapic_remapped_entry;
     	x86_io_apic_ops.eoi_ioapic_pin	= eoi_ioapic_pin_remapped;
    -	x86_msi.setup_msi_irqs		= irq_remapping_setup_msi_irqs;
     	x86_msi.setup_hpet_msi		= setup_hpet_msi_remapped;
     	x86_msi.compose_msi_msg		= compose_remapped_msi_msg;
     }
    -- 
    1.7.10.4
    
    ^ permalink raw reply related	[flat|nested] 11+ messages in thread

  • end of thread, other threads:[~2015-01-20  3:08 UTC | newest]
    
    Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
    -- links below jump to the message on this page --
         [not found] <1421723321-8386-1-git-send-email-jiang.liu@linux.intel.com>
         [not found] ` <1421723321-8386-1-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
    2015-01-20  3:08   ` [Patch Part1 v7 07/38] x86/dmar: Use new irqdomain interfaces to allocate/free IRQ Jiang Liu
    2015-01-20  3:08   ` [Patch Part1 v7 09/38] irq_remapping/vt-d: Change prototypes to prepare for enabling hierarchy irqdomain Jiang Liu
    2015-01-20  3:08   ` [Patch Part1 v7 10/38] irq_remapping/vt-d: Enhance Intel IR driver to suppport " Jiang Liu
    2015-01-20  3:08   ` [Patch Part1 v7 11/38] irq_remapping/amd: Enhance AMD " Jiang Liu
    2015-01-20  3:08   ` [Patch Part1 v7 15/38] irq_remapping/vt-d: Clean up unused MSI related code Jiang Liu
    2015-01-20  3:08   ` [Patch Part1 v7 16/38] irq_remapping/amd: " Jiang Liu
    2015-01-20  3:08   ` [Patch Part1 v7 17/38] irq_remapping: " Jiang Liu
    2015-01-20  3:08   ` [Patch Part1 v7 19/38] iommu/vt-d: Refine the interfaces to create IRQ for DMAR unit Jiang Liu
    2015-01-20  3:08   ` [Patch Part1 v7 28/38] irq_remapping: Kill unused function irq_remapping_print_chip() Jiang Liu
    2015-01-20  3:08 ` [Patch Part1 v7 08/38] irq_remapping: Introduce new interfaces to support hierarchy irqdomain Jiang Liu
    2015-01-20  3:08 ` [Patch Part1 v7 13/38] x86/MSI: Use hierarchy irqdomain to manage MSI interrupts Jiang Liu
    

    This is a public inbox, see mirroring instructions
    for how to clone and mirror all data and code used for this inbox