Improve IRQ remapping abstraction in x86 core code
Joerg Roedel
maintainerv4 cover Improve IRQ remapping abstraction in x86 core code
Hi,
here is the fourth version of the patch-set to improve the abstraction of interrupt remapping in the x86 core code. A more detailed description can be found in the original post at:
https://lkml.org/lkml/2012/8/7/317
Changes from v3->v4:
* Rebased to v3.7-rc6
* Added Acked-bys
* Fixed problems with AMD IRQ remapping code that came up in testing
Changes from v2->v3:
* Rebased to v3.6-rc7
* Worked in most comments on v2 by Sebastian Andrzej Siewior
Changes from v1->v2:
* Fixed a couple of compile issues on i386 (reported by Fengguang Wu, thanks a lot)
* Rebased to Linux v3.6-rc2
Please review.
Cheers,
Joerg
Joerg Roedel
maintainerPATCH v4 1/19 x86, apic: Move irq_remapping_enabled checks into IRQ-remapping code
Move the three easy to move checks in the x86' apic.c file into the IRQ-remapping code.
--- arch/x86/kernel/apic/apic.c | 9 +++------ drivers/iommu/irq_remapping.c | 11 +++++++++-- 2 files changed, 12 insertions(+), 8 deletions(-)
arch/x86/kernel/apic/apic.c +3 -6
@@ -1444,8 +1444,7 @@ void __init bsp_end_local_APIC_setup(void)* Now that local APIC setup is completed for BP, configure the fault * handling for interrupt remapping. */ -if (irq_remapping_enabled) -irq_remap_enable_fault_handling (); +irq_remap_enable_fault_handling (); }
@@ -2218,8 +2217,7 @@ static int lapic_suspend(void)local_irq_save (flags);disable_local_APIC (); -if (irq_remapping_enabled) -irq_remapping_disable (); +irq_remapping_disable ();local_irq_restore (flags);return 0 ;
@@ -2287,8 +2285,7 @@ static void lapic_resume(void)apic_write (APIC_ESR ,0 );apic_read (APIC_ESR ); -if (irq_remapping_enabled) -irq_remapping_reenable (x2apic_mode); +irq_remapping_reenable (x2apic_mode);local_irq_restore (flags); }
drivers/iommu/irq_remapping.c +9 -2
@@ -87,7 +87,9 @@ int __init irq_remapping_enable(void)void irq_remapping_disable (void ) { -if (!remap_ops || !remap_ops->disable) +if (!irq_remapping_enabled || + !remap_ops || + !remap_ops->disable)return ; remap_ops->disable ();
@@ -95,7 +97,9 @@ void irq_remapping_disable(void)int irq_remapping_reenable (int mode) { -if (!remap_ops || !remap_ops->reenable) +if (!irq_remapping_enabled || + !remap_ops || + !remap_ops->reenable)return 0 ;return remap_ops->reenable (mode);
@@ -103,6 +107,9 @@ int irq_remapping_reenable(int mode)int __init irq_remap_enable_fault_handling (void ) { +if (!irq_remapping_enabled) +return 0 ; +if (!remap_ops || !remap_ops->enable_faulting)return -ENODEV ;
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 2/19 x86, apic: Mask IO-APIC and PIC unconditionally on LAPIC resume
In reply to Joerg RoedelIO-APIC and PIC use the same resume routines when IRQ remapping is enabled or disabled. So it should be safe to mask the other APICs for the IRQ-remapping-disabled case too.
--- arch/x86/kernel/apic/apic.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
arch/x86/kernel/apic/apic.c +9 -10
@@ -2233,16 +2233,15 @@ static void lapic_resume(void)return ;local_irq_save (flags); -if (irq_remapping_enabled) { -/* -* IO-APIC and PIC have their own resume routines. -* We just mask them here to make sure the interrupt -* subsystem is completely quiet while we enable x2apic -* and interrupt-remapping. -*/ -mask_ioapic_entries (); - legacy_pic->mask_all (); - } + +/* +* IO-APIC and PIC have their own resume routines. +* We just mask them here to make sure the interrupt +* subsystem is completely quiet while we enable x2apic +* and interrupt-remapping. +*/ +mask_ioapic_entries (); + legacy_pic->mask_all ();if (x2apic_mode)enable_x2apic ();
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 3/19 x86, io_apic: Introduce x86_io_apic_ops.disable()
In reply to Joerg RoedelThis function pointer is used to call a system-specific function for disabling the IO-APIC. Currently this is used for IRQ remapping which has its own disable routine.
Also introduce the necessary infrastructure in the interrupt remapping code to overwrite this and other function pointers as necessary by interrupt remapping.
--- arch/x86/include/asm/io_apic.h | 2 ++ arch/x86/include/asm/x86_init.h | 9 +++++---- arch/x86/kernel/apic/io_apic.c | 41 ++++++++++++++++++--------------------- arch/x86/kernel/x86_init.c | 9 +++++---- drivers/iommu/irq_remapping.c | 31 ++++++++++++++++++++++++++++- 5 files changed, 61 insertions(+), 31 deletions(-)
arch/x86/include/asm/io_apic.h +2 -0
@@ -179,6 +179,7 @@ extern void __init native_io_apic_init_mappings(void);extern unsigned int native_io_apic_read (unsigned int apic,unsigned int reg);extern void native_io_apic_write (unsigned int apic,unsigned int reg,unsigned int val);extern void native_io_apic_modify (unsigned int apic,unsigned int reg,unsigned int val); +extern void native_disable_io_apic (void );static inline unsigned int io_apic_read (unsigned int apic,unsigned int reg) {
@@ -223,6 +224,7 @@ static inline void disable_ioapic_support(void) { }#define native_io_apic_read NULL#define native_io_apic_write NULL#define native_io_apic_modify NULL +#define native_disable_io_apic NULL#endif #endif /* _ASM_X86_IO_APIC_H */
arch/x86/include/asm/x86_init.h +5 -4
@@ -190,10 +190,11 @@ struct x86_msi_ops { };struct x86_io_apic_ops { -void (*init) (void ); -unsigned int (*read) (unsigned int apic,unsigned int reg); -void (*write) (unsigned int apic,unsigned int reg,unsigned int value); -void (*modify)(unsigned int apic,unsigned int reg,unsigned int value); +void (*init) (void ); +unsigned int (*read) (unsigned int apic,unsigned int reg); +void (*write) (unsigned int apic,unsigned int reg,unsigned int value); +void (*modify) (unsigned int apic,unsigned int reg,unsigned int value); +void (*disable)(void ); };extern struct x86_init_ops x86_init;
arch/x86/kernel/apic/io_apic.c +19 -22
61 lines not on this page · raw message
arch/x86/kernel/x86_init.c +5 -4
@@ -118,8 +118,9 @@ struct x86_msi_ops x86_msi = { };struct x86_io_apic_ops x86_io_apic_ops = { - .init = native_io_apic_init_mappings, - .read = native_io_apic_read, - .write = native_io_apic_write, - .modify = native_io_apic_modify, + .init = native_io_apic_init_mappings, + .read = native_io_apic_read, + .write = native_io_apic_write, + .modify = native_io_apic_modify, + .disable = native_disable_io_apic, };
drivers/iommu/irq_remapping.c +30 -1
@@ -1,3 +1,4 @@ +#include <linux/cpumask.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/cpumask.h>
@@ -6,6 +7,9 @@#include <asm/hw_irq.h> #include <asm/irq_remapping.h> +#include <asm/processor.h> +#include <asm/x86_init.h> +#include <asm/apic.h> #include "irq_remapping.h"
@@ -17,6 +21,24 @@ int no_x2apic_optout;static struct irq_remap_ops *remap_ops; +static void irq_remapping_disable_io_apic (void ) +{ +/* +* With interrupt-remapping, for now we will use virtual wire A +* mode, as virtual wire B is little complex (need to configure +* both IOAPIC RTE as well as interrupt-remapping table entry). +* As this gets called during crash dump, keep this simple for +* now. +*/ +if (cpu_has_apic ||apic_from_smp_config ()) +disconnect_bsp_APIC (0 ); +} + +static void __init irq_remapping_modify_x86_ops (void ) +{ + x86_io_apic_ops.disable = irq_remapping_disable_io_apic; +} +static __init int setup_nointremap (char *str) { disable_irq_remap =1 ;
@@ -79,10 +101,17 @@ int __init irq_remapping_prepare(void)int __init irq_remapping_enable (void ) { +int ret; +if (!remap_ops || !remap_ops->enable)return -ENODEV ; -return remap_ops->enable (); + ret = remap_ops->enable (); + +if (irq_remapping_enabled) +irq_remapping_modify_x86_ops (); + +return ret; }void irq_remapping_disable (void )
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 4/19 x86, io_apic: Introduce x86_io_apic_ops.print_entries for debugging
In reply to Joerg RoedelThis call-back is used to dump IO-APIC entries for debugging purposes into the kernel log. VT-d needs a special routine for this and will overwrite the default.
--- arch/x86/include/asm/io_apic.h | 3 + arch/x86/include/asm/x86_init.h | 1 + arch/x86/kernel/apic/io_apic.c | 109 ++++++++++++++++++----------------- arch/x86/kernel/x86_init.c | 1 + drivers/iommu/intel_irq_remapping.c | 8 +++ 5 files changed, 69 insertions(+), 53 deletions(-)
arch/x86/include/asm/io_apic.h +3 -0
@@ -180,6 +180,8 @@ extern unsigned int native_io_apic_read(unsigned int apic, unsigned int reg);extern void native_io_apic_write (unsigned int apic,unsigned int reg,unsigned int val);extern void native_io_apic_modify (unsigned int apic,unsigned int reg,unsigned int val);extern void native_disable_io_apic (void ); +extern void native_io_apic_print_entries (unsigned int apic,unsigned int nr_entries); +extern void intel_ir_io_apic_print_entries (unsigned int apic,unsigned int nr_entries);static inline unsigned int io_apic_read (unsigned int apic,unsigned int reg) {
@@ -225,6 +227,7 @@ static inline void disable_ioapic_support(void) { }#define native_io_apic_write NULL#define native_io_apic_modify NULL#define native_disable_io_apic NULL +#define native_io_apic_print_entries NULL#endif #endif /* _ASM_X86_IO_APIC_H */
arch/x86/include/asm/x86_init.h +1 -0
@@ -195,6 +195,7 @@ struct x86_io_apic_ops {void (*write) (unsigned int apic,unsigned int reg,unsigned int value);void (*modify) (unsigned int apic,unsigned int reg,unsigned int value);void (*disable)(void ); +void (*print_entries)(unsigned int apic,unsigned int nr_entries); };extern struct x86_init_ops x86_init;
arch/x86/kernel/apic/io_apic.c +56 -53
123 lines not on this page · raw message
arch/x86/kernel/x86_init.c +1 -0
@@ -123,4 +123,5 @@ struct x86_io_apic_ops x86_io_apic_ops = { .write = native_io_apic_write, .modify = native_io_apic_modify, .disable = native_disable_io_apic, + .print_entries = native_io_apic_print_entries, };
drivers/iommu/intel_irq_remapping.c +8 -0
@@ -617,6 +617,14 @@ static int __init intel_enable_irq_remapping(void) goto error; irq_remapping_enabled =1 ; + +/* +* VT-d has a different layout for IO-APIC entries when +* interrupt remapping is enabled. So it needs a special routine +* to print IO-APIC entries for debugging purposes too. +*/ + x86_io_apic_ops.print_entries = intel_ir_io_apic_print_entries; +pr_info ("Enabled IRQ remapping in %s mode\n" , eim ?"x2apic" :"xapic" );return eim ?IRQ_REMAP_X2APIC_MODE :IRQ_REMAP_XAPIC_MODE ;
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 5/19 x86, hpet: Introduce x86_msi_ops.setup_hpet_msi
In reply to Joerg RoedelThis function pointer can be overwritten by the IRQ remapping code. The irq_remapping_enabled check can be removed from default_setup_hpet_msi.
--- arch/x86/include/asm/hpet.h | 5 +++-- arch/x86/include/asm/x86_init.h | 1 + arch/x86/kernel/apic/io_apic.c | 7 +------ arch/x86/kernel/hpet.c | 2 +- arch/x86/kernel/x86_init.c | 10 ++++++---- drivers/iommu/irq_remapping.c | 3 ++- 6 files changed, 14 insertions(+), 14 deletions(-)
arch/x86/include/asm/hpet.h +3 -2
@@ -80,9 +80,9 @@ extern void hpet_msi_write(struct hpet_dev *hdev, struct msi_msg *msg);extern void hpet_msi_read (struct hpet_dev *hdev,struct msi_msg *msg);#ifdef CONFIG_PCI_MSI -extern int arch_setup_hpet_msi (unsigned int irq,unsigned int id); +extern int default_setup_hpet_msi (unsigned int irq,unsigned int id);#else -static inline int arch_setup_hpet_msi (unsigned int irq,unsigned int id) +static inline int default_setup_hpet_msi (unsigned int irq,unsigned int id) {return -EINVAL ; }
@@ -111,6 +111,7 @@ extern void hpet_unregister_irq_handler(rtc_irq_handler handler);static inline int hpet_enable (void ) {return 0 ; }static inline int is_hpet_enabled (void ) {return 0 ; }#define hpet_readl (a) 0 +#define default_setup_hpet_msi NULL#endif #endif /* _ASM_X86_HPET_H */
arch/x86/include/asm/x86_init.h +1 -0
@@ -187,6 +187,7 @@ struct x86_msi_ops {void (*teardown_msi_irq)(unsigned int irq);void (*teardown_msi_irqs)(struct pci_dev *dev);void (*restore_msi_irqs)(struct pci_dev *dev,int irq); +int (*setup_hpet_msi)(unsigned int irq,unsigned int id); };struct x86_io_apic_ops {
arch/x86/kernel/apic/io_apic.c +1 -6
@@ -3310,17 +3310,12 @@ static struct irq_chip hpet_msi_type = { .irq_retrigger = ioapic_retrigger_irq, }; -int arch_setup_hpet_msi (unsigned int irq,unsigned int id) +int default_setup_hpet_msi (unsigned int irq,unsigned int id) {struct irq_chip *chip = &hpet_msi_type;struct msi_msg msg;int ret; -if (irq_remapping_enabled) { -if (!setup_hpet_msi_remapped (irq, id)) -return -1 ; - } - ret =msi_compose_msg (NULL , irq, &msg, id);if (ret <0 )return ret;
arch/x86/kernel/hpet.c +1 -1
@@ -478,7 +478,7 @@ static int hpet_msi_next_event(unsigned long delta,static int hpet_setup_msi_irq (unsigned int irq) { -if (arch_setup_hpet_msi (irq, hpet_blockid)) { +if (x86_msi.setup_hpet_msi (irq, hpet_blockid)) {destroy_irq (irq);return -EINVAL ; }
arch/x86/kernel/x86_init.c +6 -4
@@ -19,6 +19,7 @@#include <asm/time.h> #include <asm/irq.h> #include <asm/io_apic.h> +#include <asm/hpet.h> #include <asm/pat.h> #include <asm/tsc.h> #include <asm/iommu.h>
@@ -111,10 +112,11 @@ struct x86_platform_ops x86_platform = {EXPORT_SYMBOL_GPL (x86_platform);struct x86_msi_ops x86_msi = { - .setup_msi_irqs = native_setup_msi_irqs, - .teardown_msi_irq = native_teardown_msi_irq, - .teardown_msi_irqs = default_teardown_msi_irqs, - .restore_msi_irqs = default_restore_msi_irqs, + .setup_msi_irqs = native_setup_msi_irqs, + .teardown_msi_irq = native_teardown_msi_irq, + .teardown_msi_irqs = default_teardown_msi_irqs, + .restore_msi_irqs = default_restore_msi_irqs, + .setup_hpet_msi = default_setup_hpet_msi, };struct x86_io_apic_ops x86_io_apic_ops = {
drivers/iommu/irq_remapping.c +2 -1
@@ -36,7 +36,8 @@ static void irq_remapping_disable_io_apic(void)static void __init irq_remapping_modify_x86_ops (void ) { - x86_io_apic_ops.disable = irq_remapping_disable_io_apic; + x86_io_apic_ops.disable = irq_remapping_disable_io_apic; + x86_msi.setup_hpet_msi = setup_hpet_msi_remapped; }static __init int setup_nointremap (char *str)
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 6/19 x86, msi: Use IRQ remapping specific setup_msi_irqs routine
In reply to Joerg RoedelUse seperate routines to setup MSI IRQs for bothirq_remapping_enabled cases.
--- arch/x86/include/asm/irq_remapping.h | 12 ------- arch/x86/include/asm/pci.h | 2 ++ arch/x86/kernel/apic/io_apic.c | 26 ++-------------- drivers/iommu/irq_remapping.c | 57 ++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 38 deletions(-)
arch/x86/include/asm/irq_remapping.h +0 -12
@@ -47,9 +47,6 @@ extern void free_remapped_irq(int irq);extern void compose_remapped_msi_msg (struct pci_dev *pdev,unsigned int irq,unsigned int dest,struct msi_msg *msg,u8 hpet_id); -extern int msi_alloc_remapped_irq (struct pci_dev *pdev,int irq,int nvec); -extern int msi_setup_remapped_irq (struct pci_dev *pdev,unsigned int irq, -int index,int sub_handle);extern int setup_hpet_msi_remapped (unsigned int irq,unsigned int id);#else /* CONFIG_IRQ_REMAP */
@@ -83,15 +80,6 @@ static inline void compose_remapped_msi_msg(struct pci_dev *pdev, struct msi_msg *msg, u8 hpet_id) { } -static inline int msi_alloc_remapped_irq (struct pci_dev *pdev,int irq,int nvec) -{ -return -ENODEV ; -} -static inline int msi_setup_remapped_irq (struct pci_dev *pdev,unsigned int irq, -int index,int sub_handle) -{ -return -ENODEV ; -}static inline int setup_hpet_msi_remapped (unsigned int irq,unsigned int id) {return -ENODEV ;
arch/x86/include/asm/pci.h +2 -0
@@ -121,9 +121,11 @@ static inline void x86_restore_msi_irqs(struct pci_dev *dev, int irq)#define arch_teardown_msi_irq x86_teardown_msi_irq#define arch_restore_msi_irqs x86_restore_msi_irqs/* implemented in arch/x86/kernel/apic/io_apic. */ +struct msi_desc ;int native_setup_msi_irqs (struct pci_dev *dev,int nvec,int type);void native_teardown_msi_irq (unsigned int irq);void native_restore_msi_irqs (struct pci_dev *dev,int irq); +int setup_msi_irq (struct pci_dev *dev,struct msi_desc *msidesc,int irq);/* default to the implementation in drivers/lib/msi.c */ #define HAVE_DEFAULT_MSI_TEARDOWN_IRQS #define HAVE_DEFAULT_MSI_RESTORE_IRQS
arch/x86/kernel/apic/io_apic.c +3 -23
@@ -3148,7 +3148,7 @@ static struct irq_chip msi_chip = { .irq_retrigger = ioapic_retrigger_irq, }; -static int setup_msi_irq (struct pci_dev *dev,struct msi_desc *msidesc,int irq) +int setup_msi_irq (struct pci_dev *dev,struct msi_desc *msidesc,int irq) {struct irq_chip *chip = &msi_chip;struct msi_msg msg;
@@ -3175,9 +3175,9 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)int native_setup_msi_irqs (struct pci_dev *dev,int nvec,int type) { -int node, ret, sub_handle, index =0 ;unsigned int irq, irq_want;struct msi_desc *msidesc; +int node, ret;/* x86 doesn't support multiple MSI yet */ if (type ==PCI_CAP_ID_MSI && nvec >1 )
@@ -3185,36 +3185,16 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) node =dev_to_node (&dev->dev); irq_want = nr_irqs_gsi; - sub_handle =0 ;list_for_each_entry (msidesc, &dev->msi_list, list) { irq =create_irq_nr (irq_want, node);if (irq ==0 )return -1 ; + irq_want = irq +1 ; -if (!irq_remapping_enabled) - goto no_ir; -if (!sub_handle) { -/* -* allocate the consecutive block of IRTE's -* for 'nvec' -*/ - index =msi_alloc_remapped_irq (dev, irq, nvec); -if (index <0 ) { - ret = index; - goto error; - } - }else { - ret =msi_setup_remapped_irq (dev, irq, index, - sub_handle); -if (ret <0 ) - goto error; - } -no_ir: ret =setup_msi_irq (dev, msidesc, irq);if (ret <0 ) goto error; - sub_handle++; }return 0 ;
drivers/iommu/irq_remapping.c +54 -3
90 lines not on this page · raw message
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 7/19 x86, io_apic: Introduce set_affinity function pointer
In reply to Joerg RoedelWith interrupt remapping a special function is used to change the affinity of an IO-APIC interrupt. Abstract this with a function pointer.
--- arch/x86/include/asm/io_apic.h | 4 ++++ arch/x86/include/asm/irq_remapping.h | 9 --------- arch/x86/include/asm/x86_init.h | 6 ++++++ arch/x86/kernel/apic/io_apic.c | 17 +++++++---------- arch/x86/kernel/x86_init.c | 1 + drivers/iommu/irq_remapping.c | 4 ++++ 6 files changed, 22 insertions(+), 19 deletions(-)
arch/x86/include/asm/io_apic.h +4 -0
@@ -182,6 +182,9 @@ extern void native_io_apic_modify(unsigned int apic, unsigned int reg, unsignedextern void native_disable_io_apic (void );extern void native_io_apic_print_entries (unsigned int apic,unsigned int nr_entries);extern void intel_ir_io_apic_print_entries (unsigned int apic,unsigned int nr_entries); +extern int native_ioapic_set_affinity (struct irq_data *, +const struct cpumask *, +bool );static inline unsigned int io_apic_read (unsigned int apic,unsigned int reg) {
@@ -228,6 +231,7 @@ static inline void disable_ioapic_support(void) { }#define native_io_apic_modify NULL#define native_disable_io_apic NULL#define native_io_apic_print_entries NULL +#define native_ioapic_set_affinity NULL#endif #endif /* _ASM_X86_IO_APIC_H */
arch/x86/include/asm/irq_remapping.h +0 -9
@@ -40,9 +40,6 @@ extern int setup_ioapic_remapped_entry(int irq,unsigned int destination, int vector, struct io_apic_irq_attr *attr); -extern int set_remapped_irq_affinity (struct irq_data *data, -const struct cpumask *mask, -bool force);extern void free_remapped_irq (int irq); extern void compose_remapped_msi_msg(struct pci_dev *pdev, unsigned int irq, unsigned int dest,
@@ -68,12 +65,6 @@ static inline int setup_ioapic_remapped_entry(int irq, {return -ENODEV ; } -static inline int set_remapped_irq_affinity (struct irq_data *data, -const struct cpumask *mask, -bool force) -{ -return 0 ; -}static inline void free_remapped_irq (int irq) { } static inline void compose_remapped_msi_msg(struct pci_dev *pdev, unsigned int irq, unsigned int dest,
arch/x86/include/asm/x86_init.h +6 -0
@@ -190,6 +190,9 @@ struct x86_msi_ops {int (*setup_hpet_msi)(unsigned int irq,unsigned int id); }; +struct irq_data ; +struct cpumask ; +struct x86_io_apic_ops {void (*init) (void );unsigned int (*read) (unsigned int apic,unsigned int reg);
@@ -197,6 +200,9 @@ struct x86_io_apic_ops {void (*modify) (unsigned int apic,unsigned int reg,unsigned int value);void (*disable)(void );void (*print_entries)(unsigned int apic,unsigned int nr_entries); +int (*set_affinity)(struct irq_data *data, +const struct cpumask *mask, +bool force); };extern struct x86_init_ops x86_init;
arch/x86/kernel/apic/io_apic.c +7 -10
@@ -2381,9 +2381,10 @@ int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,return 0 ; } -static int -ioapic_set_affinity (struct irq_data *data,const struct cpumask *mask, -bool force) + +int native_ioapic_set_affinity (struct irq_data *data, +const struct cpumask *mask, +bool force) {unsigned int dest, irq = data->irq;unsigned long flags;
@@ -2582,8 +2583,7 @@ static void irq_remap_modify_chip_defaults(struct irq_chip *chip) chip->irq_print_chip = ir_print_prefix; chip->irq_ack = ir_ack_apic_edge; chip->irq_eoi = ir_ack_apic_level; - - chip->irq_set_affinity = set_remapped_irq_affinity; + chip->irq_set_affinity = x86_io_apic_ops.set_affinity; }#endif /* CONFIG_IRQ_REMAP */
@@ -2594,7 +2594,7 @@ static struct irq_chip ioapic_chip __read_mostly = { .irq_unmask = unmask_ioapic_irq, .irq_ack = ack_apic_edge, .irq_eoi = ack_apic_level, - .irq_set_affinity = ioapic_set_affinity, + .irq_set_affinity = native_ioapic_set_affinity, .irq_retrigger = ioapic_retrigger_irq, };
@@ -3669,10 +3669,7 @@ void __init setup_ioapic_dest(void)else mask = apic->target_cpus (); -if (irq_remapping_enabled) -set_remapped_irq_affinity (idata, mask, false); -else -ioapic_set_affinity (idata, mask, false); + x86_io_apic_ops.set_affinity (idata, mask, false); } }
arch/x86/kernel/x86_init.c +1 -0
@@ -126,4 +126,5 @@ struct x86_io_apic_ops x86_io_apic_ops = { .modify = native_io_apic_modify, .disable = native_disable_io_apic, .print_entries = native_io_apic_print_entries, + .set_affinity = native_ioapic_set_affinity, };
drivers/iommu/irq_remapping.c +4 -0
@@ -26,6 +26,9 @@ static struct irq_remap_ops *remap_ops;static int msi_alloc_remapped_irq (struct pci_dev *pdev,int irq,int nvec);static int msi_setup_remapped_irq (struct pci_dev *pdev,unsigned int irq,int index,int sub_handle); +static int set_remapped_irq_affinity (struct irq_data *data, +const struct cpumask *mask, +bool force);static void irq_remapping_disable_io_apic (void ) {
@@ -87,6 +90,7 @@ error:static void __init irq_remapping_modify_x86_ops (void ) { x86_io_apic_ops.disable = irq_remapping_disable_io_apic; + x86_io_apic_ops.set_affinity = set_remapped_irq_affinity; x86_msi.setup_msi_irqs = irq_remapping_setup_msi_irqs; x86_msi.setup_hpet_msi = setup_hpet_msi_remapped; }
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 8/19 x86, io_apic: Convert setup_ioapic_entry to function pointer
In reply to Joerg RoedelThis pointer is changed to a different function when IRQ remapping is enabled.
--- arch/x86/include/asm/io_apic.h | 5 +++++ arch/x86/include/asm/x86_init.h | 5 +++++ arch/x86/kernel/apic/io_apic.c | 14 +++++--------- arch/x86/kernel/x86_init.c | 1 + drivers/iommu/irq_remapping.c | 1 + 5 files changed, 17 insertions(+), 9 deletions(-)
arch/x86/include/asm/io_apic.h +5 -0
@@ -149,6 +149,10 @@ extern int io_apic_set_pci_routing(struct device *dev, int irq,void setup_IO_APIC_irq_extra (u32 gsi);extern void ioapic_insert_resources (void ); +extern int native_setup_ioapic_entry (int ,struct IO_APIC_route_entry *, +unsigned int ,int , +struct io_apic_irq_attr *); +int io_apic_setup_irq_pin_once (unsigned int irq,int node,struct io_apic_irq_attr *attr);extern int save_ioapic_entries (void );
@@ -232,6 +236,7 @@ static inline void disable_ioapic_support(void) { }#define native_disable_io_apic NULL#define native_io_apic_print_entries NULL#define native_ioapic_set_affinity NULL +#define native_setup_ioapic_entry NULL#endif #endif /* _ASM_X86_IO_APIC_H */
arch/x86/include/asm/x86_init.h +5 -0
@@ -190,6 +190,8 @@ struct x86_msi_ops {int (*setup_hpet_msi)(unsigned int irq,unsigned int id); }; +struct IO_APIC_route_entry ; +struct io_apic_irq_attr ;struct irq_data ;struct cpumask ;
@@ -203,6 +205,9 @@ struct x86_io_apic_ops {int (*set_affinity)(struct irq_data *data,const struct cpumask *mask,bool force); +int (*setup_entry)(int irq,struct IO_APIC_route_entry *entry, +unsigned int destination,int vector, +struct io_apic_irq_attr *attr); };extern struct x86_init_ops x86_init;
arch/x86/kernel/apic/io_apic.c +5 -9
@@ -1319,14 +1319,10 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg, fasteoi ? "fasteoi" : "edge"); } -static int setup_ioapic_entry (int irq,struct IO_APIC_route_entry *entry, -unsigned int destination,int vector, -struct io_apic_irq_attr *attr) +int native_setup_ioapic_entry (int irq,struct IO_APIC_route_entry *entry, +unsigned int destination,int vector, +struct io_apic_irq_attr *attr) { -if (irq_remapping_enabled) -return setup_ioapic_remapped_entry (irq, entry, destination, - vector, attr); -memset (entry,0 ,sizeof (*entry)); entry->delivery_mode = apic->irq_delivery_mode;
@@ -1384,8 +1380,8 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, attr->ioapic,mpc_ioapic_id (attr->ioapic), attr->ioapic_pin, cfg->vector, irq, attr->trigger, attr->polarity, dest); -if (setup_ioapic_entry (irq, &entry, dest, cfg->vector, attr)) { -pr_warn ("Failed to setup ioapic entry for ioapic %d, pin %d\n" , +if (x86_io_apic_ops.setup_entry (irq, &entry, dest, cfg->vector, attr)) { +pr_warn ("Failed to setup ioapic entry for ioapic %d, pin %d\n" ,mpc_ioapic_id (attr->ioapic), attr->ioapic_pin);__clear_irq_vector (irq, cfg);
arch/x86/kernel/x86_init.c +1 -0
@@ -127,4 +127,5 @@ struct x86_io_apic_ops x86_io_apic_ops = { .disable = native_disable_io_apic, .print_entries = native_io_apic_print_entries, .set_affinity = native_ioapic_set_affinity, + .setup_entry = native_setup_ioapic_entry, };
drivers/iommu/irq_remapping.c +1 -0
@@ -91,6 +91,7 @@ static void __init irq_remapping_modify_x86_ops(void) { x86_io_apic_ops.disable = irq_remapping_disable_io_apic; x86_io_apic_ops.set_affinity = set_remapped_irq_affinity; + x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry; x86_msi.setup_msi_irqs = irq_remapping_setup_msi_irqs; x86_msi.setup_hpet_msi = setup_hpet_msi_remapped; }
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 9/19 x86, io_apic: Move irq_remapping_enabled checks out of check_timer()
In reply to Joerg RoedelMove these checks to IRQ remapping code by introducing the panic_on_irq_remap() function.
--- arch/x86/include/asm/irq_remapping.h | 5 +++++ arch/x86/kernel/apic/io_apic.c | 6 ++---- drivers/iommu/irq_remapping.c | 6 ++++++ 3 files changed, 13 insertions(+), 4 deletions(-)
arch/x86/include/asm/irq_remapping.h +5 -0
@@ -45,6 +45,7 @@ extern void compose_remapped_msi_msg(struct pci_dev *pdev, unsigned int irq, unsigned int dest, struct msi_msg *msg, u8 hpet_id);extern int setup_hpet_msi_remapped (unsigned int irq,unsigned int id); +extern void panic_if_irq_remap (const char *msg);#else /* CONFIG_IRQ_REMAP */
@@ -75,6 +76,10 @@ static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id) {return -ENODEV ; } + +static inline void panic_if_irq_remap (const char *msg) +{ +}#endif /* CONFIG_IRQ_REMAP */ #endif /* __X86_IRQ_REMAPPING_H */
arch/x86/kernel/apic/io_apic.c +2 -4
@@ -2789,8 +2789,7 @@ static inline void __init check_timer(void)* 8259A. */ if (pin1 ==-1 ) { -if (irq_remapping_enabled) -panic ("BIOS bug: timer not connected to IO-APIC" ); +panic_if_irq_remap ("BIOS bug: timer not connected to IO-APIC" ); pin1 = pin2; apic1 = apic2; no_pin1 =1 ;
@@ -2822,8 +2821,7 @@ static inline void __init check_timer(void)clear_IO_APIC_pin (0 , pin1); goto out; } -if (irq_remapping_enabled) -panic ("timer doesn't work through Interrupt-remapped IO-APIC" ); +panic_if_irq_remap ("timer doesn't work through Interrupt-remapped IO-APIC" );local_irq_disable ();clear_IO_APIC_pin (apic1, pin1);if (!no_pin1)
drivers/iommu/irq_remapping.c +6 -0
@@ -266,3 +266,9 @@ int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)return remap_ops->setup_hpet_msi (irq, id); } + +void panic_if_irq_remap (const char *msg) +{ +if (irq_remapping_enabled) +panic (msg); +}
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 10/19 x86, io_apic: Remove irq_remapping_enabled check in setup_timer_IRQ0_pin
In reply to Joerg RoedelThis function is only called when irq-remapping is disabled.
--- arch/x86/kernel/apic/io_apic.c | 3 --- 1 file changed, 3 deletions(-)
arch/x86/kernel/apic/io_apic.c +0 -3
@@ -1489,9 +1489,6 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx,struct IO_APIC_route_entry entry;unsigned int dest; -if (irq_remapping_enabled) -return ; -memset (&entry,0 ,sizeof (entry));/*
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 11/19 x86, irq: Move irq_remapping_enabled declaration to iommu code
In reply to Joerg RoedelRemove the last left-over from this flag from x86 code.
--- arch/x86/include/asm/irq_remapping.h | 4 ---- drivers/iommu/dmar.c | 2 ++ drivers/iommu/intel-iommu.c | 2 ++ drivers/iommu/irq_remapping.h | 1 + 4 files changed, 5 insertions(+), 4 deletions(-)
arch/x86/include/asm/irq_remapping.h +0 -4
@@ -26,8 +26,6 @@#ifdef CONFIG_IRQ_REMAP -extern int irq_remapping_enabled; -extern void setup_irq_remapping_ops (void );extern int irq_remapping_supported (void );extern int irq_remapping_prepare (void );
@@ -49,8 +47,6 @@ extern void panic_if_irq_remap(const char *msg);#else /* CONFIG_IRQ_REMAP */ -#define irq_remapping_enabled 0 -static inline void setup_irq_remapping_ops (void ) { }static inline int irq_remapping_supported (void ) {return 0 ; }static inline int irq_remapping_prepare (void ) {return -ENODEV ; }
drivers/iommu/dmar.c +2 -0
@@ -41,6 +41,8 @@#include <asm/irq_remapping.h> #include <asm/iommu_table.h> +#include "irq_remapping.h" +/* No locks are needed as DMA remapping hardware unit * list is constructed at boot time and hotplug of * these units are not supported by the architecture.
drivers/iommu/intel-iommu.c +2 -0
@@ -46,6 +46,8 @@#include <asm/cacheflush.h> #include <asm/iommu.h> +#include "irq_remapping.h" +#define ROOT_SIZE VTD_PAGE_SIZE#define CONTEXT_SIZE VTD_PAGE_SIZE
drivers/iommu/irq_remapping.h +1 -0
@@ -34,6 +34,7 @@ struct msi_msg;extern int disable_irq_remap;extern int disable_sourceid_checking;extern int no_x2apic_optout; +extern int irq_remapping_enabled;struct irq_remap_ops {/* Check whether Interrupt Remapping is supported */
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 12/19 x86, irq: Add data structure to keep AMD specific irq remapping information
In reply to Joerg RoedelAdd a data structure to store information the IOMMU driver can use to get from a 'struct irq_cfg' to the remapping entry.
--- arch/x86/include/asm/hw_irq.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
arch/x86/include/asm/hw_irq.h +11 -1
@@ -101,6 +101,7 @@ static inline void set_io_apic_irq_attr(struct io_apic_irq_attr *irq_attr, irq_attr->polarity = polarity; } +/* Intel specific interrupt remapping information */ struct irq_2_iommu {struct intel_iommu *iommu;u16 irte_index;
@@ -108,6 +109,12 @@ struct irq_2_iommu {u8 irte_mask; }; +/* AMD specific interrupt remapping information */ +struct irq_2_irte { +u16 devid;/* Device ID for IRTE table */ +u16 index;/* Index into IRTE table*/ +}; +/* * This is performance-critical, we want to do it O(1) *
@@ -120,7 +127,10 @@ struct irq_cfg {u8 vector; u8 move_in_progress : 1;#ifdef CONFIG_IRQ_REMAP -struct irq_2_iommu irq_2_iommu; +union { +struct irq_2_iommu irq_2_iommu; +struct irq_2_irte irq_2_irte; + };#endif };
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 13/19 x86, io-apic: Move CONFIG_IRQ_REMAP code out of x86 core
In reply to Joerg RoedelMove all the code to either to the header fileasm/irq_remapping.h or to drivers/iommu/.
--- arch/x86/include/asm/hw_irq.h | 1 + arch/x86/include/asm/io_apic.h | 5 ++++ arch/x86/include/asm/irq_remapping.h | 17 +++++++++++++ arch/x86/kernel/apic/io_apic.c | 44 +--------------------------------- drivers/iommu/intel_irq_remapping.c | 4 ++++ drivers/iommu/irq_remapping.c | 25 +++++++++++++++++++ 6 files changed, 53 insertions(+), 43 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -0
@@ -127,6 +127,7 @@ struct irq_cfg {u8 vector; u8 move_in_progress : 1; #ifdef CONFIG_IRQ_REMAP + u8 remapped : 1; union { struct irq_2_iommu irq_2_iommu; struct irq_2_irte irq_2_irte;
arch/x86/include/asm/io_apic.h +5 -0
@@ -144,6 +144,7 @@ extern int timer_through_8259; (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)struct io_apic_irq_attr ; +struct irq_cfg ;extern int io_apic_set_pci_routing (struct device *dev,int irq,struct io_apic_irq_attr *irq_attr);void setup_IO_APIC_irq_extra (u32 gsi);
@@ -152,6 +153,10 @@ extern void ioapic_insert_resources(void);extern int native_setup_ioapic_entry (int ,struct IO_APIC_route_entry *,unsigned int ,int ,struct io_apic_irq_attr *); +extern int native_setup_ioapic_entry (int ,struct IO_APIC_route_entry *, +unsigned int ,int , +struct io_apic_irq_attr *); +extern void eoi_ioapic_irq (unsigned int irq,struct irq_cfg *cfg);int io_apic_setup_irq_pin_once (unsigned int irq,int node,struct io_apic_irq_attr *attr);
arch/x86/include/asm/irq_remapping.h +17 -0
@@ -45,6 +45,13 @@ extern void compose_remapped_msi_msg(struct pci_dev *pdev,extern int setup_hpet_msi_remapped (unsigned int irq,unsigned int id);extern void panic_if_irq_remap (const char *msg); +static inline bool irq_remapped (struct irq_cfg *cfg) +{ +return (cfg->remapped ==1 ); +} + +void irq_remap_modify_chip_defaults (struct irq_chip *chip); +#else /* CONFIG_IRQ_REMAP */ static inline void setup_irq_remapping_ops (void ) { }
@@ -76,6 +83,16 @@ static inline int setup_hpet_msi_remapped(unsigned int irq, unsigned int id)static inline void panic_if_irq_remap (const char *msg) { } + +static inline bool irq_remapped (struct irq_cfg *cfg) +{ +return false; +} + +static inline void irq_remap_modify_chip_defaults (struct irq_chip *chip) +{ +} +#endif /* CONFIG_IRQ_REMAP */ #endif /* __X86_IRQ_REMAPPING_H */
arch/x86/kernel/apic/io_apic.c +1 -43
62 lines not on this page · raw message
drivers/iommu/intel_irq_remapping.c +4 -0
@@ -68,6 +68,7 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) {struct ir_table *table = iommu->ir_table;struct irq_2_iommu *irq_iommu =irq_2_iommu (irq); +struct irq_cfg *cfg =irq_get_chip_data (irq);u16 index, start_index;unsigned int mask =0 ;unsigned long flags;
@@ -115,6 +116,7 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)for (i = index; i < index + count; i++) table->base[i].present =1 ; + cfg->remapped =1 ; irq_iommu->iommu = iommu; irq_iommu->irte_index = index; irq_iommu->sub_handle =0 ;
@@ -155,6 +157,7 @@ static int map_irq_to_irte_handle(int irq, u16 *sub_handle)static int set_irte_irq (int irq,struct intel_iommu *iommu,u16 index,u16 subhandle) {struct irq_2_iommu *irq_iommu =irq_2_iommu (irq); +struct irq_cfg *cfg =irq_get_chip_data (irq);unsigned long flags;if (!irq_iommu)
@@ -162,6 +165,7 @@ static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subharaw_spin_lock_irqsave (&irq_2_ir_lock, flags); + cfg->remapped =1 ; irq_iommu->iommu = iommu; irq_iommu->irte_index = index; irq_iommu->sub_handle = subhandle;
drivers/iommu/irq_remapping.c +25 -0
@@ -1,3 +1,4 @@ +#include <linux/seq_file.h> #include <linux/cpumask.h> #include <linux/kernel.h> #include <linux/string.h>
@@ -272,3 +273,27 @@ void panic_if_irq_remap(const char *msg)if (irq_remapping_enabled)panic (msg); } + +static void ir_ack_apic_edge (struct irq_data *data) +{ +ack_APIC_irq (); +} + +static void ir_ack_apic_level (struct irq_data *data) +{ +ack_APIC_irq (); +eoi_ioapic_irq (data->irq, data->chip_data); +} + +static void ir_print_prefix (struct irq_data *data,struct seq_file *p) +{ +seq_printf (p," IR-%s" , data->chip->name); +} + +void irq_remap_modify_chip_defaults (struct irq_chip *chip) +{ + chip->irq_print_chip = ir_print_prefix; + chip->irq_ack = ir_ack_apic_edge; + chip->irq_eoi = ir_ack_apic_level; + chip->irq_set_affinity = x86_io_apic_ops.set_affinity; +}
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 14/19 x86, io-apic: Remove !irq_remapped() check from __target_IO_APIC_irq()
In reply to Joerg RoedelThis function is only called from default_ioapic_set_affinity() which is only used when interrupt remapping is disabled since the introduction of the set_affinity function pointer. So the check will always evaluate as true and can be removed.
--- arch/x86/kernel/apic/io_apic.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
arch/x86/kernel/apic/io_apic.c +2 -6
@@ -2311,12 +2311,8 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq apic = entry->apic; pin = entry->pin; -/* -* With interrupt-remapping, destination information comes -* from interrupt-remapping table entry. -*/ -if (!irq_remapped (cfg)) -io_apic_write (apic,0x11 + pin*2 , dest); + +io_apic_write (apic,0x11 + pin*2 , dest); reg =io_apic_read (apic,0x10 + pin*2 ); reg &= ~IO_APIC_REDIR_VECTOR_MASK ; reg |= vector;
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 15/19 x86, irq: Move irq_remapped() check into free_remapped_irq
In reply to Joerg RoedelThe function is called unconditionally now in IO-APIC code removing another irq_remapped() check from x86 core code.
--- arch/x86/kernel/apic/io_apic.c | 4 ++-- drivers/iommu/irq_remapping.c | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-)
arch/x86/kernel/apic/io_apic.c +2 -2
@@ -2994,8 +2994,8 @@ void destroy_irq(unsigned int irq)irq_set_status_flags (irq,IRQ_NOREQUEST |IRQ_NOPROBE ); -if (irq_remapped (cfg)) -free_remapped_irq (irq); +free_remapped_irq (irq); +raw_spin_lock_irqsave (&vector_lock, flags);__clear_irq_vector (irq, cfg);raw_spin_unlock_irqrestore (&vector_lock, flags);
drivers/iommu/irq_remapping.c +4 -1
@@ -227,10 +227,13 @@ int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask,void free_remapped_irq (int irq) { +struct irq_cfg *cfg =irq_get_chip_data (irq); +if (!remap_ops || !remap_ops->free_irq)return ; - remap_ops->free_irq (irq); +if (irq_remapped (cfg)) + remap_ops->free_irq (irq); } void compose_remapped_msi_msg(struct pci_dev *pdev,
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 16/19 x86, irq: Introduce setup_remapped_irq()
In reply to Joerg RoedelThis function does irq-remapping specific interrupt setup like modifying the chip defaults.
--- arch/x86/include/asm/irq_remapping.h | 9 +++++++++ arch/x86/kernel/apic/io_apic.c | 13 +++---------- drivers/iommu/irq_remapping.c | 9 +++++++++ 3 files changed, 21 insertions(+), 10 deletions(-)
arch/x86/include/asm/irq_remapping.h +9 -0
@@ -44,6 +44,9 @@ extern void compose_remapped_msi_msg(struct pci_dev *pdev, struct msi_msg *msg, u8 hpet_id);extern int setup_hpet_msi_remapped (unsigned int irq,unsigned int id);extern void panic_if_irq_remap (const char *msg); +extern bool setup_remapped_irq (int irq, +struct irq_cfg *cfg, +struct irq_chip *chip);static inline bool irq_remapped (struct irq_cfg *cfg) {
@@ -93,6 +96,12 @@ static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) { } +static inline bool setup_remapped_irq (int irq, +struct irq_cfg *cfg, +struct irq_chip *chip) +{ +return false; +}#endif /* CONFIG_IRQ_REMAP */ #endif /* __X86_IRQ_REMAPPING_H */
arch/x86/kernel/apic/io_apic.c +3 -10
@@ -1292,11 +1292,8 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg, fasteoi = false; } -if (irq_remapped (cfg)) { -irq_set_status_flags (irq,IRQ_MOVE_PCNTXT ); -irq_remap_modify_chip_defaults (chip); +if (setup_remapped_irq (irq, cfg, chip)) fasteoi = trigger !=0 ; - } hdl = fasteoi ? handle_fasteoi_irq : handle_edge_irq; irq_set_chip_and_handler_name(irq, chip, hdl,
@@ -3106,10 +3103,7 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)irq_set_msi_desc (irq, msidesc);write_msi_msg (irq, &msg); -if (irq_remapped (irq_get_chip_data (irq))) { -irq_set_status_flags (irq,IRQ_MOVE_PCNTXT ); -irq_remap_modify_chip_defaults (chip); - } +setup_remapped_irq (irq,irq_get_chip_data (irq), chip);irq_set_chip_and_handler_name (irq, chip, handle_edge_irq,"edge" );
@@ -3247,8 +3241,7 @@ int default_setup_hpet_msi(unsigned int irq, unsigned int id)hpet_msi_write (irq_get_handler_data (irq), &msg);irq_set_status_flags (irq,IRQ_MOVE_PCNTXT ); -if (irq_remapped (irq_get_chip_data (irq))) -irq_remap_modify_chip_defaults (chip); +setup_remapped_irq (irq,irq_get_chip_data (irq), chip);irq_set_chip_and_handler_name (irq, chip, handle_edge_irq,"edge" );return 0 ;
drivers/iommu/irq_remapping.c +9 -0
@@ -300,3 +300,12 @@ void irq_remap_modify_chip_defaults(struct irq_chip *chip) chip->irq_eoi = ir_ack_apic_level; chip->irq_set_affinity = x86_io_apic_ops.set_affinity; } + +bool setup_remapped_irq (int irq,struct irq_cfg *cfg,struct irq_chip *chip) +{ +if (!irq_remapped (cfg)) +return false; +irq_set_status_flags (irq,IRQ_MOVE_PCNTXT ); +irq_remap_modify_chip_defaults (chip); +return true; +}
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 17/19 x86, msi: Introduce x86_msi.compose_msi_msg call-back
In reply to Joerg RoedelThis 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.
--- arch/x86/include/asm/io_apic.h | 4 +++ arch/x86/include/asm/x86_init.h | 4 +++ arch/x86/kernel/apic/io_apic.c | 59 ++++++++++++++++++++------------------- arch/x86/kernel/x86_init.c | 1 + drivers/iommu/irq_remapping.c | 9 ++++-- 5 files changed, 46 insertions(+), 31 deletions(-)
arch/x86/include/asm/io_apic.h +4 -0
@@ -158,6 +158,9 @@ extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *, struct io_apic_irq_attr *);extern void eoi_ioapic_irq (unsigned int irq,struct irq_cfg *cfg); +extern void native_compose_msi_msg (struct pci_dev *pdev, +unsigned int irq,unsigned int dest, +struct msi_msg *msg,u8 hpet_id);int io_apic_setup_irq_pin_once (unsigned int irq,int node,struct io_apic_irq_attr *attr);extern int save_ioapic_entries (void );
@@ -242,6 +245,7 @@ static inline void disable_ioapic_support(void) { }#define native_io_apic_print_entries NULL#define native_ioapic_set_affinity NULL#define native_setup_ioapic_entry NULL +#define native_compose_msi_msg NULL#endif #endif /* _ASM_X86_IO_APIC_H */
arch/x86/include/asm/x86_init.h +4 -0
@@ -181,9 +181,13 @@ struct x86_platform_ops { };struct pci_dev ; +struct msi_msg ;struct x86_msi_ops {int (*setup_msi_irqs)(struct pci_dev *dev,int nvec,int type); +void (*compose_msi_msg)(struct pci_dev *dev,unsigned int irq, +unsigned int dest,struct msi_msg *msg, +u8 hpet_id);void (*teardown_msi_irq)(unsigned int irq);void (*teardown_msi_irqs)(struct pci_dev *dev);void (*restore_msi_irqs)(struct pci_dev *dev,int irq);
arch/x86/kernel/apic/io_apic.c +31 -28
76 lines not on this page · raw message
arch/x86/kernel/x86_init.c +1 -0
@@ -113,6 +113,7 @@ struct x86_platform_ops x86_platform = {EXPORT_SYMBOL_GPL (x86_platform);struct x86_msi_ops x86_msi = { .setup_msi_irqs = native_setup_msi_irqs, + .compose_msi_msg = native_compose_msi_msg, .teardown_msi_irq = native_teardown_msi_irq, .teardown_msi_irqs = default_teardown_msi_irqs, .restore_msi_irqs = default_restore_msi_irqs,
drivers/iommu/irq_remapping.c +6 -3
@@ -95,6 +95,7 @@ static void __init irq_remapping_modify_x86_ops(void) x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry; 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; }static __init int setup_nointremap (char *str)
@@ -240,10 +241,12 @@ void compose_remapped_msi_msg(struct pci_dev *pdev, unsigned int irq, unsigned int dest, struct msi_msg *msg, u8 hpet_id) { - if (!remap_ops || !remap_ops->compose_msi_msg) - return; + struct irq_cfg *cfg = irq_get_chip_data(irq); - remap_ops->compose_msi_msg (pdev, irq, dest, msg, hpet_id); +if (!irq_remapped (cfg)) +native_compose_msi_msg (pdev, irq, dest, msg, hpet_id); +else if (remap_ops && remap_ops->compose_msi_msg) + remap_ops->compose_msi_msg (pdev, irq, dest, msg, hpet_id); }static int msi_alloc_remapped_irq (struct pci_dev *pdev,int irq,int nvec)
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 18/19 x86, io_apic: Introduce eoi_ioapic_pin call-back
In reply to Joerg RoedelThis callback replaces the old __eoi_ioapic_pin function which needs a special path for interrupt remapping.
--- arch/x86/include/asm/io_apic.h | 5 +++++ arch/x86/include/asm/x86_init.h | 1 + arch/x86/kernel/apic/io_apic.c | 20 ++++++-------------- arch/x86/kernel/x86_init.c | 1 + drivers/iommu/irq_remapping.c | 12 ++++++++++++ 5 files changed, 25 insertions(+), 14 deletions(-)
arch/x86/include/asm/io_apic.h +5 -0
@@ -161,6 +161,7 @@ extern void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg);extern void native_compose_msi_msg (struct pci_dev *pdev,unsigned int irq,unsigned int dest,struct msi_msg *msg,u8 hpet_id); +extern void native_eoi_ioapic_pin (int apic,int pin,int vector);int io_apic_setup_irq_pin_once (unsigned int irq,int node,struct io_apic_irq_attr *attr);extern int save_ioapic_entries (void );
@@ -211,6 +212,9 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned { x86_io_apic_ops.modify (apic, reg, value); } + +extern void io_apic_eoi (unsigned int apic,unsigned int vector); +#else /* !CONFIG_X86_IO_APIC */ #define io_apic_assign_pci_irqs 0
@@ -246,6 +250,7 @@ static inline void disable_ioapic_support(void) { }#define native_ioapic_set_affinity NULL#define native_setup_ioapic_entry NULL#define native_compose_msi_msg NULL +#define native_eoi_ioapic_pin NULL#endif #endif /* _ASM_X86_IO_APIC_H */
arch/x86/include/asm/x86_init.h +1 -0
@@ -212,6 +212,7 @@ struct x86_io_apic_ops {int (*setup_entry)(int irq,struct IO_APIC_route_entry *entry,unsigned int destination,int vector,struct io_apic_irq_attr *attr); +void (*eoi_ioapic_pin)(int apic,int pin,int vector); };extern struct x86_init_ops x86_init;
arch/x86/kernel/apic/io_apic.c +6 -14
@@ -310,7 +310,7 @@ static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) + (mpc_ioapic_addr (idx) & ~PAGE_MASK ); } -static inline void io_apic_eoi (unsigned int apic,unsigned int vector) +void io_apic_eoi (unsigned int apic,unsigned int vector) {struct io_apic __iomem *io_apic =io_apic_base (apic);writel (vector, &io_apic->eoi);
@@ -557,19 +557,10 @@ static void unmask_ioapic_irq(struct irq_data *data)* Otherwise, we simulate the EOI message manually by changing the trigger * mode to edge and then back to level, with RTE being masked during this. */ -static void __eoi_ioapic_pin (int apic,int pin,int vector,struct irq_cfg *cfg) +void native_eoi_ioapic_pin (int apic,int pin,int vector) {if (mpc_ioapic_ver (apic) >=0x20 ) { -/* -* Intr-remapping uses pin number as the virtual vector -* in the RTE. Actual vector is programmed in -* intr-remapping table entry. Hence for the io-apic -* EOI we use the pin number. -*/ -if (cfg &&irq_remapped (cfg)) -io_apic_eoi (apic, pin); -else -io_apic_eoi (apic, vector); +io_apic_eoi (apic, vector); }else {struct IO_APIC_route_entry entry, entry1;
@@ -597,7 +588,8 @@ void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)raw_spin_lock_irqsave (&ioapic_lock, flags);for_each_irq_pin (entry, cfg->irq_2_pin) -__eoi_ioapic_pin (entry->apic, entry->pin, cfg->vector, cfg); + x86_io_apic_ops.eoi_ioapic_pin (entry->apic, entry->pin, + cfg->vector);raw_spin_unlock_irqrestore (&ioapic_lock, flags); }
@@ -634,7 +626,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) }raw_spin_lock_irqsave (&ioapic_lock, flags); -__eoi_ioapic_pin (apic, pin, entry.vector,NULL ); + x86_io_apic_ops.eoi_ioapic_pin (apic, pin, entry.vector);raw_spin_unlock_irqrestore (&ioapic_lock, flags); }
arch/x86/kernel/x86_init.c +1 -0
@@ -129,4 +129,5 @@ struct x86_io_apic_ops x86_io_apic_ops = { .print_entries = native_io_apic_print_entries, .set_affinity = native_ioapic_set_affinity, .setup_entry = native_setup_ioapic_entry, + .eoi_ioapic_pin = native_eoi_ioapic_pin, };
drivers/iommu/irq_remapping.c +12 -0
@@ -88,11 +88,23 @@ error:return ret; } +void eoi_ioapic_pin_remapped (int apic,int pin,int vector) +{ +/* +* Intr-remapping uses pin number as the virtual vector +* in the RTE. Actual vector is programmed in +* intr-remapping table entry. Hence for the io-apic +* EOI we use the pin number. +*/ +io_apic_eoi (apic, pin); +} +static void __init irq_remapping_modify_x86_ops (void ) { x86_io_apic_ops.disable = irq_remapping_disable_io_apic; 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;
Signature · 1 line
1.7.9.5
Joerg Roedel
maintainerPATCH v4 19/19 x86, irq: Move irq_remapped out of x86 core code
In reply to Joerg RoedelThe irq_remapped function is only used in IOMMU code after the last patch. So move its definition there too.
--- arch/x86/include/asm/irq_remapping.h | 10 ---------- drivers/iommu/irq_remapping.c | 5 +++++ 2 files changed, 5 insertions(+), 10 deletions(-)
arch/x86/include/asm/irq_remapping.h +0 -10
@@ -48,11 +48,6 @@ extern bool setup_remapped_irq(int irq,struct irq_cfg *cfg, struct irq_chip *chip); -static inline bool irq_remapped (struct irq_cfg *cfg) -{ -return (cfg->remapped ==1 ); -} -void irq_remap_modify_chip_defaults (struct irq_chip *chip);#else /* CONFIG_IRQ_REMAP */
@@ -87,11 +82,6 @@ static inline void panic_if_irq_remap(const char *msg) { } -static inline bool irq_remapped (struct irq_cfg *cfg) -{ -return false; -} -static inline void irq_remap_modify_chip_defaults (struct irq_chip *chip) { }
drivers/iommu/irq_remapping.c +5 -0
@@ -31,6 +31,11 @@ static int set_remapped_irq_affinity(struct irq_data *data,const struct cpumask *mask, bool force); +static bool irq_remapped (struct irq_cfg *cfg) +{ +return (cfg->remapped ==1 ); +} +static void irq_remapping_disable_io_apic (void ) {/*
Signature · 1 line
1.7.9.5
Quoted 5 lines · Joerg Roedel
Hi,
here is the fourth version of the patch-set to improve the abstraction of interrupt remapping in the x86 core code. A more detailed description can be found in the original post at:
Are these patches available on some git tree?
Quoted 32 lines
https://lkml.org/lkml/2012/8/7/317Changes from
v3->v4:* Rebased to v3.7-rc6
* Added Acked-bys
* Fixed problems with AMD IRQ remapping code that came up in testingChanges from
v2->v3:* Rebased to v3.6-rc7
* Worked in most comments on v2 by Sebastian Andrzej SiewiorChanges from
v1->v2:* Fixed a couple of compile issues on i386 (reported by Fengguang Wu, thanks a lot)
* Rebased to Linux v3.6-rc2Please review.
Cheers,
Joerg
_______________________________________________
iommu mailing list iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Quoted 8 lines · Joerg Roedel
Hi,
here is the fourth version of the patch-set to improve the abstraction of interrupt remapping in the x86 core code. A more detailed description can be found in the original post at:
https://lkml.org/lkml/2012/8/7/317
I looked at the patches and you can also add
If you have a git tree I would like to test them as well. Thx.
Quoted 29 lines
Changes from
v3->v4:* Rebased to v3.7-rc6
* Added Acked-bys
* Fixed problems with AMD IRQ remapping code that came up in testingChanges from
v2->v3:* Rebased to v3.6-rc7
* Worked in most comments on v2 by Sebastian Andrzej SiewiorChanges from
v1->v2:* Fixed a couple of compile issues on i386 (reported by Fengguang Wu, thanks a lot)
* Rebased to Linux v3.6-rc2Please review.
Cheers,
Joerg
_______________________________________________
iommu mailing list iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Joerg Roedel
maintainerHi Konrad,
Quoted 2 lines · Konrad Rzeszutek Wilk
I looked at the patches and you can also add
Reviewed-by Konrad Rzeszutek Wilk <[email protected]>
Thanks for your review, I added the line to the patches.
Quoted 1 line
If you have a git tree I would like to test them as well. Thx.
I rebased to v3.7-rc7 and pushed it to
git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git ioapic-cleanups
(Just pushed, may take some time to hit the mirrors)
Thanks,
Joerg