Re: PROBLEM: do_IRQ: [number] No irq handler for vector (irq -1)

2014-01-16 Thread Neil Horman
On Wed, Jan 15, 2014 at 09:03:05PM -0700, Alex Williamson wrote:
> [cc +Neil]
> 
> On Tue, 2014-01-14 at 12:41 -0500, Anthony DeRobertis wrote:
> > I repeatedly get "No irq handler for vector" since upgrading to 3.12. I 
> > have confirmed it happens in git master as of yesterday morning 
> > (061f49ec2d722f485237870f04544d8bec15a778). Fixed by disabling VT-d quirk.
> 
> The full dmesg/console log may also prove useful.  Thanks,
> 
Agreed, I'd like to see the full dmesg log from both a boot that has VT-D
enabled in the bios, and then again with it disabled in the bios.  I would also
be interested to know if enabling VT-D in the bios, and adding nointremap to the
kernel command line reproduces the problem.  What I read below indicates:

1) Disabling VT-D in the bios makes it appear disabled to software, but the
system still behaves as though its enabled (i.e. symptoms of using the broken
hardware are still present) 

2) Enabling VT-D in bios, and modifying the kernel to allow it to remain enabled
allows allows the system to function without the symptoms of the broken
hardware.

I'm having trouble getting my head around those two conditions as they seem to
contradict each other.  Its like the sense of the bios switch is reversed (i.e.
setting VT-D enabled in the bios actually disables it, and vice versa).

Neil

> Alex
> 
> > [please cc me on responses; I'm not subscribed to the list]
> > 
> > DETAILS:
> > 
> > This is on a ASUS Sabertooth X58 board. Ever since upgrading to 3.12, 
> > I've been flooded with messages like:
> > 
> > Jan  5 19:06:46 Zia kernel: [292039.181501] do_IRQ: 1.76 No irq handler 
> > for vector (irq -1)
> > Jan  5 19:08:26 Zia kernel: [292138.390433] do_IRQ: 2.140 No irq handler 
> > for vector (irq -1)
> > Jan  5 19:40:16 Zia kernel: [294049.535992] do_IRQ: 1.84 No irq handler 
> > for vector (irq -1)
> > Jan  5 23:12:18 Zia kernel: [306774.882154] do_IRQ: 1.227 No irq handler 
> > for vector (irq -1)
> > 
> > When first booting 3.12, I got the "This system BIOS has enabled 
> > interrupt remapping on a chipset that contains an erratum making that 
> > feature unstable.  To maintain system stability interrupt remapping is 
> > being disabled. Please contact your BIOS vendor for an update" message. 
> > I believe I also got the do_IRQ messages in that configuration, but am 
> > not completely sure.
> > 
> > After seeing that, I rebooted the machine and turned off VT-d in the 
> > BIOS. The warning went away after that. However, the do_IRQ messages are 
> > definitely present in that configuration.
> > 
> > I have found one configuration that stops them. I turned back on VT-d in 
> > the BIOS, and then disabled the fix
> > "iommu/vt-d: add quirk for broken interrupt remapping on 55XX chipsets" 
> > (03bbcb2e7e292838bb0244f5a7816d194c911d62).
> > 
> > Also, I am running BIOS version 1402 (the latest), released 2012-08-29, 
> > with the release notes "improve VT-d compatibility issue." The machine 
> > has been perfectly stable, running pre-3.12 kernels with VT-d enabled 
> > (though I'm not sure I'm actually really using that feature, as I 
> > sometimes use KVM, but don't redirect any real hardware to the VMs).
> > 
> > Here is the patch I used to disable the quirk:
> > 
> > diff --git a/drivers/iommu/intel_irq_remapping.c 
> > b/drivers/iommu/intel_irq_remapping.c
> > index bab10b1..a5bf817 100644
> > --- a/drivers/iommu/intel_irq_remapping.c
> > +++ b/drivers/iommu/intel_irq_remapping.c
> > @@ -530,10 +530,11 @@ static int __init intel_irq_remapping_supported(void)
> >  "on a chipset that contains an erratum making 
> > that\n"
> >  "feature unstable.  To maintain system stability\n"
> >  "interrupt remapping is being disabled.  Please\n"
> > -   "contact your BIOS vendor for an update\n");
> > -   add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
> > +   "contact your BIOS vendor for an update\n"
> > +   "Ignoring and leaving enabled anyway!\n");
> > +   /* add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
> >  disable_irq_remap = 1;
> > -   return 0;
> > +   return 0; */
> >  }
> >   
> >  if (!dmar_ir_support())
> > 
> > 
> > SYSTEM INFO:
> > 
> > processor   : 0
> > vendor_id   : GenuineIntel
> > cpu family  : 6
> > model   : 26
> > model name  : Intel(R) Core(TM) i7 CPU 930  @ 2.80GHz
> > stepping: 5
> > microcode   : 0x19
> > cpu MHz : 1600.000
> > cache size  : 8192 KB
> > physical id : 0
> > siblings: 8
> > core id : 0
> > cpu cores   : 4
> > apicid  : 0
> > initial apicid  : 0
> > fpu : yes
> > fpu_exception   : yes
> > cpuid level : 11
> > wp  : yes
> > flags   : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca 
> > cmov pat 

[PATCH 09/11] ARM: dts: Add nodes for SMMUs on Calxeda ECX-2000

2014-01-16 Thread Andreas Herrmann
Cc: Rob Herring 
Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 arch/arm/boot/dts/ecx-2000.dts|   44 +++--
 arch/arm/boot/dts/ecx-common.dtsi |9 +---
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/ecx-2000.dts b/arch/arm/boot/dts/ecx-2000.dts
index 2ccbb57f..722de49 100644
--- a/arch/arm/boot/dts/ecx-2000.dts
+++ b/arch/arm/boot/dts/ecx-2000.dts
@@ -76,10 +76,11 @@
};
 
soc {
-   ranges = <0x 0x 0x 0x>;
+   ranges = <0x0 0x0 0x0 0x>;
 
timer {
-   compatible = "arm,cortex-a15-timer", "arm,armv7-timer"; 
interrupts = <1 13 0xf08>,
+   compatible = "arm,cortex-a15-timer", "arm,armv7-timer";
+   interrupts = <1 13 0xf08>,
<1 14 0xf08>,
<1 11 0xf08>,
<1 10 0xf08>;
@@ -109,6 +110,45 @@
interrupts = <0 76 4  0 75 4  0 74 4  0 73 4>;
};
};
+
+   soc@92000 {
+   ranges = <0x9 0x2000 0x9 0x2000 0x29>;
+   #address-cells = <2>;
+   #size-cells = <1>;
+   compatible = "simple-bus";
+   interrupt-parent = <&intc>;
+
+   smmu_mac0: smmu@92000 {
+   compatible = "arm,mmu-400";
+   reg = <0x9 0x2000 0x1>;
+   #global-interrupts = <1>;
+   interrupts = <0 106 4 0 106 4>;
+   mmu-masters = <&mac0 0 1>;
+   calxeda,smmu-secure-config-access;
+   arm,smmu-isolate-devices;
+   };
+
+   smmu_mac1: smmu@92008 {
+   compatible = "arm,mmu-400";
+   reg = <0x9 0x2008 0x1>;
+   #global-interrupts = <1>;
+   interrupts = <0 108 4 0 108 4>;
+   mmu-masters = <&mac1 0 1>;
+   calxeda,smmu-secure-config-access;
+   arm,smmu-isolate-devices;
+   };
+
+   smmu_sata: smmu@92018 {
+   compatible = "arm,mmu-400";
+   reg = <0x0009 0x2018 0x1>;
+   mmu-masters = <&sata 0 1 2 3 4 5 6 7 8 9>;
+   #global-interrupts = <1>;
+   interrupts = <0 114 4 0 114 4>;
+   calxeda,smmu-secure-config-access;
+   arm,smmu-isolate-devices;
+   };
+   };
+
 };
 
 /include/ "ecx-common.dtsi"
