aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <joro@8bytes.org>2012-09-26 06:44:49 -0400
committerJoerg Roedel <joro@8bytes.org>2013-01-28 06:42:48 -0500
commit7601384f91be1a5ea60cb4ef6e28cad628e6cd1e (patch)
treec5dd95d5edb2d89aad2f7df7f70f6897c44beec8
parent2976fd8417f5744de3bb9109e4f30f353a36b1c0 (diff)
x86, msi: Introduce x86_msi.compose_msi_msg call-back
This call-back points to the right function for initializing the msi_msg structure. The old code for msi_msg generation was split up into the irq-remapped and the default case. The irq-remapped case just calls into the specific Intel or AMD implementation when the device is behind an IOMMU. Otherwise the default function is called. Signed-off-by: Joerg Roedel <joro@8bytes.org> Acked-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r--arch/x86/include/asm/io_apic.h4
-rw-r--r--arch/x86/include/asm/x86_init.h4
-rw-r--r--arch/x86/kernel/apic/io_apic.c57
-rw-r--r--arch/x86/kernel/x86_init.c1
-rw-r--r--drivers/iommu/irq_remapping.c9
5 files changed, 45 insertions, 30 deletions
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 36fb5abd3725..1838e884a5cc 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -158,6 +158,9 @@ extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *,
158 struct io_apic_irq_attr *); 158 struct io_apic_irq_attr *);
159extern void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg); 159extern void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg);
160 160
161extern void native_compose_msi_msg(struct pci_dev *pdev,
162 unsigned int irq, unsigned int dest,
163 struct msi_msg *msg, u8 hpet_id);
161int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr); 164int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr);
162 165
163extern int save_ioapic_entries(void); 166extern int save_ioapic_entries(void);
@@ -242,6 +245,7 @@ static inline void disable_ioapic_support(void) { }
242#define native_io_apic_print_entries NULL 245#define native_io_apic_print_entries NULL
243#define native_ioapic_set_affinity NULL 246#define native_ioapic_set_affinity NULL
244#define native_setup_ioapic_entry NULL 247#define native_setup_ioapic_entry NULL
248#define native_compose_msi_msg NULL
245#endif 249#endif
246 250
247#endif /* _ASM_X86_IO_APIC_H */ 251#endif /* _ASM_X86_IO_APIC_H */
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 17da29cf1a47..c9f87be84b0f 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -181,9 +181,13 @@ struct x86_platform_ops {
181}; 181};
182 182
183struct pci_dev; 183struct pci_dev;
184struct msi_msg;
184 185
185struct x86_msi_ops { 186struct x86_msi_ops {
186 int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type); 187 int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
188 void (*compose_msi_msg)(struct pci_dev *dev, unsigned int irq,
189 unsigned int dest, struct msi_msg *msg,
190 u8 hpet_id);
187 void (*teardown_msi_irq)(unsigned int irq); 191 void (*teardown_msi_irq)(unsigned int irq);
188 void (*teardown_msi_irqs)(struct pci_dev *dev); 192 void (*teardown_msi_irqs)(struct pci_dev *dev);
189 void (*restore_msi_irqs)(struct pci_dev *dev, int irq); 193 void (*restore_msi_irqs)(struct pci_dev *dev, int irq);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 372512219a9b..b832810d28f0 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3019,37 +3019,16 @@ void destroy_irqs(unsigned int irq, unsigned int count)
3019/* 3019/*
3020 * MSI message composition 3020 * MSI message composition
3021 */ 3021 */
3022#ifdef CONFIG_PCI_MSI 3022void native_compose_msi_msg(struct pci_dev *pdev,
3023static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, 3023 unsigned int irq, unsigned int dest,
3024 struct msi_msg *msg, u8 hpet_id) 3024 struct msi_msg *msg, u8 hpet_id)
3025{ 3025{
3026 struct irq_cfg *cfg; 3026 struct irq_cfg *cfg = irq_cfg(irq);
3027 int err;
3028 unsigned dest;
3029 3027
3030 if (disable_apic) 3028 msg->address_hi = MSI_ADDR_BASE_HI;
3031 return -ENXIO;
3032
3033 cfg = irq_cfg(irq);
3034 err = assign_irq_vector(irq, cfg, apic->target_cpus());
3035 if (err)
3036 return err;
3037
3038 err = apic->cpu_mask_to_apicid_and(cfg->domain,
3039 apic->target_cpus(), &dest);
3040 if (err)
3041 return err;
3042
3043 if (irq_remapped(cfg)) {
3044 compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id);
3045 return 0;
3046 }
3047 3029
3048 if (x2apic_enabled()) 3030 if (x2apic_enabled())
3049 msg->address_hi = MSI_ADDR_BASE_HI | 3031 msg->address_hi |= MSI_ADDR_EXT_DEST_ID(dest);
3050 MSI_ADDR_EXT_DEST_ID(dest);
3051 else
3052 msg->address_hi = MSI_ADDR_BASE_HI;
3053 3032
3054 msg->address_lo = 3033 msg->address_lo =
3055 MSI_ADDR_BASE_LO | 3034 MSI_ADDR_BASE_LO |
@@ -3068,6 +3047,30 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
3068 MSI_DATA_DELIVERY_FIXED: 3047 MSI_DATA_DELIVERY_FIXED:
3069 MSI_DATA_DELIVERY_LOWPRI) | 3048 MSI_DATA_DELIVERY_LOWPRI) |
3070 MSI_DATA_VECTOR(cfg->vector); 3049 MSI_DATA_VECTOR(cfg->vector);
3050}
3051
3052#ifdef CONFIG_PCI_MSI
3053static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,
3054 struct msi_msg *msg, u8 hpet_id)
3055{
3056 struct irq_cfg *cfg;
3057 int err;
3058 unsigned dest;
3059
3060 if (disable_apic)
3061 return -ENXIO;
3062
3063 cfg = irq_cfg(irq);
3064 err = assign_irq_vector(irq, cfg, apic->target_cpus());
3065 if (err)
3066 return err;
3067
3068 err = apic->cpu_mask_to_apicid_and(cfg->domain,
3069 apic->target_cpus(), &dest);
3070 if (err)
3071 return err;
3072
3073 x86_msi.compose_msi_msg(pdev, irq, dest, msg, hpet_id);
3071 3074
3072 return 0; 3075 return 0;
3073} 3076}
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 06db44f4fbf5..ee4a17c22569 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -113,6 +113,7 @@ struct x86_platform_ops x86_platform = {
113EXPORT_SYMBOL_GPL(x86_platform); 113EXPORT_SYMBOL_GPL(x86_platform);
114struct x86_msi_ops x86_msi = { 114struct x86_msi_ops x86_msi = {
115 .setup_msi_irqs = native_setup_msi_irqs, 115 .setup_msi_irqs = native_setup_msi_irqs,
116 .compose_msi_msg = native_compose_msi_msg,
116 .teardown_msi_irq = native_teardown_msi_irq, 117 .teardown_msi_irq = native_teardown_msi_irq,
117 .teardown_msi_irqs = default_teardown_msi_irqs, 118 .teardown_msi_irqs = default_teardown_msi_irqs,
118 .restore_msi_irqs = default_restore_msi_irqs, 119 .restore_msi_irqs = default_restore_msi_irqs,
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 339260c98cf9..158091b345cb 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -150,6 +150,7 @@ static void __init irq_remapping_modify_x86_ops(void)
150 x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry; 150 x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
151 x86_msi.setup_msi_irqs = irq_remapping_setup_msi_irqs; 151 x86_msi.setup_msi_irqs = irq_remapping_setup_msi_irqs;
152 x86_msi.setup_hpet_msi = setup_hpet_msi_remapped; 152 x86_msi.setup_hpet_msi = setup_hpet_msi_remapped;
153 x86_msi.compose_msi_msg = compose_remapped_msi_msg;
153} 154}
154 155
155static __init int setup_nointremap(char *str) 156static __init int setup_nointremap(char *str)
@@ -295,10 +296,12 @@ void compose_remapped_msi_msg(struct pci_dev *pdev,
295 unsigned int irq, unsigned int dest, 296 unsigned int irq, unsigned int dest,
296 struct msi_msg *msg, u8 hpet_id) 297 struct msi_msg *msg, u8 hpet_id)
297{ 298{
298 if (!remap_ops || !remap_ops->compose_msi_msg) 299 struct irq_cfg *cfg = irq_get_chip_data(irq);
299 return;
300 300
301 remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id); 301 if (!irq_remapped(cfg))
302 native_compose_msi_msg(pdev, irq, dest, msg, hpet_id);
303 else if (remap_ops && remap_ops->compose_msi_msg)
304 remap_ops->compose_msi_msg(pdev, irq, dest, msg, hpet_id);
302} 305}
303 306
304static int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec) 307static int msi_alloc_remapped_irq(struct pci_dev *pdev, int irq, int nvec)