From 736baef4472d00574089f295bc759ac002b9558c Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 30 Mar 2012 11:47:00 -0700 Subject: iommu/vt-d: Make intr-remapping initialization generic This patch introduces irq_remap_ops to hold implementation specific function pointer to handle interrupt remapping. As the first part the initialization functions for VT-d are converted to these ops. Signed-off-by: Joerg Roedel Acked-by: Yinghai Lu Cc: David Woodhouse Cc: Alex Williamson Signed-off-by: Suresh Siddha Signed-off-by: Joerg Roedel --- include/linux/dmar.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 731a60975101..6d66c9c76e0a 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -115,9 +115,6 @@ struct irte { }; #ifdef CONFIG_IRQ_REMAP -extern int intr_remapping_enabled; -extern int intr_remapping_supported(void); -extern int enable_intr_remapping(void); extern void disable_intr_remapping(void); extern int reenable_intr_remapping(int); -- cgit v1.2.3 From 4f3d8b67ad3090f9fb72f8235d21cde53cd24b79 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 30 Mar 2012 11:47:01 -0700 Subject: iommu/vt-d: Convert missing apic.c intr-remapping call to remap_ops Convert these calls too: * Disable of remapping hardware * Reenable of remapping hardware * Enable fault handling With that all of arch/x86/kernel/apic/apic.c is converted to use the generic intr-remapping interface. Signed-off-by: Joerg Roedel Acked-by: Yinghai Lu Cc: David Woodhouse Cc: Alex Williamson Signed-off-by: Suresh Siddha Signed-off-by: Joerg Roedel --- arch/x86/include/asm/intr_remapping.h | 6 ++++++ arch/x86/kernel/apic/apic.c | 6 +++--- drivers/iommu/intel_intr_remapping.c | 7 +++++-- drivers/iommu/intr_remapping.c | 24 ++++++++++++++++++++++++ drivers/iommu/intr_remapping.h | 9 +++++++++ include/linux/dmar.h | 18 ------------------ 6 files changed, 47 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/arch/x86/include/asm/intr_remapping.h b/arch/x86/include/asm/intr_remapping.h index 207c605dbdf5..55aa892a53e3 100644 --- a/arch/x86/include/asm/intr_remapping.h +++ b/arch/x86/include/asm/intr_remapping.h @@ -30,6 +30,9 @@ extern void setup_intr_remapping(void); extern int intr_remapping_supported(void); extern int intr_hardware_init(void); extern int intr_hardware_enable(void); +extern void intr_hardware_disable(void); +extern int intr_hardware_reenable(int); +extern int intr_enable_fault_handling(void); #else /* CONFIG_IRQ_REMAP */ @@ -39,6 +42,9 @@ static inline void setup_intr_remapping(void) { } static inline int intr_remapping_supported(void) { return 0; } static inline int intr_hardware_init(void) { return -ENODEV; } static inline int intr_hardware_enable(void) { return -ENODEV; } +static inline void intr_hardware_disable(void) { } +static inline int intr_hardware_reenable(int eim) { return -ENODEV; } +static inline int intr_enable_fault_handling(void) { return -ENODEV; } #endif /* CONFIG_IRQ_REMAP */ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 1db6f63a22ff..a2762687e2ee 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1443,7 +1443,7 @@ void __init bsp_end_local_APIC_setup(void) * handling for interrupt remapping. */ if (intr_remapping_enabled) - enable_drhd_fault_handling(); + intr_enable_fault_handling(); } @@ -2181,7 +2181,7 @@ static int lapic_suspend(void) disable_local_APIC(); if (intr_remapping_enabled) - disable_intr_remapping(); + intr_hardware_disable(); local_irq_restore(flags); return 0; @@ -2250,7 +2250,7 @@ static void lapic_resume(void) apic_read(APIC_ESR); if (intr_remapping_enabled) - reenable_intr_remapping(x2apic_mode); + intr_hardware_reenable(x2apic_mode); local_irq_restore(flags); } diff --git a/drivers/iommu/intel_intr_remapping.c b/drivers/iommu/intel_intr_remapping.c index 9c742fb111b6..610b75b66c07 100644 --- a/drivers/iommu/intel_intr_remapping.c +++ b/drivers/iommu/intel_intr_remapping.c @@ -764,7 +764,7 @@ int __init ir_dev_scope_init(void) } rootfs_initcall(ir_dev_scope_init); -void disable_intr_remapping(void) +static void disable_intr_remapping(void) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu = NULL; @@ -780,7 +780,7 @@ void disable_intr_remapping(void) } } -int reenable_intr_remapping(int eim) +static int reenable_intr_remapping(int eim) { struct dmar_drhd_unit *drhd; int setup = 0; @@ -818,4 +818,7 @@ struct irq_remap_ops intel_irq_remap_ops = { .supported = intel_intr_remapping_supported, .hardware_init = dmar_table_init, .hardware_enable = intel_enable_intr_remapping, + .hardware_disable = disable_intr_remapping, + .hardware_reenable = reenable_intr_remapping, + .enable_faulting = enable_drhd_fault_handling, }; diff --git a/drivers/iommu/intr_remapping.c b/drivers/iommu/intr_remapping.c index 670c69a80afd..9aabed7c0320 100644 --- a/drivers/iommu/intr_remapping.c +++ b/drivers/iommu/intr_remapping.c @@ -74,3 +74,27 @@ int __init intr_hardware_enable(void) return remap_ops->hardware_enable(); } + +void intr_hardware_disable(void) +{ + if (!remap_ops || !remap_ops->hardware_disable) + return; + + remap_ops->hardware_disable(); +} + +int intr_hardware_reenable(int mode) +{ + if (!remap_ops || !remap_ops->hardware_reenable) + return 0; + + return remap_ops->hardware_reenable(mode); +} + +int __init intr_enable_fault_handling(void) +{ + if (!remap_ops || !remap_ops->enable_faulting) + return -ENODEV; + + return remap_ops->enable_faulting(); +} diff --git a/drivers/iommu/intr_remapping.h b/drivers/iommu/intr_remapping.h index d6df732e001f..2744c9ae4aec 100644 --- a/drivers/iommu/intr_remapping.h +++ b/drivers/iommu/intr_remapping.h @@ -37,6 +37,15 @@ struct irq_remap_ops { /* Enables the remapping hardware */ int (*hardware_enable)(void); + + /* Disables the remapping hardware */ + void (*hardware_disable)(void); + + /* Reenables the remapping hardware */ + int (*hardware_reenable)(int); + + /* Enable fault handling */ + int (*enable_faulting)(void); }; extern struct irq_remap_ops intel_irq_remap_ops; diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 6d66c9c76e0a..f2bd87f52a8d 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -115,9 +115,6 @@ struct irte { }; #ifdef CONFIG_IRQ_REMAP -extern void disable_intr_remapping(void); -extern int reenable_intr_remapping(int); - extern int get_irte(int irq, struct irte *entry); extern int modify_irte(int irq, struct irte *irte_modified); extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count); @@ -179,21 +176,6 @@ static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev) return 0; } -#define intr_remapping_enabled (0) - -static inline int enable_intr_remapping(void) -{ - return -1; -} - -static inline void disable_intr_remapping(void) -{ -} - -static inline int reenable_intr_remapping(int eim) -{ - return 0; -} #endif enum { -- cgit v1.2.3 From 9d619f65722236e0e0c35467d1528caed206e439 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 30 Mar 2012 11:47:04 -0700 Subject: iommu/vt-d: Convert free_irte into a remap_ops callback The operation for releasing a remapping entry is iommu specific too. Signed-off-by: Joerg Roedel Acked-by: Yinghai Lu Cc: David Woodhouse Cc: Alex Williamson Signed-off-by: Suresh Siddha Signed-off-by: Joerg Roedel --- arch/x86/include/asm/intr_remapping.h | 2 ++ arch/x86/kernel/apic/io_apic.c | 2 +- drivers/iommu/intel_intr_remapping.c | 3 ++- drivers/iommu/intr_remapping.c | 8 ++++++++ drivers/iommu/intr_remapping.h | 3 +++ include/linux/dmar.h | 5 ----- 6 files changed, 16 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/arch/x86/include/asm/intr_remapping.h b/arch/x86/include/asm/intr_remapping.h index ae933ecfd8f0..a195b7d6995c 100644 --- a/arch/x86/include/asm/intr_remapping.h +++ b/arch/x86/include/asm/intr_remapping.h @@ -43,6 +43,7 @@ extern int intr_setup_ioapic_entry(int irq, extern int intr_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force); +extern void intr_free_irq(int irq); #else /* CONFIG_IRQ_REMAP */ @@ -68,6 +69,7 @@ static inline int intr_set_affinity(struct irq_data *data, { return 0; } +static inline void intr_free_irq(int irq) { } #endif /* CONFIG_IRQ_REMAP */ #endif /* __X86_INTR_REMAPPING_H */ diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index a97c79aa25cf..5690469555fb 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -3041,7 +3041,7 @@ void destroy_irq(unsigned int irq) irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE); if (irq_remapped(cfg)) - free_irte(irq); + intr_free_irq(irq); raw_spin_lock_irqsave(&vector_lock, flags); __clear_irq_vector(irq, cfg); raw_spin_unlock_irqrestore(&vector_lock, flags); diff --git a/drivers/iommu/intel_intr_remapping.c b/drivers/iommu/intel_intr_remapping.c index 25372c1f3c8c..44a6e04a070b 100644 --- a/drivers/iommu/intel_intr_remapping.c +++ b/drivers/iommu/intel_intr_remapping.c @@ -253,7 +253,7 @@ static int clear_entries(struct irq_2_iommu *irq_iommu) return qi_flush_iec(iommu, index, irq_iommu->irte_mask); } -int free_irte(int irq) +static int free_irte(int irq) { struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); unsigned long flags; @@ -964,4 +964,5 @@ struct irq_remap_ops intel_irq_remap_ops = { .enable_faulting = enable_drhd_fault_handling, .setup_ioapic_entry = intel_setup_ioapic_entry, .set_affinity = intel_ioapic_set_affinity, + .free_irq = free_irte, }; diff --git a/drivers/iommu/intr_remapping.c b/drivers/iommu/intr_remapping.c index 2f4f27ffb861..a68d304f9729 100644 --- a/drivers/iommu/intr_remapping.c +++ b/drivers/iommu/intr_remapping.c @@ -119,3 +119,11 @@ int intr_set_affinity(struct irq_data *data, const struct cpumask *mask, return remap_ops->set_affinity(data, mask, force); } + +void intr_free_irq(int irq) +{ + if (!remap_ops || !remap_ops->free_irq) + return; + + remap_ops->free_irq(irq); +} diff --git a/drivers/iommu/intr_remapping.h b/drivers/iommu/intr_remapping.h index e0bc6e0ba1fb..57485539383d 100644 --- a/drivers/iommu/intr_remapping.h +++ b/drivers/iommu/intr_remapping.h @@ -60,6 +60,9 @@ struct irq_remap_ops { /* Set the CPU affinity of a remapped interrupt */ int (*set_affinity)(struct irq_data *data, const struct cpumask *mask, bool force); + + /* Free an IRQ */ + int (*free_irq)(int); }; extern struct irq_remap_ops intel_irq_remap_ops; diff --git a/include/linux/dmar.h b/include/linux/dmar.h index f2bd87f52a8d..7a207a39f879 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -121,7 +121,6 @@ extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count); extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 sub_handle); extern int map_irq_to_irte_handle(int irq, u16 *sub_handle); -extern int free_irte(int irq); extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev); extern struct intel_iommu *map_ioapic_to_ir(int apic); @@ -138,10 +137,6 @@ static inline int modify_irte(int irq, struct irte *irte_modified) { return -1; } -static inline int free_irte(int irq) -{ - return -1; -} static inline int map_irq_to_irte_handle(int irq, u16 *sub_handle) { return -1; -- cgit v1.2.3 From 263b5e8629c9ce21c9cd4c0e29c097afb1c10ef3 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 30 Mar 2012 11:47:06 -0700 Subject: x86, iommu/vt-d: Clean up interfaces for interrupt remapping Remove the Intel specific interfaces from dmar.h and remove asm/irq_remapping.h which is only used for io_apic.c anyway. Signed-off-by: Joerg Roedel Acked-by: Yinghai Lu Cc: David Woodhouse Cc: Alex Williamson Signed-off-by: Suresh Siddha Signed-off-by: Joerg Roedel --- arch/x86/include/asm/irq_remapping.h | 22 -------------- arch/x86/kernel/apic/io_apic.c | 17 ++++++++++- drivers/iommu/intel_intr_remapping.c | 20 ++++++------ include/linux/dmar.h | 59 ------------------------------------ 4 files changed, 26 insertions(+), 92 deletions(-) delete mode 100644 arch/x86/include/asm/irq_remapping.h (limited to 'include') diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h deleted file mode 100644 index 0ddfc0b90adb..000000000000 --- a/arch/x86/include/asm/irq_remapping.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _ASM_X86_IRQ_REMAPPING_H -#define _ASM_X86_IRQ_REMAPPING_H - -#define IRTE_DEST(dest) ((x2apic_mode) ? dest : dest << 8) - -#ifdef CONFIG_IRQ_REMAP -static void irq_remap_modify_chip_defaults(struct irq_chip *chip); -static inline bool irq_remapped(struct irq_cfg *cfg) -{ - return cfg->irq_2_iommu.iommu != NULL; -} -#else -static inline bool irq_remapped(struct irq_cfg *cfg) -{ - return false; -} -static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) -{ -} -#endif - -#endif /* _ASM_X86_IRQ_REMAPPING_H */ diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 3db693bda91d..073edd1d3c66 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include @@ -87,6 +86,22 @@ void __init set_io_apic_ops(const struct io_apic_ops *ops) io_apic_ops = *ops; } +#ifdef CONFIG_IRQ_REMAP +static void irq_remap_modify_chip_defaults(struct irq_chip *chip); +static inline bool irq_remapped(struct irq_cfg *cfg) +{ + return cfg->irq_2_iommu.iommu != NULL; +} +#else +static inline bool irq_remapped(struct irq_cfg *cfg) +{ + return false; +} +static inline void irq_remap_modify_chip_defaults(struct irq_chip *chip) +{ +} +#endif + /* * Is the SiS APIC rmw bug present ? * -1 = don't know, 0 = no, 1 = yes diff --git a/drivers/iommu/intel_intr_remapping.c b/drivers/iommu/intel_intr_remapping.c index a3bae67ec43c..7472634df350 100644 --- a/drivers/iommu/intel_intr_remapping.c +++ b/drivers/iommu/intel_intr_remapping.c @@ -64,7 +64,7 @@ int get_irte(int irq, struct irte *entry) return 0; } -int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) +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); @@ -136,7 +136,7 @@ static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask) return qi_submit_sync(&desc, iommu); } -int map_irq_to_irte_handle(int irq, u16 *sub_handle) +static int map_irq_to_irte_handle(int irq, u16 *sub_handle) { struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); unsigned long flags; @@ -152,7 +152,7 @@ int map_irq_to_irte_handle(int irq, u16 *sub_handle) return index; } -int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) +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); unsigned long flags; @@ -172,7 +172,7 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) return 0; } -int modify_irte(int irq, struct irte *irte_modified) +static int modify_irte(int irq, struct irte *irte_modified) { struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); struct intel_iommu *iommu; @@ -200,7 +200,7 @@ int modify_irte(int irq, struct irte *irte_modified) return rc; } -struct intel_iommu *map_hpet_to_ir(u8 hpet_id) +static struct intel_iommu *map_hpet_to_ir(u8 hpet_id) { int i; @@ -210,7 +210,7 @@ struct intel_iommu *map_hpet_to_ir(u8 hpet_id) return NULL; } -struct intel_iommu *map_ioapic_to_ir(int apic) +static struct intel_iommu *map_ioapic_to_ir(int apic) { int i; @@ -220,7 +220,7 @@ struct intel_iommu *map_ioapic_to_ir(int apic) return NULL; } -struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) +static struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) { struct dmar_drhd_unit *drhd; @@ -312,7 +312,7 @@ static void set_irte_sid(struct irte *irte, unsigned int svt, irte->sid = sid; } -int set_ioapic_sid(struct irte *irte, int apic) +static int set_ioapic_sid(struct irte *irte, int apic) { int i; u16 sid = 0; @@ -337,7 +337,7 @@ int set_ioapic_sid(struct irte *irte, int apic) return 0; } -int set_hpet_sid(struct irte *irte, u8 id) +static int set_hpet_sid(struct irte *irte, u8 id) { int i; u16 sid = 0; @@ -367,7 +367,7 @@ int set_hpet_sid(struct irte *irte, u8 id) return 0; } -int set_msi_sid(struct irte *irte, struct pci_dev *dev) +static int set_msi_sid(struct irte *irte, struct pci_dev *dev) { struct pci_dev *bridge; diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 7a207a39f879..b029d1aa2d12 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -114,65 +114,6 @@ struct irte { }; }; -#ifdef CONFIG_IRQ_REMAP -extern int get_irte(int irq, struct irte *entry); -extern int modify_irte(int irq, struct irte *irte_modified); -extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count); -extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, - u16 sub_handle); -extern int map_irq_to_irte_handle(int irq, u16 *sub_handle); - -extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev); -extern struct intel_iommu *map_ioapic_to_ir(int apic); -extern struct intel_iommu *map_hpet_to_ir(u8 id); -extern int set_ioapic_sid(struct irte *irte, int apic); -extern int set_hpet_sid(struct irte *irte, u8 id); -extern int set_msi_sid(struct irte *irte, struct pci_dev *dev); -#else -static inline int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) -{ - return -1; -} -static inline int modify_irte(int irq, struct irte *irte_modified) -{ - return -1; -} -static inline int map_irq_to_irte_handle(int irq, u16 *sub_handle) -{ - return -1; -} -static inline int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, - u16 sub_handle) -{ - return -1; -} -static inline struct intel_iommu *map_dev_to_ir(struct pci_dev *dev) -{ - return NULL; -} -static inline struct intel_iommu *map_ioapic_to_ir(int apic) -{ - return NULL; -} -static inline struct intel_iommu *map_hpet_to_ir(unsigned int hpet_id) -{ - return NULL; -} -static inline int set_ioapic_sid(struct irte *irte, int apic) -{ - return 0; -} -static inline int set_hpet_sid(struct irte *irte, u8 id) -{ - return -1; -} -static inline int set_msi_sid(struct irte *irte, struct pci_dev *dev) -{ - return 0; -} - -#endif - enum { IRQ_REMAP_XAPIC_MODE, IRQ_REMAP_X2APIC_MODE, -- cgit v1.2.3