diff --git a/arch/arm/boot/dts/ecx-common.dtsi 
b/arch/arm/boot/dts/ecx-common.dtsi
index b90045a..ad9b2fd 100644
--- a/arch/arm/boot/dts/ecx-common.dtsi
+++ b/arch/arm/boot/dts/ecx-common.dtsi
@@ -33,7 +33,7 @@
compatible = "simple-bus";
interrupt-parent = <&intc>;
 
-   sata@ffe08000 {
+   sata: sata@ffe08000 {
compatible = "calxeda,hb-ahci";
reg = <0xffe08000 0x1>;
interrupts = <0 83 4>;
@@ -43,6 +43,7 @@
 &combophy0 3>;
calxeda,sgpio-gpio =<&gpioh 5 1 &gpioh 6 1 &gpioh 7 1>;
calxeda,led-order = <4 0 1 2 3>;
+   #stream-id-cells = <10>;
};
 
sdhci@ffe0e000 {
@@ -210,18 +211,20 @@
clock-names = "apb_pclk";
};
 
-   ethernet@fff5 {
+   mac0: ethernet@fff5 {
compatible = "calxeda,hb-xgmac";
reg = <0xfff5 0x1000>;
interrupts = <0 77 4  0 78 4  0 79 4>;
dma-coherent;
+   #stream-id-cells = <2>;
};
 
-   ethernet@fff51000 {
+   mac1: ethernet@fff51000 {
compatible = "calxeda,hb-xgmac";
reg = <0xfff51000 0x1000>;
interrupts = <0 80 4  0 81 4  0 82 4>;
dma-coherent;
+   #stream-id-cells = <2>;
};
 
combophy0: combo-phy@fff58000 {
-- 
1.7.9.5

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


[PATCH 01/11] iommu/arm-smmu: Introduce driver option handling

2014-01-16 Thread Andreas Herrmann
Introduce handling of driver options. Options are set based on DT
information when probing an SMMU device. The first option introduced
is "arm,smmu-isolate-devices". (It will be used in the bus notifier
block.)

Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 drivers/iommu/arm-smmu.c |   29 +
 1 file changed, 29 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index e46a887..0b97d03 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -47,6 +47,9 @@
 
 #include 
 
+/* Driver options */
+#define ARM_SMMU_OPT_ISOLATE_DEVICES   (1 << 0)
+
 /* Maximum number of stream IDs assigned to a single device */
 #define MAX_MASTER_STREAMIDS   8
 
@@ -348,6 +351,7 @@ struct arm_smmu_device {
 #define ARM_SMMU_FEAT_TRANS_S2 (1 << 3)
 #define ARM_SMMU_FEAT_TRANS_NESTED (1 << 4)
u32 features;
+   u32 options;
int version;
 
u32 num_context_banks;
@@ -398,6 +402,29 @@ struct arm_smmu_domain {
 static DEFINE_SPINLOCK(arm_smmu_devices_lock);
 static LIST_HEAD(arm_smmu_devices);
 
+struct arm_smmu_option_prop {
+   u32 opt;
+   const char *prop;
+};
+
+static struct arm_smmu_option_prop arm_smmu_options [] = {
+   { ARM_SMMU_OPT_ISOLATE_DEVICES, "arm,smmu-isolate-devices" },
+   { 0, NULL},
+};
+
+static void check_driver_options(struct arm_smmu_device *smmu)
+{
+   int i = 0;
+   do {
+   if (of_property_read_bool(smmu->dev->of_node,
+   arm_smmu_options[i].prop)) {
+   smmu->options |= arm_smmu_options[i].opt;
+   dev_dbg(smmu->dev, "option %s\n",
+   arm_smmu_options[i].prop);
+   }
+   } while (arm_smmu_options[++i].opt);
+}
+
 static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu,
struct device_node *dev_node)
 {
@@ -1783,6 +1810,8 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev)
}
smmu->dev = dev;
 
+   check_driver_options(smmu);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
smmu->base = devm_ioremap_resource(dev, res);
if (IS_ERR(smmu->base))
-- 
1.7.9.5

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


[PATCH 02/11] iommu/arm-smmu: Introduce bus notifier block

2014-01-16 Thread Andreas Herrmann
At the moment just handle BUS_NOTIFY_BIND_DRIVER to conditionally
isolate all master devices for an SMMU.

Depending on DT information each device is put into its own protection
domain (if possible).  For configuration with one or just a few
masters per SMMU that is easy to achieve.

In case of many devices per SMMU (e.g. MMU-500 with it's distributed
translation support) isolation of each device might not be possible --
depending on number of available SMR groups and/or context banks.

Default is that device isolation is contolled per SMMU with SMMU node
property "arm,smmu-isolate-devices" in a DT. If this property is set
for an SMMU node, device isolation is performed.

W/o device isolation the driver detects SMMUs but no translation is
configured (transactions just bypass translation process).

Note that for device isolation dma_base and size are fixed as 0 and
SZ_128M at the moment. Additional patches will address this
restriction and allow automatic growth of mapping size.

Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 drivers/iommu/arm-smmu.c |   45 +
 1 file changed, 45 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 0b97d03..bc81dd0 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -46,6 +46,7 @@
 #include 
 
 #include 
+#include 
 
 /* Driver options */
 #define ARM_SMMU_OPT_ISOLATE_DEVICES   (1 << 0)
@@ -1964,6 +1965,48 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
return 0;
 }
 
+static int arm_smmu_device_notifier(struct notifier_block *nb,
+   unsigned long action, void *data)
+{
+   struct device *dev = data;
+   struct dma_iommu_mapping *mapping;
+   struct arm_smmu_device *smmu;
+   int ret;
+
+   switch (action) {
+   case BUS_NOTIFY_BIND_DRIVER:
+
+   arm_smmu_add_device(dev);
+   smmu = dev->archdata.iommu;
+   if (!smmu || !(smmu->options & ARM_SMMU_OPT_ISOLATE_DEVICES))
+   break;
+
+   mapping = arm_iommu_create_mapping(&platform_bus_type,
+   0, SZ_128M, 0);
+   if (IS_ERR(mapping)) {
+   ret = PTR_ERR(mapping);
+   dev_info(dev, "arm_iommu_create_mapping failed\n");
+   break;
+   }
+
+   ret = arm_iommu_attach_device(dev, mapping);
+   if (ret < 0) {
+   dev_info(dev, "arm_iommu_attach_device failed\n");
+   arm_iommu_release_mapping(mapping);
+   }
+
+   break;
+   default:
+   break;
+   }
+
+   return 0;
+}
+
+static struct notifier_block device_nb = {
+   .notifier_call = arm_smmu_device_notifier,
+};
+
 #ifdef CONFIG_OF
 static struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", },
@@ -2000,6 +2043,8 @@ static int __init arm_smmu_init(void)
if (!iommu_present(&amba_bustype))
bus_set_iommu(&amba_bustype, &arm_smmu_ops);
 
+   bus_register_notifier(&platform_bus_type, &device_nb);
+
return 0;
 }
 
-- 
1.7.9.5

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


[PATCH 07/11] iommu/arm-smmu: Set MAX_MASTER_STREAMIDS to MAX_PHANDLE_ARGS

2014-01-16 Thread Andreas Herrmann
The DT parsing code that determines stream IDs uses
of_parse_phandle_with_args and thus MAX_MASTER_STREAMIDS
is always bound by MAX_PHANDLE_ARGS.

Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 drivers/iommu/arm-smmu.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a4e0c93..68bbe45 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -54,7 +54,7 @@
 #define ARM_SMMU_OPT_SECURE_CONFIG_ACCESS  (1 << 1)
 
 /* Maximum number of stream IDs assigned to a single device */
-#define MAX_MASTER_STREAMIDS   8
+#define MAX_MASTER_STREAMIDS   MAX_PHANDLE_ARGS
 
 /* Maximum stream ID */
 #define ARM_SMMU_MAX_STREAMID  (SZ_64K - 1)
-- 
1.7.9.5

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


[PATCH 03/11] iommu/arm-smmu: Support buggy implementation where all config accesses are secure

2014-01-16 Thread Andreas Herrmann
In such a case we have to use secure aliases of some non-secure
registers.

This handling is switched on by DT property
"calxeda,smmu-secure-config-access" for an SMMU node.

Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 drivers/iommu/arm-smmu.c |   31 +--
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index bc81dd0..823699e 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -50,6 +50,7 @@
 
 /* Driver options */
 #define ARM_SMMU_OPT_ISOLATE_DEVICES   (1 << 0)
+#define ARM_SMMU_OPT_SECURE_CONFIG_ACCESS  (1 << 1)
 
 /* Maximum number of stream IDs assigned to a single device */
 #define MAX_MASTER_STREAMIDS   8
@@ -64,6 +65,15 @@
 #define ARM_SMMU_GR0(smmu) ((smmu)->base)
 #define ARM_SMMU_GR1(smmu) ((smmu)->base + (smmu)->pagesize)
 
+/*
+ * SMMU global address space with conditional offset to access secure aliases 
of
+ * non-secure registers (e.g. nsCR0: 0x400, nsGFSR: 0x448, nsGFSYNR0: 0x450)
+ */
+#define ARM_SMMU_GR0_NS(smmu)  \
+   ((smmu)->base + \
+   ((smmu->options & ARM_SMMU_OPT_SECURE_CONFIG_ACCESS)\
+   ? 0x400 : 0))
+
 /* Page table bits */
 #define ARM_SMMU_PTE_PAGE  (((pteval_t)3) << 0)
 #define ARM_SMMU_PTE_CONT  (((pteval_t)1) << 52)
@@ -410,6 +420,7 @@ struct arm_smmu_option_prop {
 
 static struct arm_smmu_option_prop arm_smmu_options [] = {
{ ARM_SMMU_OPT_ISOLATE_DEVICES, "arm,smmu-isolate-devices" },
+   { ARM_SMMU_OPT_SECURE_CONFIG_ACCESS, 
"calxeda,smmu-secure-config-access" },
{ 0, NULL},
 };
 
@@ -639,16 +650,16 @@ static irqreturn_t arm_smmu_global_fault(int irq, void 
*dev)
 {
u32 gfsr, gfsynr0, gfsynr1, gfsynr2;
struct arm_smmu_device *smmu = dev;
-   void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+   void __iomem *gr0_base = ARM_SMMU_GR0_NS(smmu);
 
gfsr = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSR);
-   if (!gfsr)
-   return IRQ_NONE;
-
gfsynr0 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR0);
gfsynr1 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR1);
gfsynr2 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR2);
 
