RE: [PATCHv7 9/9] ARM: dma-mapping: add support for IOMMU mapper

2012-03-30 Thread Marek Szyprowski
Hello,

On Friday, March 30, 2012 4:24 AM Krishna Reddy wrote:

 Hi,
 I have found a bug in arm_iommu_map_sg().
 
  +int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
  +enum dma_data_direction dir, struct dma_attrs *attrs) {
  +   struct scatterlist *s = sg, *dma = sg, *start = sg;
  +   int i, count = 0;
  +   unsigned int offset = s-offset;
  +   unsigned int size = s-offset + s-length;
  +   unsigned int max = dma_get_max_seg_size(dev);
  +
  +   for (i = 1; i  nents; i++) {
  +   s-dma_address = ARM_DMA_ERROR;
  +   s-dma_length = 0;
  +
  +   s = sg_next(s);
 
 With above code, the last sg element's dma_length is not getting set to zero.
 This causing additional incorrect  unmapping during arm_iommu_unmap_sg call 
 and
 leading to random crashes.
 The order of above three lines should be as follows.
   s = sg_next(s);
 
   s-dma_address = ARM_DMA_ERROR;
   s-dma_length = 0;
 

You are right, the order of those lines must be reversed. In all my test codes 
the 
scatter list was initially cleared, so I missed this typical off-by-one error. 
Thanks for spotting it!

Best regards
-- 
Marek Szyprowski
Samsung Poland RD Center


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCHv7 9/9] ARM: dma-mapping: add support for IOMMU mapper

2012-03-30 Thread Subash Patel

Hi KyongHo,

On 03/22/2012 07:29 PM, Subash Patel wrote:

Hi KyongHo,

On 03/21/2012 05:26 AM, KyongHo Cho wrote:

On Tue, Mar 20, 2012 at 10:50 PM, Subash Patelsubas...@gmail.com wrote:

Sorry for digging this very late. But as part of integrating dma_map v7
sysmmu v12 on 3.3-rc5, I am facing below issue:

a) By un-selecting IOMMU in menu config, I am able to allocate memory in
vb2-dma-contig

b) When I enable SYSMMU support for the IP's, I am receiving below
fault:

Unhandled fault: external abort on non-linefetch (0x818) at 0xb6f55000

I think this has something to do with the access to the SYSMMU
registers for
writing the page table. Has anyone of you faced this issue while testing
these(dma_map+iommu) patches on kernel mentioned above? This must be
something related to recent changes, as I didn't have issues with these
patches on 3.2 kernel.



0xb6f55000 is not an address of SYSMMU register if your kernel starts
at 0xc000.

Can you tell me any detailed information or situation?

I hate to say this, but I am not able to catch the fault location even
with JTAG. Once the fault comes, the debugger looses all control over. I
think now possible method is reproduction at your end :)


Thanks to you, Issue is now figured out. This was due to generic Power 
Domain code added recently. SYSMMU registers were not getting enabled 
due to this. I reverted the PD changes from the machine to architecture 
specific, and voila, SYSMMU is back into action using the 
dma-mapping-v7. I will have to see how the same would behave when the 
complete PD changes comes to mainline from maintainers for-next in future.




Regards,

KyongHo.

Regards,
Subash

Regards,
Subash
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] iommu: OMAP: device detach on domain destroy

2012-03-30 Thread Omar Ramirez Luna
'domain_destroy with devices attached' case isn't yet handled, instead
code assumes that the device was already detached.

If the domain is destroyed the hardware still has access to invalid
pointers to its page table and internal iommu object. In order to
detach the users we need to track devices using the iommu, current
use cases only have one user of iommu per instance. When required
this can evolve to a list with the devices using the iommu_dev.

Reported-by: Joerg Roedel j...@8bytes.org
Reviewed-by: Ohad Ben-Cohen o...@wizery.com
Signed-off-by: Omar Ramirez Luna omar.l...@linaro.org
---
 drivers/iommu/omap-iommu.c |   32 +++-
 1 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 821062a..e32bd15 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -41,11 +41,13 @@
  * @pgtable:   the page table
  * @iommu_dev: an omap iommu device attached to this domain. only a single
  * iommu device can be attached for now.
+ * @dev:   Device using this domain.
  * @lock:  domain lock, should be taken when attaching/detaching
  */
 struct omap_iommu_domain {
u32 *pgtable;
struct omap_iommu *iommu_dev;
+   struct device *dev;
spinlock_t lock;
 };
 
@@ -1074,6 +1076,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct 
device *dev)
}
 
omap_domain-iommu_dev = arch_data-iommu_dev = oiommu;
+   omap_domain-dev = dev;
oiommu-domain = domain;
 
/* temporary workaround */
@@ -1084,19 +1087,16 @@ out:
return ret;
 }
 
-static void omap_iommu_detach_dev(struct iommu_domain *domain,
-struct device *dev)
+static void _omap_iommu_detach_dev(struct omap_iommu_domain *omap_domain,
+   struct device *dev)
 {
-   struct omap_iommu_domain *omap_domain = domain-priv;
-   struct omap_iommu_arch_data *arch_data = dev-archdata.iommu;
struct omap_iommu *oiommu = dev_to_omap_iommu(dev);
-
-   spin_lock(omap_domain-lock);
+   struct omap_iommu_arch_data *arch_data = dev-archdata.iommu;
 
/* only a single device is supported per domain for now */
if (omap_domain-iommu_dev != oiommu) {
dev_err(dev, invalid iommu device\n);
-   goto out;
+   return;
}
 
iopgtable_clear_entry_all(oiommu);
@@ -1104,11 +1104,19 @@ static void omap_iommu_detach_dev(struct iommu_domain 
*domain,
omap_iommu_detach(oiommu);
 
omap_domain-iommu_dev = arch_data-iommu_dev = NULL;
+   omap_domain-dev = NULL;
 
/* temporary workaround */
clk_disable(oiommu-clk);
+}
 
-out:
+static void omap_iommu_detach_dev(struct iommu_domain *domain,
+struct device *dev)
+{
+   struct omap_iommu_domain *omap_domain = domain-priv;
+
+   spin_lock(omap_domain-lock);
+   _omap_iommu_detach_dev(omap_domain, dev);
spin_unlock(omap_domain-lock);
 }
 
@@ -1147,13 +1155,19 @@ out:
return -ENOMEM;
 }
 
-/* assume device was already detached */
 static void omap_iommu_domain_destroy(struct iommu_domain *domain)
 {
struct omap_iommu_domain *omap_domain = domain-priv;
 
domain-priv = NULL;
 
+   /*
+* An iommu device is still attached
+* (currently, only one device can be attached) ?
+*/
+   if (omap_domain-iommu_dev)
+   _omap_iommu_detach_dev(omap_domain, omap_domain-dev);
+
kfree(omap_domain-pgtable);
kfree(omap_domain);
 }
-- 
1.7.4.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 00/10] vt-d irq_remap_ops patchset

2012-03-30 Thread Suresh Siddha
Ingo,

Here is the Joerg's irq_remap_ops patchset updated for the latest -tip.
Simplified some of the naming conventions to follow the irq_remapping
terminology. There are still some if (irq_remapping_enabled) checks in
io_apic.c that I would like to roll into the new io_apic_ops. I will
look into that shortly.

Joerg Roedel (8):
  iommu: Rename intr_remapping files to intel_intr_remapping
  iommu/vt-d: Make intr-remapping initialization generic
  iommu/vt-d: Convert missing apic.c intr-remapping call to remap_ops
  iommu/vt-d: Convert IR ioapic-setup to use remap_ops
  iommu/vt-d: Convert IR set_affinity function to remap_ops
  iommu/vt-d: Convert free_irte into a remap_ops callback
  iommu/vt-d: Convert MSI remapping setup to remap_ops
  x86, iommu/vt-d: Clean up interfaces for interrupt remapping

Suresh Siddha (2):
  iommu: rename intr_remapping references to irq_remapping
  iommu: rename intr_remapping.[ch] to irq_remapping.[ch]

 arch/ia64/include/asm/irq_remapping.h  |4 +
 arch/x86/include/asm/irq_remapping.h   |  120 +--
 arch/x86/kernel/apic/apic.c|   30 +-
 arch/x86/kernel/apic/io_apic.c |  297 -
 drivers/iommu/Makefile |2 +-
 drivers/iommu/dmar.c   |9 +-
 drivers/iommu/intel-iommu.c|3 +-
 .../{intr_remapping.c = intel_irq_remapping.c}|  355 
 drivers/iommu/intr_remapping.h |   17 -
 drivers/iommu/irq_remapping.c  |  164 +
 drivers/iommu/irq_remapping.h  |   88 +
 include/linux/dmar.h   |   85 -
 12 files changed, 724 insertions(+), 450 deletions(-)
 create mode 100644 arch/ia64/include/asm/irq_remapping.h
 rename drivers/iommu/{intr_remapping.c = intel_irq_remapping.c} (66%)
 delete mode 100644 drivers/iommu/intr_remapping.h
 create mode 100644 drivers/iommu/irq_remapping.c
 create mode 100644 drivers/iommu/irq_remapping.h

-- 
1.7.6.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 01/10] iommu: Rename intr_remapping files to intel_intr_remapping

2012-03-30 Thread Suresh Siddha
From: Joerg Roedel joerg.roe...@amd.com

The files contain code mostly relevant for the Intel
implementation of interrupt remapping. Make that visible in
the file names. Also inline intr_remapping.h into
intr_remapping.c because it is only included there and the
content is very small. So there is no reason for a seperate
header file.

Signed-off-by: Joerg Roedel joerg.roe...@amd.com
Acked-by: Yinghai Lu ying...@kernel.org
Cc: David Woodhouse dw...@infradead.org
Cc: Alex Williamson alex.william...@redhat.com
Signed-off-by: Suresh Siddha suresh.b.sid...@intel.com
---
 drivers/iommu/Makefile |2 +-
 .../{intr_remapping.c = intel_intr_remapping.c}   |   17 -
 drivers/iommu/intr_remapping.h |   17 -
 3 files changed, 17 insertions(+), 19 deletions(-)
 rename drivers/iommu/{intr_remapping.c = intel_intr_remapping.c} (98%)
 delete mode 100644 drivers/iommu/intr_remapping.h

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 7ad7a3b..1533ebf 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -4,7 +4,7 @@ obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o
-obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o
+obj-$(CONFIG_IRQ_REMAP) += intel_intr_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
diff --git a/drivers/iommu/intr_remapping.c 
b/drivers/iommu/intel_intr_remapping.c
similarity index 98%
rename from drivers/iommu/intr_remapping.c
rename to drivers/iommu/intel_intr_remapping.c
index 6777ca0..212fff0 100644
--- a/drivers/iommu/intr_remapping.c
+++ b/drivers/iommu/intel_intr_remapping.c
@@ -10,10 +10,25 @@
 #include asm/smp.h
 #include asm/cpu.h
 #include linux/intel-iommu.h
-#include intr_remapping.h
 #include acpi/acpi.h
 #include asm/pci-direct.h
 
+struct ioapic_scope {
+   struct intel_iommu *iommu;
+   unsigned int id;
+   unsigned int bus;   /* PCI bus number */
+   unsigned int devfn; /* PCI devfn number */
+};
+
+struct hpet_scope {
+   struct intel_iommu *iommu;
+   u8 id;
+   unsigned int bus;
+   unsigned int devfn;
+};
+
+#define IR_X2APIC_MODE(mode) (mode ? (1  11) : 0)
+
 static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
 static struct hpet_scope ir_hpet[MAX_HPET_TBS];
 static int ir_ioapic_num, ir_hpet_num;
diff --git a/drivers/iommu/intr_remapping.h b/drivers/iommu/intr_remapping.h
deleted file mode 100644
index 5662fec..000
--- a/drivers/iommu/intr_remapping.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#include linux/intel-iommu.h
-
-struct ioapic_scope {
-   struct intel_iommu *iommu;
-   unsigned int id;
-   unsigned int bus;   /* PCI bus number */
-   unsigned int devfn; /* PCI devfn number */
-};
-
-struct hpet_scope {
-   struct intel_iommu *iommu;
-   u8 id;
-   unsigned int bus;
-   unsigned int devfn;
-};
-
-#define IR_X2APIC_MODE(mode) (mode ? (1  11) : 0)
-- 
1.7.6.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 02/10] iommu/vt-d: Make intr-remapping initialization generic

2012-03-30 Thread Suresh Siddha
From: Joerg Roedel joerg.roe...@amd.com

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 joerg.roe...@amd.com
Acked-by: Yinghai Lu ying...@kernel.org
Cc: David Woodhouse dw...@infradead.org
Cc: Alex Williamson alex.william...@redhat.com
Signed-off-by: Suresh Siddha suresh.b.sid...@intel.com
---
 arch/ia64/include/asm/intr_remapping.h |4 ++
 arch/x86/include/asm/intr_remapping.h  |   45 +++
 arch/x86/kernel/apic/apic.c|   14 --
 arch/x86/kernel/apic/io_apic.c |1 +
 drivers/iommu/Makefile |2 +-
 drivers/iommu/dmar.c   |1 +
 drivers/iommu/intel-iommu.c|1 +
 drivers/iommu/intel_intr_remapping.c   |   52 +-
 drivers/iommu/intr_remapping.c |   76 
 drivers/iommu/intr_remapping.h |   46 +++
 include/linux/dmar.h   |3 -
 11 files changed, 196 insertions(+), 49 deletions(-)
 create mode 100644 arch/ia64/include/asm/intr_remapping.h
 create mode 100644 arch/x86/include/asm/intr_remapping.h
 create mode 100644 drivers/iommu/intr_remapping.c
 create mode 100644 drivers/iommu/intr_remapping.h

diff --git a/arch/ia64/include/asm/intr_remapping.h 
b/arch/ia64/include/asm/intr_remapping.h
new file mode 100644
index 000..095aa0d
--- /dev/null
+++ b/arch/ia64/include/asm/intr_remapping.h
@@ -0,0 +1,4 @@
+#ifndef __IA64_INTR_REMAPPING_H
+#define __IA64_INTR_REMAPPING_H
+#define intr_remapping_enabled 0
+#endif
diff --git a/arch/x86/include/asm/intr_remapping.h 
b/arch/x86/include/asm/intr_remapping.h
new file mode 100644
index 000..207c605
--- /dev/null
+++ b/arch/x86/include/asm/intr_remapping.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ * Author: Joerg Roedel joerg.roe...@amd.com
+ *
+ * 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 published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * This header file contains the interface of the interrupt remapping code to
+ * the x86 interrupt management code.
+ */
+
+#ifndef __X86_INTR_REMAPPING_H
+#define __X86_INTR_REMAPPING_H
+
+#ifdef CONFIG_IRQ_REMAP
+
+extern int intr_remapping_enabled;
+
+extern void setup_intr_remapping(void);
+extern int intr_remapping_supported(void);
+extern int intr_hardware_init(void);
+extern int intr_hardware_enable(void);
+
+#else  /* CONFIG_IRQ_REMAP */
+
+#define intr_remapping_enabled 0
+
+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; }
+
+#endif /* CONFIG_IRQ_REMAP */
+
+#endif /* __X86_INTR_REMAPPING_H */
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 11544d8..7fbeaa7 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -35,6 +35,7 @@
 #include linux/smp.h
 #include linux/mm.h
 
+#include asm/intr_remapping.h
 #include asm/perf_event.h
 #include asm/x86_init.h
 #include asm/pgalloc.h
@@ -1528,7 +1529,7 @@ int __init enable_IR(void)
return -1;
}
 
-   return enable_intr_remapping();
+   return intr_hardware_enable();
 #endif
return -1;
 }
@@ -1537,10 +1538,13 @@ void __init enable_IR_x2apic(void)
 {
unsigned long flags;
int ret, x2apic_enabled = 0;
-   int dmar_table_init_ret;
+   int hardware_init_ret;
 
-   dmar_table_init_ret = dmar_table_init();
-   if (dmar_table_init_ret  !x2apic_supported())
+   /* Make sure irq_remap_ops are initialized */
+   setup_intr_remapping();
+
+   hardware_init_ret = intr_hardware_init();
+   if (hardware_init_ret  !x2apic_supported())
return;
 
ret = save_ioapic_entries();
@@ -1556,7 +1560,7 @@ void __init enable_IR_x2apic(void)
if (x2apic_preenabled  nox2apic)
disable_x2apic();
 
-   if (dmar_table_init_ret)
+   if (hardware_init_ret)
ret = -1;
else
ret = enable_IR();
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e88300d..1151fdc 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ 

[PATCH 03/10] iommu/vt-d: Convert missing apic.c intr-remapping call to remap_ops

2012-03-30 Thread Suresh Siddha
From: Joerg Roedel joerg.roe...@amd.com

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 joerg.roe...@amd.com
Acked-by: Yinghai Lu ying...@kernel.org
Cc: David Woodhouse dw...@infradead.org
Cc: Alex Williamson alex.william...@redhat.com
Signed-off-by: Suresh Siddha suresh.b.sid...@intel.com
---
 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(-)

diff --git a/arch/x86/include/asm/intr_remapping.h 
b/arch/x86/include/asm/intr_remapping.h
index 207c605..55aa892 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 7fbeaa7..846f3b6 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();
 
 }
 
@@ -2177,7 +2177,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;
@@ -2244,7 +2244,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 9c742fb..610b75b 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 670c69a..9aabed7 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 d6df732..2744c9a 100644
--- a/drivers/iommu/intr_remapping.h
+++ 

[PATCH 05/10] iommu/vt-d: Convert IR set_affinity function to remap_ops

2012-03-30 Thread Suresh Siddha
From: Joerg Roedel joerg.roe...@amd.com

The function to set interrupt affinity with interrupt
remapping enabled is Intel specific too. So move it to the
irq_remap_ops too.

Signed-off-by: Joerg Roedel joerg.roe...@amd.com
Acked-by: Yinghai Lu ying...@kernel.org
Cc: David Woodhouse dw...@infradead.org
Cc: Alex Williamson alex.william...@redhat.com
Signed-off-by: Suresh Siddha suresh.b.sid...@intel.com
---
 arch/x86/include/asm/intr_remapping.h |9 
 arch/x86/kernel/apic/io_apic.c|   69 +
 drivers/iommu/intel_intr_remapping.c  |   54 +
 drivers/iommu/intr_remapping.c|9 
 drivers/iommu/intr_remapping.h|6 +++
 5 files changed, 80 insertions(+), 67 deletions(-)

diff --git a/arch/x86/include/asm/intr_remapping.h 
b/arch/x86/include/asm/intr_remapping.h
index a22e1f1..ae933ec 100644
--- a/arch/x86/include/asm/intr_remapping.h
+++ b/arch/x86/include/asm/intr_remapping.h
@@ -40,6 +40,9 @@ extern int intr_setup_ioapic_entry(int irq,
   struct IO_APIC_route_entry *entry,
   unsigned int destination, int vector,
   struct io_apic_irq_attr *attr);
+extern int intr_set_affinity(struct irq_data *data,
+const struct cpumask *mask,
+bool force);
 
 #else  /* CONFIG_IRQ_REMAP */
 
@@ -59,6 +62,12 @@ static inline int intr_setup_ioapic_entry(int irq,
 {
return -ENODEV;
 }
+static inline int intr_set_affinity(struct irq_data *data,
+   const struct cpumask *mask,
+   bool force)
+{
+   return 0;
+}
 #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 e1ab625..a97c79a 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2327,71 +2327,6 @@ ioapic_set_affinity(struct irq_data *data, const struct 
cpumask *mask,
return ret;
 }
 
-#ifdef CONFIG_IRQ_REMAP
-
-/*
- * Migrate the IO-APIC irq in the presence of intr-remapping.
- *
- * For both level and edge triggered, irq migration is a simple atomic
- * update(of vector and cpu destination) of IRTE and flush the hardware cache.
- *
- * For level triggered, we eliminate the io-apic RTE modification (with the
- * updated vector information), by using a virtual vector (io-apic pin number).
- * Real vector that is used for interrupting cpu will be coming from
- * the interrupt-remapping table entry.
- *
- * As the migration is a simple atomic update of IRTE, the same mechanism
- * is used to migrate MSI irq's in the presence of interrupt-remapping.
- */
-static int
-ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
-  bool force)
-{
-   struct irq_cfg *cfg = data-chip_data;
-   unsigned int dest, irq = data-irq;
-   struct irte irte;
-
-   if (!cpumask_intersects(mask, cpu_online_mask))
-   return -EINVAL;
-
-   if (get_irte(irq, irte))
-   return -EBUSY;
-
-   if (assign_irq_vector(irq, cfg, mask))
-   return -EBUSY;
-
-   dest = apic-cpu_mask_to_apicid_and(cfg-domain, mask);
-
-   irte.vector = cfg-vector;
-   irte.dest_id = IRTE_DEST(dest);
-
-   /*
-* Atomically updates the IRTE with the new destination, vector
-* and flushes the interrupt entry cache.
-*/
-   modify_irte(irq, irte);
-
-   /*
-* After this point, all the interrupts will start arriving
-* at the new destination. So, time to cleanup the previous
-* vector allocation.
-*/
-   if (cfg-move_in_progress)
-   send_cleanup_vector(cfg);
-
-   cpumask_copy(data-affinity, mask);
-   return 0;
-}
-
-#else
-static inline int
-ir_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
-  bool force)
-{
-   return 0;
-}
-#endif
-
 asmlinkage void smp_irq_move_cleanup_interrupt(void)
 {
unsigned vector, me;
@@ -2636,7 +2571,7 @@ static void irq_remap_modify_chip_defaults(struct 
irq_chip *chip)
chip-irq_eoi = ir_ack_apic_level;
 
 #ifdef CONFIG_SMP
-   chip-irq_set_affinity = ir_ioapic_set_affinity;
+   chip-irq_set_affinity = intr_set_affinity;
 #endif
 }
 #endif /* CONFIG_IRQ_REMAP */
@@ -3826,7 +3761,7 @@ void __init setup_ioapic_dest(void)
mask = apic-target_cpus();
 
if (intr_remapping_enabled)
-   ir_ioapic_set_affinity(idata, mask, false);
+   intr_set_affinity(idata, mask, false);
else
ioapic_set_affinity(idata, mask, false);
}
diff --git a/drivers/iommu/intel_intr_remapping.c 
b/drivers/iommu/intel_intr_remapping.c
index f495eba..25372c1 100644
--- 

[PATCH 06/10] iommu/vt-d: Convert free_irte into a remap_ops callback

2012-03-30 Thread Suresh Siddha
From: Joerg Roedel joerg.roe...@amd.com

The operation for releasing a remapping entry is iommu
specific too.

Signed-off-by: Joerg Roedel joerg.roe...@amd.com
Acked-by: Yinghai Lu ying...@kernel.org
Cc: David Woodhouse dw...@infradead.org
Cc: Alex Williamson alex.william...@redhat.com
Signed-off-by: Suresh Siddha suresh.b.sid...@intel.com
---
 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(-)

diff --git a/arch/x86/include/asm/intr_remapping.h 
b/arch/x86/include/asm/intr_remapping.h
index ae933ec..a195b7d 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 a97c79a..5690469 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 25372c1..44a6e04 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 2f4f27f..a68d304 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 e0bc6e0..5748553 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 f2bd87f..7a207a3 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;
-- 
1.7.6.5

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 08/10] x86, iommu/vt-d: Clean up interfaces for interrupt remapping

2012-03-30 Thread Suresh Siddha
From: Joerg Roedel joerg.roe...@amd.com

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 joerg.roe...@amd.com
Acked-by: Yinghai Lu ying...@kernel.org
Cc: David Woodhouse dw...@infradead.org
Cc: Alex Williamson alex.william...@redhat.com
Signed-off-by: Suresh Siddha suresh.b.sid...@intel.com
---
 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

diff --git a/arch/x86/include/asm/irq_remapping.h 
b/arch/x86/include/asm/irq_remapping.h
deleted file mode 100644
index 0ddfc0b..000
--- 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 3db693b..073edd1 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -58,7 +58,6 @@
 #include asm/hypertransport.h
 #include asm/setup.h
 #include asm/intr_remapping.h
-#include asm/irq_remapping.h
 #include asm/hpet.h
 #include asm/hw_irq.h
 
@@ -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 a3bae67..7472634 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