+   if (!gfsr)
+   return IRQ_NONE;
+
dev_err_ratelimited(smmu->dev,
"Unexpected global fault, this could be serious\n");
dev_err_ratelimited(smmu->dev,
@@ -1586,9 +1597,9 @@ static void arm_smmu_device_reset(struct arm_smmu_device 
*smmu)
int i = 0;
u32 reg;
 
-   /* Clear Global FSR */
-   reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSR);
-   writel(reg, gr0_base + ARM_SMMU_GR0_sGFSR);
+   /* clear global FSR */
+   reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR);
+   writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR);
 
/* Mark all SMRn as invalid and all S2CRn as bypass */
for (i = 0; i < smmu->num_mapping_groups; ++i) {
@@ -1608,7 +1619,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device 
*smmu)
writel_relaxed(0, gr0_base + ARM_SMMU_GR0_TLBIALLH);
writel_relaxed(0, gr0_base + ARM_SMMU_GR0_TLBIALLNSNH);
 
-   reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sCR0);
+   reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
 
/* Enable fault reporting */
reg |= (sCR0_GFRE | sCR0_GFIE | sCR0_GCFGFRE | sCR0_GCFGFIE);
@@ -1627,7 +1638,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device 
*smmu)
 
/* Push the button */
arm_smmu_tlb_sync(smmu);
-   writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sCR0);
+   writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
 }
 
 static int arm_smmu_id_size_to_bits(int size)
@@ -1961,7 +1972,7 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
free_irq(smmu->irqs[i], smmu);
 
/* Turn the thing off */
-   writel_relaxed(sCR0_CLIENTPD, ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_sCR0);
+   writel(sCR0_CLIENTPD,ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
return 0;
 }
 
-- 
1.7.9.5

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


[PATCH 08/11] of: Increase MAX_PHANDLE_ARGS

2014-01-16 Thread Andreas Herrmann
arm-smmu driver uses of_parse_phandle_with_args when parsing DT
information to determine stream IDs for a master device.
Thus the number of stream IDs per master device is bound by
MAX_PHANDLE_ARGS.

To support Calxeda ECX-2000 hardware arm-smmu driver requires a
slightly higher value for MAX_PHANDLE_ARGS as this hardware has 10
stream IDs for one master device.

Cc: Grant Likely 
Cc: Rob Herring 
Cc: devicet...@vger.kernel.org
Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 include/linux/of.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/of.h b/include/linux/of.h
index 276c546..0807af8 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -67,7 +67,7 @@ struct device_node {
 #endif
 };
 
-#define MAX_PHANDLE_ARGS 8
+#define MAX_PHANDLE_ARGS 10
 struct of_phandle_args {
struct device_node *np;
int args_count;
-- 
1.7.9.5

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


[PATCH v4 0/11] iommu/arm-smmu: Misc modifications to support SMMUs on Calxeda ECX-2000

2014-01-16 Thread Andreas Herrmann
Hi,

Here is v4 of arm-smmu changes to support SMMUs on Calxeda ECX-2000.

Patches are based on v3.13-rc8.

Major change to previous version is new code that allows to extend an
existing IOMMU address mapping. (last two patches)

Changelog:
v4:
 - added support to extend the size of an IOMMU address mapping
 - check for duplicate stream IDs
 - Increase MAX_PHANDLE_ARGS
 - misc minor changes of patch
   "iommu/arm-smmu: Introduce automatic stream-id-masking"
v3:
  http://marc.info/?l=linux-arm-kernel&m=138212725606348
v2:
  http://marc.info/?l=linux-arm-kernel&m=138135834704855
v1:
   http://marc.info/?l=linux-arm-kernel&m=138122450023564


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


[PATCH 05/11] iommu/arm-smmu: Check for duplicate stream IDs when registering master devices

2014-01-16 Thread Andreas Herrmann
Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 drivers/iommu/arm-smmu.c |   25 ++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 02a871e..a4e0c93 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -56,6 +56,9 @@
 /* Maximum number of stream IDs assigned to a single device */
 #define MAX_MASTER_STREAMIDS   8
 
+/* Maximum stream ID */
+#define ARM_SMMU_MAX_STREAMID  (SZ_64K - 1)
+
 /* Maximum number of context banks per SMMU */
 #define ARM_SMMU_MAX_CBS   128
 
@@ -386,6 +389,8 @@ struct arm_smmu_device {
u32 smr_mask_mask;
u32 smr_id_mask;
 
+   unsigned long   *sids;
+
struct list_headlist;
struct rb_root  masters;
 };
@@ -491,7 +496,7 @@ static int register_smmu_master(struct arm_smmu_device 
*smmu,
struct device *dev,
struct of_phandle_args *masterspec)
 {
-   int i;
+   int i, sid;
struct arm_smmu_master *master;
 
master = find_smmu_master(smmu, masterspec->np);
@@ -516,8 +521,14 @@ static int register_smmu_master(struct arm_smmu_device 
*smmu,
master->of_node = masterspec->np;
master->num_streamids   = masterspec->args_count;
 
-   for (i = 0; i < master->num_streamids; ++i)
-   master->streamids[i] = masterspec->args[i];
+   for (i = 0; i < master->num_streamids; ++i) {
+   sid = masterspec->args[i];
+   if (test_and_set_bit(sid, smmu->sids)) {
+   dev_err(dev, "duplicate stream ID (%d)\n", sid);
+   return -EEXIST;
+   }
+   master->streamids[i] = sid;
+   }
 
return insert_smmu_master(smmu, master);
 }
@@ -1934,6 +1945,14 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev)
}
smmu->dev = dev;
 
+   smmu->sids = devm_kzalloc(dev, BITS_TO_LONGS(ARM_SMMU_MAX_STREAMID) *
+   sizeof(long), GFP_KERNEL);
+   if (!smmu->sids) {
+   dev_err(dev,
+   "failed to allocate bitmap for stream ID tracking\n");
+   return -ENOMEM;
+   }
+
check_driver_options(smmu);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
1.7.9.5

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


[PATCH 06/11] documentation/iommu: Update description of ARM System MMU binding

2014-01-16 Thread Andreas Herrmann
This patch adds descriptions fore new properties of device tree
binding for the ARM SMMU architecture. These properties control
arm-smmu driver options.

Cc: Rob Herring 
Cc: Grant Likely 
Cc: Will Deacon 
Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 .../devicetree/bindings/iommu/arm,smmu.txt |   11 +++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index e34c6cd..7ad8ff0 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -48,6 +48,16 @@ conditions.
   from the mmu-masters towards memory) node for this
   SMMU.
 
+- arm,smmu-isolate-devices : Enable device isolation for all masters
+   of this SMMU. Ie. each master will be attached to
+   its own iommu domain.
+
+- calxeda,smmu-secure-config-access : Enable proper handling of buggy
+   implementations that always use secure access to
+   SMMU configuration registers. In this case
+   non-secure aliases of secure registers have to be
+   used during SMMU configuration.
+
 Example:
 
 smmu {
@@ -67,4 +77,5 @@ Example:
  */
 mmu-masters = <&dma0 0xd01d 0xd01e>,
   <&dma1 0xd11c>;
+arm,smmu-isolate-devices;
 };
-- 
1.7.9.5

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


[PATCH 10/11] arm: dma-mapping: Add additional parameters to arm_iommu_create_mapping

2014-01-16 Thread Andreas Herrmann
The new parameters are

  dma_addr_t grow_size

 Specifies the size by which the mapping will be extended in
 case that no sufficient space is left in the mapping to
 handle an iova allocation request. If a grow_size of 0 is
 specified the mapping is not extended.

  dma_addr_t max_size

 Specifies the maximum size for the entire mapping --
 including all extensions made over time. The mapping can only
 be extended if the entire size is less than or equal to
 max_size.

Adapt existing calls to arm_iommu_create_mapping in exynos_drm_iommu.c
and shmobile-iommu.c such that they do not make use of the extension
feature.

Adapt existing call to arm_iommu_create_mapping in arm-smmu.c such
that the extension feature will be used.

Cc: Russell King 
Cc: Marek Szyprowski 
Cc: Nicolas Pitre 
Cc: Hiroshi Doyu 
Cc: Joerg Roedel 
Cc: Inki Dae 
Cc: Kyungmin Park 
Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 arch/arm/include/asm/dma-iommu.h  |4 ++--
 arch/arm/mm/dma-mapping.c |2 +-
 drivers/gpu/drm/exynos/exynos_drm_iommu.c |4 ++--
 drivers/iommu/arm-smmu.c  |2 +-
 drivers/iommu/shmobile-iommu.c|2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
index a8c56ac..50edacd 100644
--- a/arch/arm/include/asm/dma-iommu.h
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -23,8 +23,8 @@ struct dma_iommu_mapping {
 };
 
 struct dma_iommu_mapping *
-arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
-int order);
+arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base,  size_t size,
+   int order, dma_addr_t grow_size, dma_addr_t max_size);
 
 void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping);
 
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f61a570..ccea46a 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1887,7 +1887,7 @@ struct dma_map_ops iommu_coherent_ops = {
  */
 struct dma_iommu_mapping *
 arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
-int order)
+   int order, dma_addr_t grow_size, dma_addr_t max_size)
 {
unsigned int count = size >> (PAGE_SHIFT + order);
unsigned int bitmap_size = BITS_TO_LONGS(count) * sizeof(long);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_iommu.c 
b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
index fb8db03..c1cd18b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_iommu.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_iommu.c
@@ -40,8 +40,8 @@ int drm_create_iommu_mapping(struct drm_device *drm_dev)
priv->da_space_order = EXYNOS_DEV_ADDR_ORDER;
 
mapping = arm_iommu_create_mapping(&platform_bus_type, priv->da_start,
-   priv->da_space_size,
-   priv->da_space_order);
+   priv->da_space_size,
+   priv->da_space_order, 0, 0);
if (IS_ERR(mapping))
return PTR_ERR(mapping);
 
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 68bbe45..31414e5 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2124,7 +2124,7 @@ static int arm_smmu_device_notifier(struct notifier_block 
*nb,
break;
 
mapping = arm_iommu_create_mapping(&platform_bus_type,
-   0, SZ_128M, 0);
+   0, SZ_128M, 0, SZ_128M, SZ_2G);
if (IS_ERR(mapping)) {
ret = PTR_ERR(mapping);
dev_info(dev, "arm_iommu_create_mapping failed\n");
diff --git a/drivers/iommu/shmobile-iommu.c b/drivers/iommu/shmobile-iommu.c
index d572863..1ba3a01 100644
--- a/drivers/iommu/shmobile-iommu.c
+++ b/drivers/iommu/shmobile-iommu.c
@@ -343,7 +343,7 @@ static int shmobile_iommu_add_device(struct device *dev)
mapping = archdata->iommu_mapping;
if (!mapping) {
mapping = arm_iommu_create_mapping(&platform_bus_type, 0,
-  L1_LEN << 20, 0);
+   L1_LEN << 20, 0, 0, 0);
if (IS_ERR(mapping))
return PTR_ERR(mapping);
archdata->iommu_mapping = mapping;
-- 
1.7.9.5

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


[PATCH 04/11] iommu/arm-smmu: Introduce automatic stream-id-masking

2014-01-16 Thread Andreas Herrmann
Try to determine a mask that can be used for all StreamIDs of a master
device. This allows to use just one SMR group instead of
number-of-streamids SMR groups for a master device.

Changelog:
* dropped "#define DEBUG"
* removed  "BUG_ON(!is_power_of_2(nr))" from determine_smr_mask
  by passing an order instead of the actual number of streamids
  to this function.
* added check for master->num_used_smrs being 0 to
  determine_smr_mapping
* renamed num_used_smrs to num_s2crs
* added validation of calculated SMR mask and id field (against number
  of implemented bits of SMR

Notes:

* Check for duplicate stream IDs
  - not implemented with this patch but in a separate patch
  - If the same stream ID is specified for 2 masters further behaviour
is implementation defined (we'll end with more than one matching
entry in the stream mapping table).
  - If one stream ID is specified twice for a master device, the
determination of how many S2CR/SMR groups are required for stream
mapping will fail. Esp. it can happen that more than one matching
entry is created in the stream mapping table.

* Sorting of stream IDs (to make usage of S2CR independend of sequence of
  stream IDs in DT)
  - intentionally not implemented
  - code does not rely on sorting
  - in fact sorting might make things worse with this simple
implementation
+ Example: master with stream IDs 4, 5, 6, 0xe, 0xf requires 3
  SMRs when IDs are specified in this sorted order (one to map 4,
  5, one to map 6, one to map 0xe, 0xf) but just 2 SMRs when
  specified as 4, 5, 0xe, 0xf, 6 (one to map 4, 5, 0xe, 0xf and
  one SMR to map 6)
  - thus by modifying the DT information you can affect the number of
S2CRs required for stream matching
  => I'd say "use common sense" when specifying stream IDs for a master
   device in DT.

Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 drivers/iommu/arm-smmu.c |  142 +-
 1 file changed, 127 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 823699e..02a871e 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -338,8 +339,9 @@ struct arm_smmu_master {
 * SMMU chain.
 */
struct rb_node  node;
-   int num_streamids;
+   u32 num_streamids;
u16 streamids[MAX_MASTER_STREAMIDS];
+   int num_s2crs;
 
/*
 * We only need to allocate these on the root SMMU, as we
@@ -381,6 +383,9 @@ struct arm_smmu_device {
u32 num_context_irqs;
unsigned int*irqs;
 
+   u32 smr_mask_mask;
+   u32 smr_id_mask;
+
struct list_headlist;
struct rb_root  masters;
 };
@@ -1025,10 +1030,109 @@ static void arm_smmu_domain_destroy(struct 
iommu_domain *domain)
kfree(smmu_domain);
 }
 
+static int determine_smr_mask(struct arm_smmu_device *smmu,
+   struct arm_smmu_master *master,
+   struct arm_smmu_smr *smr, int start, int order)
+{
+   u16 i, zero_bits_mask, one_bits_mask, const_mask;
+   int nr;
+
+   nr = 1 << order;
+
+   if (nr == 1) {
+   /* no mask, use streamid to match and be done with it */
+   smr->mask = 0;
+   smr->id = master->streamids[start];
+   return 0;
+   }
+
+   zero_bits_mask = 0;
+   one_bits_mask = 0x;
+   for (i = start; i < start + nr; i++) {
+   zero_bits_mask |= master->streamids[i];   /* const 0 bits */
+   one_bits_mask &= master->streamids[i]; /* const 1 bits */
+   }
+   zero_bits_mask = ~zero_bits_mask;
+
+   /* bits having constant values (either 0 or 1) */
+   const_mask = zero_bits_mask | one_bits_mask;
+
+   i = hweight16(~const_mask);
+   if ((1 << i) == nr) {
+   smr->mask = ~const_mask;
+   smr->id = one_bits_mask;
+   } else {
+   /* no usable mask for this set of streamids */
+   return 1;
+   }
+
+   if (((smr->mask & smmu->smr_mask_mask) != smr->mask) ||
+   ((smr->id & smmu->smr_id_mask) != smr->id))
+   /* insufficient number of mask/id bits */
+   return 1;
+
+   return 0;
+}
+
+static int determine_smr_mapping(struct arm_smmu_device *smmu,
+   struct arm_smmu_master *master,
+   struct arm_smmu_smr *smrs, int max_smrs)
+{
+   int nr_sid, nr, i, bit, start;
+
+   /*
+* This function is called only once -- when a master is added
+* to a domain. If master->

[PATCH 11/11] arm: dma-mapping: Add support to extend DMA IOMMU mappings

2014-01-16 Thread Andreas Herrmann
Instead of using just one bitmap to keep track of IO virtual addresses
(handed out for IOMMU use) introduce a list of iova_ranges (each
having its own bitmap). This allows us to extend existing mappings
when running out of iova space for a mapping.

If there is not enough space in the mapping to service an IO virtual
address allocation request, __alloc_iova() tries to extend the mapping
-- by allocating another bitmap -- and makes another allocation
attempt using the freshly allocated bitmap.

This allows arm iommu drivers to start with a decent initial size when
an dma_iommu_mapping is created and still to avoid running out of IO
virtual addresses for the mapping.

Tests were done on Calxeda ECX-2000 with smmu for sata and xgmac.
I've used SZ_512K both for initial mapping size and grow_size.

Cc: Russell King 
Cc: Marek Szyprowski 
Cc: Nicolas Pitre 
Cc: Hiroshi Doyu 
Cc: Andreas Herrmann 
Signed-off-by: Andreas Herrmann 
---
 arch/arm/include/asm/dma-iommu.h |   17 -
 arch/arm/mm/dma-mapping.c|  147 --
 2 files changed, 139 insertions(+), 25 deletions(-)

diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
index 50edacd..987d62c 100644
--- a/arch/arm/include/asm/dma-iommu.h
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -8,15 +8,26 @@
 #include 
 #include 
 #include 
+#include 
+
+struct dma_iommu_iova_range {
+   struct list_headlist_head;
+   unsigned long   *bitmap;
+   size_t  bits;
+   dma_addr_t  base;
+   dma_addr_t  size;
+};
 
 struct dma_iommu_mapping {
/* iommu specific data */
struct iommu_domain *domain;
 
-   void*bitmap;
-   size_t  bits;
-   unsigned intorder;
+   struct list_headiova_ranges;
dma_addr_t  base;
+   dma_addr_t  size;
+   dma_addr_t  grow_size;
+   dma_addr_t  max_size;
+   unsigned intorder;
 
spinlock_t  lock;
struct kref kref;
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ccea46a..503e8d6 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1069,6 +1070,8 @@ fs_initcall(dma_debug_do_init);
 
 /* IOMMU */
 
+static int extend_iommu_mapping(struct dma_iommu_mapping *mapping);
+
 static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
  size_t size)
 {
@@ -1076,6 +1079,8 @@ static inline dma_addr_t __alloc_iova(struct 
dma_iommu_mapping *mapping,
unsigned int align = 0;
unsigned int count, start;
unsigned long flags;
+   struct dma_iommu_iova_range *e;
+   bool area_found;
 
if (order > CONFIG_ARM_DMA_IOMMU_ALIGNMENT)
order = CONFIG_ARM_DMA_IOMMU_ALIGNMENT;
@@ -1086,32 +1091,80 @@ static inline dma_addr_t __alloc_iova(struct 
dma_iommu_mapping *mapping,
if (order > mapping->order)
align = (1 << (order - mapping->order)) - 1;
 
+   area_found = false;
spin_lock_irqsave(&mapping->lock, flags);
-   start = bitmap_find_next_zero_area(mapping->bitmap, mapping->bits, 0,
-  count, align);
-   if (start > mapping->bits) {
-   spin_unlock_irqrestore(&mapping->lock, flags);
-   return DMA_ERROR_CODE;
+   list_for_each_entry(e, &mapping->iova_ranges, list_head) {
+   start = bitmap_find_next_zero_area(e->bitmap, e->bits, 0,
+   count, align);
+   if (start > e->bits)
+   continue;
+
+   bitmap_set(e->bitmap, start, count);
+   area_found = true;
+   break;
}
 
-   bitmap_set(mapping->bitmap, start, count);
+   /*
+* Try to extend the existing mapping and perform a second
+* attempt to reserve an IO virtual address range of size
+* bytes.
+*/
+   if (!area_found) {
+   if (extend_iommu_mapping(mapping)) {
+   spin_unlock_irqrestore(&mapping->lock, flags);
+   return DMA_ERROR_CODE;
+   }
+   e = list_entry(mapping->iova_ranges.prev,
+   struct dma_iommu_iova_range, list_head);
+   start = bitmap_find_next_zero_area(e->bitmap, e->bits, 0,
+   count, align);
+   if (start > e->bits) {
+   spin_unlock_irqrestore(&mapping->lock, flags);
+   return DMA_ERROR_CODE;
+   }
+   bitmap_set(e->bitmap, start, count);
+   }
spin_unlock_irqrestore(&mapping->lock, flags);
 
-   retur

Re: [PATCH v2 3/5] intel-iommu: integrate DMA CMA

2014-01-16 Thread Marek Szyprowski

Hello,

On 2014-01-14 15:13, Akinobu Mita wrote:

This adds support for the DMA Contiguous Memory Allocator for intel-iommu.
This change enables dma_alloc_coherent() to allocate big contiguous
memory.

It is achieved in the same way as nommu_dma_ops currently does, i.e.
trying to allocate memory by dma_alloc_from_contiguous() and alloc_pages()
is used as a fallback.

Cc: Marek Szyprowski 
Cc: Konrad Rzeszutek Wilk 
Cc: David Woodhouse 
Cc: Don Dutile 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: "H. Peter Anvin" 
Cc: Andi Kleen 
Cc: x...@kernel.org
Cc: iommu@lists.linux-foundation.org
Signed-off-by: Akinobu Mita 
---
No change from the previous version

  drivers/iommu/intel-iommu.c | 32 
  1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index fd426ca..172c2b0 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3004,7 +3004,7 @@ static void *intel_alloc_coherent(struct device *hwdev, 
size_t size,
  dma_addr_t *dma_handle, gfp_t flags,
  struct dma_attrs *attrs)
  {
-   void *vaddr;
+   struct page *page = NULL;
int order;
  
  	size = PAGE_ALIGN(size);

@@ -3019,17 +3019,31 @@ static void *intel_alloc_coherent(struct device *hwdev, 
size_t size,
flags |= GFP_DMA32;
}
  
-	vaddr = (void *)__get_free_pages(flags, order);

-   if (!vaddr)
+   if (!(flags & GFP_ATOMIC)) {


GFP_ATOMIC is not a flag, so please change the above check to:
   if (flags & __GFP_WAIT)

I will also fix the similar issue in arch/x86/kernel/pci-dma.c


+   unsigned int count = size >> PAGE_SHIFT;
+
+   page = dma_alloc_from_contiguous(hwdev, count, order);
+   if (page && iommu_no_mapping(hwdev) &&
+   page_to_phys(page) + size > hwdev->coherent_dma_mask) {
+   dma_release_from_contiguous(hwdev, page, count);
+   page = NULL;
+   }
+   }
+
+   if (!page)
+   page = alloc_pages(flags, order);
+   if (!page)
return NULL;
-   memset(vaddr, 0, size);
+   memset(page_address(page), 0, size);
  
-	*dma_handle = __intel_map_single(hwdev, virt_to_bus(vaddr), size,

+   *dma_handle = __intel_map_single(hwdev, page_to_phys(page), size,
 DMA_BIDIRECTIONAL,
 hwdev->coherent_dma_mask);
if (*dma_handle)
-   return vaddr;
-   free_pages((unsigned long)vaddr, order);
+   return page_address(page);
+   if (!dma_release_from_contiguous(hwdev, page, size >> PAGE_SHIFT))
+   __free_pages(page, order);
+
return NULL;
  }
  
@@ -3037,12 +3051,14 @@ static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,

dma_addr_t dma_handle, struct dma_attrs *attrs)
  {
int order;
+   struct page *page = virt_to_page(vaddr);
  
  	size = PAGE_ALIGN(size);

order = get_order(size);
  
  	intel_unmap_page(hwdev, dma_handle, size, DMA_BIDIRECTIONAL, NULL);

-   free_pages((unsigned long)vaddr, order);
+   if (!dma_release_from_contiguous(hwdev, page, size >> PAGE_SHIFT))
+   __free_pages(page, order);
  }
  
  static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,


Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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


Re: [PATCH 09/11] ARM: dts: Add nodes for SMMUs on Calxeda ECX-2000

2014-01-16 Thread Rob Herring
On Thu, Jan 16, 2014 at 6:44 AM, Andreas Herrmann
 wrote:
> Cc: Rob Herring 
> Cc: Andreas Herrmann 
> Signed-off-by: Andreas Herrmann 

One minor comment, but otherwise:

Acked-by: Rob Herring 

> ---
>  arch/arm/boot/dts/ecx-2000.dts|   44 
> +++--
>  arch/arm/boot/dts/ecx-common.dtsi |9 +---
>  2 files changed, 48 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/boot/dts/ecx-2000.dts b/arch/arm/boot/dts/ecx-2000.dts
> index 2ccbb57f..722de49 100644
> --- a/arch/arm/boot/dts/ecx-2000.dts
> +++ b/arch/arm/boot/dts/ecx-2000.dts
> @@ -76,10 +76,11 @@
> };
>
> soc {
> -   ranges = <0x 0x 0x 0x>;
> +   ranges = <0x0 0x0 0x0 0x>;
>
> timer {
> -   compatible = "arm,cortex-a15-timer", 
> "arm,armv7-timer"; interrupts = <1 13 0xf08>,
> +   compatible = "arm,cortex-a15-timer", 
> "arm,armv7-timer";
> +   interrupts = <1 13 0xf08>,
> <1 14 0xf08>,
> <1 11 0xf08>,
> <1 10 0xf08>;
> @@ -109,6 +110,45 @@
> interrupts = <0 76 4  0 75 4  0 74 4  0 73 4>;
> };
> };
> +
> +   soc@92000 {

I believe this and the other > 32-bit addresses below should be
"soc@9,2000".

> +   ranges = <0x9 0x2000 0x9 0x2000 0x29>;
> +   #address-cells = <2>;
> +   #size-cells = <1>;
> +   compatible = "simple-bus";
> +   interrupt-parent = <&intc>;
> +
> +   smmu_mac0: smmu@92000 {
> +   compatible = "arm,mmu-400";
> +   reg = <0x9 0x2000 0x1>;
> +   #global-interrupts = <1>;
> +   interrupts = <0 106 4 0 106 4>;
> +   mmu-masters = <&mac0 0 1>;
> +   calxeda,smmu-secure-config-access;
> +   arm,smmu-isolate-devices;
> +   };
> +
> +   smmu_mac1: smmu@92008 {
> +   compatible = "arm,mmu-400";
> +   reg = <0x9 0x2008 0x1>;
> +   #global-interrupts = <1>;
> +   interrupts = <0 108 4 0 108 4>;
> +   mmu-masters = <&mac1 0 1>;
> +   calxeda,smmu-secure-config-access;
> +   arm,smmu-isolate-devices;
> +   };
> +
> +   smmu_sata: smmu@92018 {
> +   compatible = "arm,mmu-400";
> +   reg = <0x0009 0x2018 0x1>;
> +   mmu-masters = <&sata 0 1 2 3 4 5 6 7 8 9>;
> +   #global-interrupts = <1>;
> +   interrupts = <0 114 4 0 114 4>;
> +   calxeda,smmu-secure-config-access;
> +   arm,smmu-isolate-devices;
> +   };
> +   };
> +
>  };
>
>  /include/ "ecx-common.dtsi"
> diff --git a/arch/arm/boot/dts/ecx-common.dtsi 
> b/arch/arm/boot/dts/ecx-common.dtsi
> index b90045a..ad9b2fd 100644
> --- a/arch/arm/boot/dts/ecx-common.dtsi
> +++ b/arch/arm/boot/dts/ecx-common.dtsi
> @@ -33,7 +33,7 @@
> compatible = "simple-bus";
> interrupt-parent = <&intc>;
>
> -   sata@ffe08000 {
> +   sata: sata@ffe08000 {
> compatible = "calxeda,hb-ahci";
> reg = <0xffe08000 0x1>;
> interrupts = <0 83 4>;
> @@ -43,6 +43,7 @@
>  &combophy0 3>;
> calxeda,sgpio-gpio =<&gpioh 5 1 &gpioh 6 1 &gpioh 7 
> 1>;
> calxeda,led-order = <4 0 1 2 3>;
> +   #stream-id-cells = <10>;
> };
>
> sdhci@ffe0e000 {
> @@ -210,18 +211,20 @@
> clock-names = "apb_pclk";
> };
>
> -   ethernet@fff5 {
> +   mac0: ethernet@fff5 {
> compatible = "calxeda,hb-xgmac";
> reg = <0xfff5 0x1000>;
> interrupts = <0 77 4  0 78 4  0 79 4>;
> dma-coherent;
> +   #stream-id-cells = <2>;
> };
>
> -   ethernet@fff51000 {
> +   mac1: ethernet@fff51000 {
> compatible = "calxeda,hb-xgmac";
> reg = <0xfff51000 0x1000>;
> interrupts = <0 80 4  0 81 4  0 82 4>;
> dma-coherent;
> +   #stream-id-cells = <2>;
> };
>
> combophy0: combo-phy@fff58000 {
> --
> 1.7.9.5
>
>
> ___
> 

Re: [PATCH 08/11] of: Increase MAX_PHANDLE_ARGS

2014-01-16 Thread Rob Herring
On Thu, Jan 16, 2014 at 6:44 AM, Andreas Herrmann
 wrote:
> arm-smmu driver uses of_parse_phandle_with_args when parsing DT
> information to determine stream IDs for a master device.
> Thus the number of stream IDs per master device is bound by
> MAX_PHANDLE_ARGS.
>
> To support Calxeda ECX-2000 hardware arm-smmu driver requires a
> slightly higher value for MAX_PHANDLE_ARGS as this hardware has 10
> stream IDs for one master device.
>
> Cc: Grant Likely 
> Cc: Rob Herring 
> Cc: devicet...@vger.kernel.org
> Cc: Andreas Herrmann 
> Signed-off-by: Andreas Herrmann 

Acked-by: Rob Herring 

One comment below...

> ---
>  include/linux/of.h |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 276c546..0807af8 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -67,7 +67,7 @@ struct device_node {
>  #endif
>  };
>
> -#define MAX_PHANDLE_ARGS 8
> +#define MAX_PHANDLE_ARGS 10

Just bump this to 16. This is normally just a temporary on the stack
and 8 more words on the stack is not going to cost much.

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


Re: [PATCH 06/11] documentation/iommu: Update description of ARM System MMU binding

2014-01-16 Thread Rob Herring
On Thu, Jan 16, 2014 at 6:44 AM, Andreas Herrmann
 wrote:
> This patch adds descriptions fore new properties of device tree
> binding for the ARM SMMU architecture. These properties control
> arm-smmu driver options.
>
> Cc: Rob Herring 
> Cc: Grant Likely 
> Cc: Will Deacon 
> Cc: Andreas Herrmann 
> Signed-off-by: Andreas Herrmann 

Acked-by: Rob Herring 

> ---
>  .../devicetree/bindings/iommu/arm,smmu.txt |   11 +++
>  1 file changed, 11 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
> b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> index e34c6cd..7ad8ff0 100644
> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> @@ -48,6 +48,16 @@ conditions.
>from the mmu-masters towards memory) node for this
>SMMU.
>
> +- arm,smmu-isolate-devices : Enable device isolation for all masters
> +   of this SMMU. Ie. each master will be attached to
> +   its own iommu domain.
> +
> +- calxeda,smmu-secure-config-access : Enable proper handling of buggy
> +   implementations that always use secure access to
> +   SMMU configuration registers. In this case
> +   non-secure aliases of secure registers have to be
> +   used during SMMU configuration.
> +
>  Example:
>
>  smmu {
> @@ -67,4 +77,5 @@ Example:
>   */
>  mmu-masters = <&dma0 0xd01d 0xd01e>,
><&dma1 0xd11c>;
> +arm,smmu-isolate-devices;
>  };
> --
> 1.7.9.5
>
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: PROBLEM: do_IRQ: [number] No irq handler for vector (irq -1)

2014-01-16 Thread Anthony DeRobertis

I see the file names got lost in the list archive. To be clear:

The one that has

ACPI: DMAR bf7980c0 000140 (v01AMI  OEMDMAR 0001 MSFT 
0097)


is the one with VT-d on.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 3/5] intel-iommu: integrate DMA CMA

2014-01-16 Thread Akinobu Mita
2014/1/16 Marek Szyprowski :
>> @@ -3019,17 +3019,31 @@ static void *intel_alloc_coherent(struct device
>> *hwdev, size_t size,
>> flags |= GFP_DMA32;
>> }
>>   - vaddr = (void *)__get_free_pages(flags, order);
>> -   if (!vaddr)
>> +   if (!(flags & GFP_ATOMIC)) {
>
>
> GFP_ATOMIC is not a flag, so please change the above check to:
>if (flags & __GFP_WAIT)

Thanks for your review.  I'll fix it in the next version.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 2/5] x86: enable DMA CMA with swiotlb

2014-01-16 Thread Akinobu Mita
2014/1/16 Konrad Rzeszutek Wilk :
> On Tue, Jan 14, 2014 at 11:13:47PM +0900, Akinobu Mita wrote:
>> The DMA Contiguous Memory Allocator support on x86 is disabled when
>> swiotlb config option is enabled.  So DMA CMA is always disabled on
>> x86_64 because swiotlb is always enabled.  This attempts to support
>> for DMA CMA with enabling swiotlb config option.
>>
>> The contiguous memory allocator on x86 is integrated in the function
>> dma_generic_alloc_coherent() which is .alloc callback in nommu_dma_ops
>> for dma_alloc_coherent().
>>
>> x86_swiotlb_alloc_coherent() which is .alloc callback in swiotlb_dma_ops
>> tries to allocate with dma_generic_alloc_coherent() firstly and then
>> swiotlb_alloc_coherent() is called as a fallback.
>>
>> The main part of supporting DMA CMA with swiotlb is that changing
>> x86_swiotlb_free_coherent() which is .free callback in swiotlb_dma_ops
>> for dma_free_coherent() so that it can distinguish memory allocated by
>> dma_generic_alloc_coherent() from one allocated by swiotlb_alloc_coherent()
>> and release it with dma_generic_free_coherent() which can handle contiguous
>> memory.  This change requires making is_swiotlb_buffer() global function.
>>
>> This also needs to change .free callback in the dma_map_ops for amd_gart
>> and sta2x11, because these dma_ops are also using
>> dma_generic_alloc_coherent().
>>
>> Cc: Marek Szyprowski 
>> Cc: Konrad Rzeszutek Wilk 
>> Cc: David Woodhouse 
>> Cc: Don Dutile 
>> Cc: Thomas Gleixner 
>> Cc: Ingo Molnar 
>> Cc: "H. Peter Anvin" 
>> Cc: Andi Kleen 
>> Cc: x...@kernel.org
>> Cc: iommu@lists.linux-foundation.org
>> Signed-off-by: Akinobu Mita 
>> Acked-by: Marek Szyprowski 
>> ---
>> No change from the previous version
>>
>>  arch/x86/Kconfig   | 2 +-
>>  arch/x86/include/asm/swiotlb.h | 7 +++
>>  arch/x86/kernel/amd_gart_64.c  | 2 +-
>>  arch/x86/kernel/pci-swiotlb.c  | 9 ++---
>>  arch/x86/pci/sta2x11-fixup.c   | 6 ++
>>  include/linux/swiotlb.h| 2 ++
>>  lib/swiotlb.c  | 2 +-
>
> It looks reasonable from my perspective (as swiotlb maintainer).
>
> Not too thrilled about the  'is_swiotlb_buffer' but that code is
> quite small so it should be fast enough.

Thanks.  Can I get your Acked-by for this patch?
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 1/5] x86: make dma_alloc_coherent() return zeroed memory if CMA is enabled

2014-01-16 Thread Akinobu Mita
2014/1/16 Konrad Rzeszutek Wilk :
> On Tue, Jan 14, 2014 at 11:13:46PM +0900, Akinobu Mita wrote:
>> Calling dma_alloc_coherent() with __GFP_ZERO must return zeroed memory.
>>
>> But when the contiguous memory allocator (CMA) is enabled on x86 and
>> the memory region is allocated by dma_alloc_from_contiguous(), it
>> doesn't return zeroed memory.  Because dma_generic_alloc_coherent()
>
> So why not fix it there to return zeroed out memory?

I thought it looked nicer than this patch as we can remove memset
from all caller of dma_alloc_from_contiguous().  But if I look at
the caller on arm, we can't simply remove the memset because
__dma_clear_buffer() is used there for ensuring cache flushing and
it is used in many places.

Of course we can do redundant memset in dma_alloc_from_contiguous(),
but now I think this patch is less impact for fixing this problem.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu