[PATCH v2] iommu/arm-smmu: Make use of phandle iterators in device-tree device-tree parsing

2016-03-23 Thread Joerg Roedel
On Tue, Mar 22, 2016 at 01:38:06PM -0500, Rob Herring wrote:
> > +   struct of_phandle_iterator it;
> > +   struct arm_smmu_phandle_args masterspec;
> 
> Isn't this a bit big to put on the stack being ~512 bytes?

Yeah, you might be right. I havn't seen any problems booting with this
being allocated on the stack, but to be on the safe side I changed the
patch to allocate the masterspec with kmalloc, patch below.


Joerg

>From 85995d1edea7f61aae3c31e0fbd3258622d0b5ae Mon Sep 17 00:00:00 2001
From: Joerg Roedel 
Date: Wed, 16 Mar 2016 17:10:10 +0100
Subject: [PATCH] iommu/arm-smmu: Make use of phandle iterators in device-tree
 parsing

Remove the usage of of_parse_phandle_with_args() and replace
it by the phandle-iterator implementation so that we can
parse out all of the potentially present 128 stream-ids.

Signed-off-by: Joerg Roedel 
---
 drivers/iommu/arm-smmu.c | 41 +
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 59ee4b8..fa9b98c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -48,7 +48,7 @@
 #include "io-pgtable.h"
 
 /* Maximum number of stream IDs assigned to a single device */
-#define MAX_MASTER_STREAMIDS   MAX_PHANDLE_ARGS
+#define MAX_MASTER_STREAMIDS   128
 
 /* Maximum number of context banks per SMMU */
 #define ARM_SMMU_MAX_CBS   128
@@ -349,6 +349,12 @@ struct arm_smmu_domain {
struct iommu_domain domain;
 };
 
+struct arm_smmu_phandle_args {
+   struct device_node *np;
+   int args_count;
+   uint32_t args[MAX_MASTER_STREAMIDS];
+};
+
 static struct iommu_ops arm_smmu_ops;
 
 static DEFINE_SPINLOCK(arm_smmu_devices_lock);
@@ -458,7 +464,7 @@ static int insert_smmu_master(struct arm_smmu_device *smmu,
 
 static int register_smmu_master(struct arm_smmu_device *smmu,
struct device *dev,
-   struct of_phandle_args *masterspec)
+   struct arm_smmu_phandle_args *masterspec)
 {
int i;
struct arm_smmu_master *master;
@@ -1716,7 +1722,8 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev)
struct arm_smmu_device *smmu;
struct device *dev = &pdev->dev;
struct rb_node *node;
-   struct of_phandle_args masterspec;
+   struct of_phandle_iterator it;
+   struct arm_smmu_phandle_args *masterspec;
int num_irqs, i, err;
 
smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
@@ -1777,20 +1784,38 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev)
 
i = 0;
smmu->masters = RB_ROOT;
-   while (!of_parse_phandle_with_args(dev->of_node, "mmu-masters",
-  "#stream-id-cells", i,
-  &masterspec)) {
-   err = register_smmu_master(smmu, dev, &masterspec);
+
+   err = -ENOMEM;
+   /* No need to zero the memory for masterspec */
+   masterspec = kmalloc(sizeof(*masterspec), GFP_KERNEL);
+   if (!masterspec)
+   goto out_put_masters;
+
+   of_for_each_phandle(&it, err, dev->of_node,
+   "mmu-masters", "#stream-id-cells", 0) {
+   int count = of_phandle_iterator_args(&it, masterspec->args,
+MAX_MASTER_STREAMIDS);
+   masterspec->np  = of_node_get(it.node);
+   masterspec->args_count  = count;
+
+   err = register_smmu_master(smmu, dev, masterspec);
if (err) {
dev_err(dev, "failed to add master %s\n",
-   masterspec.np->name);
+   masterspec->np->name);
+   kfree(masterspec);
goto out_put_masters;
}
 
i++;
}
+
+   if (i == 0)
+   goto out_put_masters;
+
dev_notice(dev, "registered %d master devices\n", i);
 
+   kfree(masterspec);
+
parse_driver_options(smmu);
 
if (smmu->version > ARM_SMMU_V1 &&
-- 
2.4.3

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


Re: [PATCH 6/6] iommu/arm-smmu: Make use of phandle iterators in device-tree parsing

2016-03-23 Thread Joerg Roedel
Hi Robin,

On Tue, Mar 22, 2016 at 06:53:48PM +, Robin Murphy wrote:
> In a stream-matching implementation, a device may quite legitimately
> own anything up to _all_ of the stream IDs (32768, or 65536 if we
> ever implement support for the SMMUv2 EXID extension), so this is
> only a genuine limit for stream indexing (and if anyone ever
> actually made one of those, I don't think they're running mainline
> on it).

Do you mean we might see a lot more than the currently 128 supported
stream-ids for an smmu?

> Alternatively, how straightforward is it to change the DT on your
> machine? I'll be getting a v2 of [1] out in a couple of weeks (after
> imminent holidays), which already gets rid of MAX_MASTER_STREAMIDS
> altogether, and might also have grown proper SMR support by then.

Hmm, I don't know how to change the DT of this Seattle machine. I think
it is provided by the ACPI BIOS. At least it boots with grub2 and not
u-boot and there is no DT in /boot.


Joerg

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


Re: [PATCH 0/6] of: Implement iterator for phandles

2016-03-23 Thread Joerg Roedel
Hi Rob,

On Tue, Mar 22, 2016 at 01:45:41PM -0500, Rob Herring wrote:
> On Tue, Mar 22, 2016 at 12:58 PM, Joerg Roedel  wrote:
> > Please review. Patches are based on v4.5.
> 
> Other than my one comment, this looks good to me. For the series:
> 
> Acked-by: Rob Herring 

Thanks a lot for your fast reply! I guess these patches will go through
the DT tree, or should I carry them in the IOMMU tree? The DT tree
probably makes more sense.



Joerg

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


[Patch V3 1/4] iommu/vt-d: replace *hdr with drhd[0] in struct dmar_drhd_unit

2016-03-23 Thread Wei Yang
Before commit <6b1972493a84> ("iommu/vt-d: Implement DMAR unit hotplug
framework"),dmaru->hdr just points to the memory region of DMA remapping
hardware definition. In this case, it would have no difference to where we
put hdr.

After this commit, DMA remapping hardware definition is copied and
attach to the end of dmaru structure. By replacing a pointer with a
zero-sized array, that would save some space for this structure.

This patch replace *hdr with drhd[0] in struct dmar_drhd_unit and change
the type from acpi_dmar_header to acpi_dmar_hardware_unit. By doing so, it
reflects the real data type contained in dmar_drhd_unit and avoid some type
cast between them.

Besides this, this patch includes another change:
* remove redundant type cast to the same type in dmar_table_detect()

Signed-off-by: Wei Yang 
---
 drivers/iommu/dmar.c|   17 +
 drivers/iommu/intel_irq_remapping.c |   10 --
 include/linux/dmar.h|3 ++-
 3 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 80e3c17..80199b3 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -292,8 +292,7 @@ static int dmar_pci_bus_add_dev(struct dmar_pci_notify_info 
*info)
if (dmaru->include_all)
continue;
 
-   drhd = container_of(dmaru->hdr,
-   struct acpi_dmar_hardware_unit, header);
+   drhd = dmaru->drhd;
ret = dmar_insert_dev_scope(info, (void *)(drhd + 1),
((void *)drhd) + drhd->header.length,
dmaru->segment,
@@ -390,8 +389,7 @@ static int dmar_parse_one_drhd(struct acpi_dmar_header 
*header, void *arg)
 * If header is allocated from slab by ACPI _DSM method, we need to
 * copy the content because the memory buffer will be freed on return.
 */
-   dmaru->hdr = (void *)(dmaru + 1);
-   memcpy(dmaru->hdr, header, header->length);
+   memcpy(dmaru->drhd, drhd, drhd->header.length);
dmaru->reg_base_addr = drhd->address;
dmaru->segment = drhd->segment;
dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
@@ -529,8 +527,7 @@ static int __init dmar_table_detect(void)
 
/* if we could find DMAR table, then there are DMAR devices */
status = acpi_get_table_with_size(ACPI_SIG_DMAR, 0,
-   (struct acpi_table_header **)&dmar_tbl,
-   &dmar_tbl_size);
+   &dmar_tbl, &dmar_tbl_size);
 
if (ACPI_SUCCESS(status) && !dmar_tbl) {
pr_warn("Unable to map DMAR\n");
@@ -663,9 +660,7 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev)
 
rcu_read_lock();
for_each_drhd_unit(dmaru) {
-   drhd = container_of(dmaru->hdr,
-   struct acpi_dmar_hardware_unit,
-   header);
+   drhd = dmaru->drhd;
 
if (dmaru->include_all &&
drhd->segment == pci_domain_nr(dev->bus))
@@ -693,9 +688,7 @@ static void __init dmar_acpi_insert_dev_scope(u8 
device_number,
struct acpi_dmar_pci_path *path;
 
for_each_drhd_unit(dmaru) {
-   drhd = container_of(dmaru->hdr,
-   struct acpi_dmar_hardware_unit,
-   header);
+   drhd = dmaru->drhd;
 
for (scope = (void *)(drhd + 1);
 (unsigned long)scope < ((unsigned long)drhd) + 
drhd->header.length;
diff --git a/drivers/iommu/intel_irq_remapping.c 
b/drivers/iommu/intel_irq_remapping.c
index 1fae188..e35062e 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -886,17 +886,15 @@ static int ir_parse_one_ioapic_scope(struct 
acpi_dmar_device_scope *scope,
return 0;
 }
 
-static int ir_parse_ioapic_hpet_scope(struct acpi_dmar_header *header,
+static int ir_parse_ioapic_hpet_scope(struct acpi_dmar_hardware_unit *drhd,
  struct intel_iommu *iommu)
 {
int ret = 0;
-   struct acpi_dmar_hardware_unit *drhd;
struct acpi_dmar_device_scope *scope;
void *start, *end;
 
-   drhd = (struct acpi_dmar_hardware_unit *)header;
start = (void *)(drhd + 1);
-   end = ((void *)drhd) + header->length;
+   end = ((void *)drhd) + drhd->header.length;
 
while (start < end && ret == 0) {
scope = start;
@@ -940,7 +938,7 @@ static int __init parse_ioapics_under_ir(void)
if (!ecap_ir_support(iommu->ecap))
continue;
 
-   ret = ir_parse_ioapic_hpet_scope(drhd->hdr, iommu);
+   ret = ir_parse_ioapic_hpet_scope(drhd->drhd, iommu);
if (ret)
return ret;
 
@@ -1420,7 +1418,

[Patch V3 2/4] iommu/vt-d: use zero-sized array in DMAR related ACPI structures

2016-03-23 Thread Wei Yang
1. DMAR table has variable number of remapping entries
2. DMAR hardware unit has variable number of device scope
3. DMAR device scope has variable number of pci path

In current implementation, we use (head + 1) to access these variable
number elements, which may not be obvious for audience. Zero-sized array is
usually used for this purpose.

This patch adds zero-sized array for variable elements in DMAR ACPI
structures, which tries to make the code more audience friendly.

Signed-off-by: Wei Yang 
---
 drivers/iommu/dmar.c  |   22 ++
 include/acpi/actbl2.h |   31 +--
 2 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 80199b3..6bff602 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -225,7 +225,6 @@ int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
int i, level;
struct device *tmp, *dev = &info->dev->dev;
struct acpi_dmar_device_scope *scope;
-   struct acpi_dmar_pci_path *path;
 
if (segment != info->seg)
return 0;
@@ -236,9 +235,8 @@ int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
scope->entry_type != ACPI_DMAR_SCOPE_TYPE_BRIDGE)
continue;
 
-   path = (struct acpi_dmar_pci_path *)(scope + 1);
-   level = (scope->length - sizeof(*scope)) / sizeof(*path);
-   if (!dmar_match_pci_path(info, scope->bus, path, level))
+   level = (scope->length - sizeof(*scope)) / sizeof(*scope->path);
+   if (!dmar_match_pci_path(info, scope->bus, scope->path, level))
continue;
 
if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT) ^
@@ -393,7 +391,7 @@ static int dmar_parse_one_drhd(struct acpi_dmar_header 
*header, void *arg)
dmaru->reg_base_addr = drhd->address;
dmaru->segment = drhd->segment;
dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
-   dmaru->devices = dmar_alloc_dev_scope((void *)(drhd + 1),
+   dmaru->devices = dmar_alloc_dev_scope(drhd->dev_scope,
  ((void *)drhd) + 
drhd->header.length,
  &dmaru->devices_cnt);
if (dmaru->devices_cnt && dmaru->devices == NULL) {
@@ -579,7 +577,7 @@ static int dmar_walk_remapping_entries(struct 
acpi_dmar_header *start,
 static inline int dmar_walk_dmar_table(struct acpi_table_dmar *dmar,
   struct dmar_res_callback *cb)
 {
-   return dmar_walk_remapping_entries((void *)(dmar + 1),
+   return dmar_walk_remapping_entries(dmar->remapping_entries,
dmar->header.length - sizeof(*dmar), cb);
 }
 
@@ -685,12 +683,11 @@ static void __init dmar_acpi_insert_dev_scope(u8 
device_number,
struct acpi_dmar_device_scope *scope;
struct device *tmp;
int i;
-   struct acpi_dmar_pci_path *path;
 
for_each_drhd_unit(dmaru) {
drhd = dmaru->drhd;
 
-   for (scope = (void *)(drhd + 1);
+   for (scope = drhd->dev_scope;
 (unsigned long)scope < ((unsigned long)drhd) + 
drhd->header.length;
 scope = ((void *)scope) + scope->length) {
if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_NAMESPACE)
@@ -698,15 +695,16 @@ static void __init dmar_acpi_insert_dev_scope(u8 
device_number,
if (scope->enumeration_id != device_number)
continue;
 
-   path = (void *)(scope + 1);
pr_info("ACPI device \"%s\" under DMAR at %llx as 
%02x:%02x.%d\n",
dev_name(&adev->dev), dmaru->reg_base_addr,
-   scope->bus, path->device, path->function);
+   scope->bus, scope->path->device,
+   scope->path->function);
for_each_dev_scope(dmaru->devices, dmaru->devices_cnt, 
i, tmp)
if (tmp == NULL) {
dmaru->devices[i].bus = scope->bus;
-   dmaru->devices[i].devfn = 
PCI_DEVFN(path->device,
-   
path->function);
+   dmaru->devices[i].devfn =
+ PCI_DEVFN(scope->path->device,
+   scope->path->function);

rcu_assign_pointer(dmaru->devices[i].dev,
   
get_device(&adev->dev));
return;
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index 6e28f54..fd5c615 100644
--- a/include/acp

[Patch V3 0/4] Code refine for Intel IOMMU

2016-03-23 Thread Wei Yang
These four patches try to refine the Intel IOMMU.   
  

  
Patch 1/2 tries to make it more user friendly by add a zero-sized array in  
  
some dmar data structure.   
  
Patch 3 move the ckeck of Register Base Address ahead to avoid cleanup when it  
  
is NULL.
  
Patch 4 re-use dmar_walk_dmar_table() to make the code easy to understand.

V3:
  * change hdr to drhd from type acpi_dmar_header to acpi_dmar_hardware_unit 
  * add reason in changelog for the change in Patch 1

V2:
  * add patch 3 and 4

Wei Yang (4):
  iommu/vt-d: replace *hdr with drhd[0] in struct dmar_drhd_unit
  iommu/vt-d: use zero-sized array in DMAR related ACPI structures
  iommu/vt-d: check Register Base Address at the beginning of
dmar_parse_one_drhd()
  iommu/vt-d: refine dmar_acpi_dev_scope_init() with
dmar_walk_dmar_table()

 drivers/iommu/dmar.c|  129 +--
 drivers/iommu/intel_irq_remapping.c |   10 ++-
 include/acpi/actbl2.h   |   31 +
 include/linux/dmar.h|3 +-
 4 files changed, 87 insertions(+), 86 deletions(-)

-- 
1.7.9.5

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


[Patch V3 3/4] iommu/vt-d: check Register Base Address at the beginning of dmar_parse_one_drhd()

2016-03-23 Thread Wei Yang
A NULL value of Register Base Address in a Hardware Unit Definition means
it is an invalid dmar. Current implementation checks this value in
alloc_iommu(), by when it has already allocated memory to store itself and
device scope.

This patch moves the check at the beginning of dmar_parse_one_drhd(), so
that it notices this is an invalid dmar and avoids related setup jobs.

Signed-off-by: Wei Yang 
---
 drivers/iommu/dmar.c |   34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 6bff602..35fc8fb 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -363,6 +363,18 @@ dmar_find_dmaru(struct acpi_dmar_hardware_unit *drhd)
return NULL;
 }
 
+static void warn_invalid_dmar(u64 addr, const char *message)
+{
+   WARN_TAINT_ONCE(
+   1, TAINT_FIRMWARE_WORKAROUND,
+   "Your BIOS is broken; DMAR reported at address %llx%s!\n"
+   "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+   addr, message,
+   dmi_get_system_info(DMI_BIOS_VENDOR),
+   dmi_get_system_info(DMI_BIOS_VERSION),
+   dmi_get_system_info(DMI_PRODUCT_VERSION));
+}
+
 /**
  * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition
  * structure which uniquely represent one DMA remapping hardware unit
@@ -379,6 +391,11 @@ static int dmar_parse_one_drhd(struct acpi_dmar_header 
*header, void *arg)
if (dmaru)
goto out;
 
+   if (!drhd->address) {
+   warn_invalid_dmar(0, "");
+   return -EINVAL;
+   }
+
dmaru = kzalloc(sizeof(*dmaru) + header->length, GFP_KERNEL);
if (!dmaru)
return -ENOMEM;
@@ -808,18 +825,6 @@ int __init dmar_table_init(void)
return dmar_table_initialized < 0 ? dmar_table_initialized : 0;
 }
 
-static void warn_invalid_dmar(u64 addr, const char *message)
-{
-   WARN_TAINT_ONCE(
-   1, TAINT_FIRMWARE_WORKAROUND,
-   "Your BIOS is broken; DMAR reported at address %llx%s!\n"
-   "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
-   addr, message,
-   dmi_get_system_info(DMI_BIOS_VENDOR),
-   dmi_get_system_info(DMI_BIOS_VERSION),
-   dmi_get_system_info(DMI_PRODUCT_VERSION));
-}
-
 static int __ref
 dmar_validate_one_drhd(struct acpi_dmar_header *entry, void *arg)
 {
@@ -995,11 +1000,6 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
int msagaw = 0;
int err;
 
-   if (!drhd->reg_base_addr) {
-   warn_invalid_dmar(0, "");
-   return -EINVAL;
-   }
-
iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
if (!iommu)
return -ENOMEM;
-- 
1.7.9.5

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


[Patch V3 4/4] iommu/vt-d: refine dmar_acpi_dev_scope_init() with dmar_walk_dmar_table()

2016-03-23 Thread Wei Yang
dmar_acpi_dev_scope_init() iterates on the remapping structure and just do
proper job for ANDD structure. This is the what dmar_walk_dmar_table()
does.

This patch improves the code with dmar_walk_dmar_table().

Signed-off-by: Wei Yang 
---
 drivers/iommu/dmar.c |   56 --
 1 file changed, 32 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 35fc8fb..6281b45 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -733,36 +733,44 @@ static void __init dmar_acpi_insert_dev_scope(u8 
device_number,
device_number, dev_name(&adev->dev));
 }
 
-static int __init dmar_acpi_dev_scope_init(void)
+static int __dmar_acpi_dev_scope_init(struct acpi_dmar_header *header,
+ void *arg)
 {
struct acpi_dmar_andd *andd;
+   acpi_handle h;
+   struct acpi_device *adev;
+
+   andd = (struct acpi_dmar_andd *)header;
+   if (!ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT,
+ andd->device_name,
+ &h))) {
+   pr_err("Failed to find handle for ACPI object %s\n",
+  andd->device_name);
+   return 0;
+   }
+   if (acpi_bus_get_device(h, &adev)) {
+   pr_err("Failed to get device for ACPI object %s\n",
+  andd->device_name);
+   return 0;
+   }
+   dmar_acpi_insert_dev_scope(andd->device_number, adev);
+   return 0;
+}
+
+static int __init dmar_acpi_dev_scope_init(void)
+{
+   struct acpi_table_dmar *dmar;
+   struct dmar_res_callback cb = {
+   .print_entry = false,
+   .ignore_unhandled = true,
+   .cb[ACPI_DMAR_TYPE_NAMESPACE] = &__dmar_acpi_dev_scope_init,
+   };
 
if (dmar_tbl == NULL)
return -ENODEV;
 
-   for (andd = (void *)dmar_tbl + sizeof(struct acpi_table_dmar);
-((unsigned long)andd) < ((unsigned long)dmar_tbl) + 
dmar_tbl->length;
-andd = ((void *)andd) + andd->header.length) {
-   if (andd->header.type == ACPI_DMAR_TYPE_NAMESPACE) {
-   acpi_handle h;
-   struct acpi_device *adev;
-
-   if (!ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT,
- andd->device_name,
- &h))) {
-   pr_err("Failed to find handle for ACPI object 
%s\n",
-  andd->device_name);
-   continue;
-   }
-   if (acpi_bus_get_device(h, &adev)) {
-   pr_err("Failed to get device for ACPI object 
%s\n",
-  andd->device_name);
-   continue;
-   }
-   dmar_acpi_insert_dev_scope(andd->device_number, adev);
-   }
-   }
-   return 0;
+   dmar = (struct acpi_table_dmar *)dmar_tbl;
+   return dmar_walk_dmar_table(dmar, &cb);
 }
 
 int __init dmar_dev_scope_init(void)
-- 
1.7.9.5

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


Re: [PATCH v2] iommu/arm-smmu: Make use of phandle iterators in device-tree device-tree parsing

2016-03-23 Thread kbuild test robot
Hi Joerg,

[auto build test ERROR on iommu/next]
[also build test ERROR on v4.5 next-20160323]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improving the system]

url:
https://github.com/0day-ci/linux/commits/Joerg-Roedel/iommu-arm-smmu-Make-use-of-phandle-iterators-in-device-tree-device-tree-parsing/20160323-194824
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
config: arm64-defconfig (attached as .config)
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm64 

All errors (new ones prefixed by >>):

   drivers/iommu/arm-smmu.c: In function 'arm_smmu_device_dt_probe':
   drivers/iommu/arm-smmu.c:1746:29: error: storage size of 'it' isn't known
 struct of_phandle_iterator it;
^
>> drivers/iommu/arm-smmu.c:1815:2: error: implicit declaration of function 
>> 'of_for_each_phandle' [-Werror=implicit-function-declaration]
 of_for_each_phandle(&it, err, dev->of_node,
 ^
>> drivers/iommu/arm-smmu.c:1816:46: error: expected ';' before '{' token
   "mmu-masters", "#stream-id-cells", 0) {
 ^
   drivers/iommu/arm-smmu.c:1746:29: warning: unused variable 'it' 
[-Wunused-variable]
 struct of_phandle_iterator it;
^
   drivers/iommu/arm-smmu.c: At top level:
   drivers/iommu/arm-smmu.c:473:12: warning: 'register_smmu_master' defined but 
not used [-Wunused-function]
static int register_smmu_master(struct arm_smmu_device *smmu,
   ^
   cc1: some warnings being treated as errors

vim +/of_for_each_phandle +1815 drivers/iommu/arm-smmu.c

  1740  {
  1741  const struct of_device_id *of_id;
  1742  struct resource *res;
  1743  struct arm_smmu_device *smmu;
  1744  struct device *dev = &pdev->dev;
  1745  struct rb_node *node;
> 1746  struct of_phandle_iterator it;
  1747  struct arm_smmu_phandle_args *masterspec;
  1748  int num_irqs, i, err;
  1749  
  1750  smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
  1751  if (!smmu) {
  1752  dev_err(dev, "failed to allocate arm_smmu_device\n");
  1753  return -ENOMEM;
  1754  }
  1755  smmu->dev = dev;
  1756  
  1757  of_id = of_match_node(arm_smmu_of_match, dev->of_node);
  1758  smmu->version = (enum arm_smmu_arch_version)of_id->data;
  1759  
  1760  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1761  smmu->base = devm_ioremap_resource(dev, res);
  1762  if (IS_ERR(smmu->base))
  1763  return PTR_ERR(smmu->base);
  1764  smmu->size = resource_size(res);
  1765  
  1766  if (of_property_read_u32(dev->of_node, "#global-interrupts",
  1767   &smmu->num_global_irqs)) {
  1768  dev_err(dev, "missing #global-interrupts property\n");
  1769  return -ENODEV;
  1770  }
  1771  
  1772  num_irqs = 0;
  1773  while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, 
num_irqs))) {
  1774  num_irqs++;
  1775  if (num_irqs > smmu->num_global_irqs)
  1776  smmu->num_context_irqs++;
  1777  }
  1778  
  1779  if (!smmu->num_context_irqs) {
  1780  dev_err(dev, "found %d interrupts but expected at least 
%d\n",
  1781  num_irqs, smmu->num_global_irqs + 1);
  1782  return -ENODEV;
  1783  }
  1784  
  1785  smmu->irqs = devm_kzalloc(dev, sizeof(*smmu->irqs) * num_irqs,
  1786GFP_KERNEL);
  1787  if (!smmu->irqs) {
  1788  dev_err(dev, "failed to allocate %d irqs\n", num_irqs);
  1789  return -ENOMEM;
  1790  }
  1791  
  1792  for (i = 0; i < num_irqs; ++i) {
  1793  int irq = platform_get_irq(pdev, i);
  1794  
  1795  if (irq < 0) {
  1796  dev_err(dev, "failed to get irq index %d\n", i);
  1797  return -ENODEV;
  1798  }
  1799  smmu->irqs[i] = irq;
  1800  }
  1801  
  1802  err = arm_smmu_device_cfg_probe(smmu);
  1803  if (err)
  1804  return err;
  1805  
  1806  i = 0;
  1807  smmu->masters = RB_ROOT;
  1

Re: [v2] powerpc: Fix incorrect PPC32 PAMU dependency

2016-03-23 Thread Madalin-Cristian Bucur
> -Original Message-
> From: Andy Fleming 
> To: j...@8bytes.org
> Cc: iommu@lists.linux-foundation.org, linuxppc-...@lists.ozlabs.org
> Subject: [v2] powerpc: Fix incorrect PPC32 PAMU dependency
>
> The Freescale PAMU can be enabled on both 32 and 64-bit Power
> chips. Commit 477ab7a19cec8409e4e2dd10e7348e4cac3c06e5
> (iommu: Make more drivers depend on COMPILE_TEST)
> restricted PAMU to PPC32. PPC covers both.
>
> Signed-off-by: Andy Fleming 

Tested-by: Madalin Bucur 

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


RE: [v2] powerpc: Fix incorrect PPC32 PAMU dependency

2016-03-23 Thread Varun Sethi


> -Original Message-
> From: Linuxppc-dev [mailto:linuxppc-dev-
> bounces+varun.sethi=freescale@lists.ozlabs.org] On Behalf Of Madalin-
> Cristian Bucur
> Sent: Wednesday, March 23, 2016 3:29 PM
> To: j...@8bytes.org; Andy Fleming 
> Cc: iommu@lists.linux-foundation.org; linuxppc-...@lists.ozlabs.org
> Subject: Re: [v2] powerpc: Fix incorrect PPC32 PAMU dependency
> 
> > -Original Message-
> > From: Andy Fleming 
> > To: j...@8bytes.org
> > Cc: iommu@lists.linux-foundation.org, linuxppc-...@lists.ozlabs.org
> > Subject: [v2] powerpc: Fix incorrect PPC32 PAMU dependency
> >
> > The Freescale PAMU can be enabled on both 32 and 64-bit Power chips.
> > Commit 477ab7a19cec8409e4e2dd10e7348e4cac3c06e5
> > (iommu: Make more drivers depend on COMPILE_TEST) restricted PAMU to
> > PPC32. PPC covers both.
> >
> > Signed-off-by: Andy Fleming 
> 
> Tested-by: Madalin Bucur 
> 
Ackd-by: Varun Sethi 
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] intel-iommu: fix up comment

2016-03-23 Thread Michael S. Tsirkin
dma_pte_free_pagetable no longer depends on
last level ptes being clear, it clears them itself.
Fix up the comment to match.

Cc: Jiang Liu 
Suggested-by: Alex Williamson 
Signed-off-by: Michael S. Tsirkin 
---
 drivers/iommu/intel-iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a2e1b7f..0100553 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1143,7 +1143,7 @@ next:
} while (!first_pte_in_page(++pte) && pfn <= last_pfn);
 }
 
-/* free page table pages. last level pte should already be cleared */
+/* clear last level (leaf) ptes and free page table pages. */
 static void dma_pte_free_pagetable(struct dmar_domain *domain,
   unsigned long start_pfn,
   unsigned long last_pfn)
-- 
MST
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 0/6] of: Implement iterator for phandles

2016-03-23 Thread Rob Herring
On Wed, Mar 23, 2016 at 6:54 AM, Joerg Roedel  wrote:
> Hi Rob,
>
> On Tue, Mar 22, 2016 at 01:45:41PM -0500, Rob Herring wrote:
>> On Tue, Mar 22, 2016 at 12:58 PM, Joerg Roedel  wrote:
>> > Please review. Patches are based on v4.5.
>>
>> Other than my one comment, this looks good to me. For the series:
>>
>> Acked-by: Rob Herring 
>
> Thanks a lot for your fast reply! I guess these patches will go through
> the DT tree, or should I carry them in the IOMMU tree? The DT tree
> probably makes more sense.

Sure, I can take them.

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


[Patch V2 2/2] iommu: remove sysfs_link to device in iommu_group/devices when failed

2016-03-23 Thread Wei Yang
The original code forgets to remove the sysfs_link to a device in
iommu_group/devices directory, when the creation fails or conflicts on the
name.

This patch tries to remove the sysfs_link on the failure.

Signed-off-by: Wei Yang 
---
 drivers/iommu/iommu.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 2696a38..8f480ba 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -403,6 +403,7 @@ rename:
ret = sysfs_create_link_nowarn(group->devices_kobj,
   &dev->kobj, device->name);
if (ret) {
+   sysfs_remove_link(group->devices_kobj, device->name);
kfree(device->name);
if (ret == -EEXIST && i >= 0) {
/*
-- 
1.7.9.5

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


[Patch V2 1/2] iommu: remove the iommu_callback_data

2016-03-23 Thread Wei Yang
According to the code path, iommu_callback_data is passed in
iommu_bus_init() and  just used in {add/remove}_iommu_group, by when the
bus->iommu_ops is already set up properly.

This patch removes the iommu_callback_data by retrieving iommu_ops from
bus->iommu_ops directly.

Signed-off-by: Wei Yang 
---
 drivers/iommu/iommu.c |   21 ++---
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 0e3b009..2696a38 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -37,10 +37,6 @@ static struct kset *iommu_group_kset;
 static struct ida iommu_group_ida;
 static struct mutex iommu_group_mutex;
 
-struct iommu_callback_data {
-   const struct iommu_ops *ops;
-};
-
 struct iommu_group {
struct kobject kobj;
struct kobject *devices_kobj;
@@ -867,8 +863,7 @@ struct iommu_domain *iommu_group_default_domain(struct 
iommu_group *group)
 
 static int add_iommu_group(struct device *dev, void *data)
 {
-   struct iommu_callback_data *cb = data;
-   const struct iommu_ops *ops = cb->ops;
+   const struct iommu_ops *ops = dev->bus->iommu_ops;
int ret;
 
if (!ops->add_device)
@@ -891,8 +886,7 @@ static int add_iommu_group(struct device *dev, void *data)
 
 static int remove_iommu_group(struct device *dev, void *data)
 {
-   struct iommu_callback_data *cb = data;
-   const struct iommu_ops *ops = cb->ops;
+   const struct iommu_ops *ops = dev->bus->iommu_ops;
 
if (ops->remove_device && dev->iommu_group)
ops->remove_device(dev);
@@ -953,13 +947,10 @@ static int iommu_bus_notifier(struct notifier_block *nb,
return 0;
 }
 
-static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
+static int iommu_bus_init(struct bus_type *bus)
 {
int err;
struct notifier_block *nb;
-   struct iommu_callback_data cb = {
-   .ops = ops,
-   };
 
nb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
if (!nb)
@@ -971,7 +962,7 @@ static int iommu_bus_init(struct bus_type *bus, const 
struct iommu_ops *ops)
if (err)
goto out_free;
 
-   err = bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
+   err = bus_for_each_dev(bus, NULL, NULL, add_iommu_group);
if (err)
goto out_err;
 
@@ -980,7 +971,7 @@ static int iommu_bus_init(struct bus_type *bus, const 
struct iommu_ops *ops)
 
 out_err:
/* Clean up */
-   bus_for_each_dev(bus, NULL, &cb, remove_iommu_group);
+   bus_for_each_dev(bus, NULL, NULL, remove_iommu_group);
bus_unregister_notifier(bus, nb);
 
 out_free:
@@ -1012,7 +1003,7 @@ int bus_set_iommu(struct bus_type *bus, const struct 
iommu_ops *ops)
bus->iommu_ops = ops;
 
/* Do IOMMU specific setup for this bus-type */
-   err = iommu_bus_init(bus, ops);
+   err = iommu_bus_init(bus);
if (err)
bus->iommu_ops = NULL;
 
-- 
1.7.9.5

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


[Patch V2 0/2] Cleanup on IOMMU

2016-03-23 Thread Wei Yang
This two patches tries to do some cleanup in iommu.

V2:
  * add patch 2

Wei Yang (2):
  iommu: remove the iommu_callback_data
  iommu: remove sysfs_link to device in iommu_group/devices when failed

 drivers/iommu/iommu.c |   22 +++---
 1 file changed, 7 insertions(+), 15 deletions(-)

-- 
1.7.9.5

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


Re: [PATCH] iommu: remove the iommu_callback_data

2016-03-23 Thread Wei Yang
Obsolete this one, V2 is sent.

On Sun, Mar 20, 2016 at 01:57:52AM +, Wei Yang wrote:
>According to the code path, iommu_callback_data is passed in
>iommu_bus_init() and  just used in {add/remove}_iommu_group, by when the
>bus->iommu_ops is already set up properly.
>
>This patch removes the iommu_callback_data by retrieving iommu_ops from
>bus->iommu_ops directly.
>
>Signed-off-by: Wei Yang 
>---
> drivers/iommu/iommu.c | 21 ++---
> 1 file changed, 6 insertions(+), 15 deletions(-)
>
>diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
>index 0e3b009..2696a38 100644
>--- a/drivers/iommu/iommu.c
>+++ b/drivers/iommu/iommu.c
>@@ -37,10 +37,6 @@ static struct kset *iommu_group_kset;
> static struct ida iommu_group_ida;
> static struct mutex iommu_group_mutex;
> 
>-struct iommu_callback_data {
>-  const struct iommu_ops *ops;
>-};
>-
> struct iommu_group {
>   struct kobject kobj;
>   struct kobject *devices_kobj;
>@@ -867,8 +863,7 @@ struct iommu_domain *iommu_group_default_domain(struct 
>iommu_group *group)
> 
> static int add_iommu_group(struct device *dev, void *data)
> {
>-  struct iommu_callback_data *cb = data;
>-  const struct iommu_ops *ops = cb->ops;
>+  const struct iommu_ops *ops = dev->bus->iommu_ops;
>   int ret;
> 
>   if (!ops->add_device)
>@@ -891,8 +886,7 @@ static int add_iommu_group(struct device *dev, void *data)
> 
> static int remove_iommu_group(struct device *dev, void *data)
> {
>-  struct iommu_callback_data *cb = data;
>-  const struct iommu_ops *ops = cb->ops;
>+  const struct iommu_ops *ops = dev->bus->iommu_ops;
> 
>   if (ops->remove_device && dev->iommu_group)
>   ops->remove_device(dev);
>@@ -953,13 +947,10 @@ static int iommu_bus_notifier(struct notifier_block *nb,
>   return 0;
> }
> 
>-static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
>+static int iommu_bus_init(struct bus_type *bus)
> {
>   int err;
>   struct notifier_block *nb;
>-  struct iommu_callback_data cb = {
>-  .ops = ops,
>-  };
> 
>   nb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
>   if (!nb)
>@@ -971,7 +962,7 @@ static int iommu_bus_init(struct bus_type *bus, const 
>struct iommu_ops *ops)
>   if (err)
>   goto out_free;
> 
>-  err = bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
>+  err = bus_for_each_dev(bus, NULL, NULL, add_iommu_group);
>   if (err)
>   goto out_err;
> 
>@@ -980,7 +971,7 @@ static int iommu_bus_init(struct bus_type *bus, const 
>struct iommu_ops *ops)
> 
> out_err:
>   /* Clean up */
>-  bus_for_each_dev(bus, NULL, &cb, remove_iommu_group);
>+  bus_for_each_dev(bus, NULL, NULL, remove_iommu_group);
>   bus_unregister_notifier(bus, nb);
> 
> out_free:
>@@ -1012,7 +1003,7 @@ int bus_set_iommu(struct bus_type *bus, const struct 
>iommu_ops *ops)
>   bus->iommu_ops = ops;
> 
>   /* Do IOMMU specific setup for this bus-type */
>-  err = iommu_bus_init(bus, ops);
>+  err = iommu_bus_init(bus);
>   if (err)
>   bus->iommu_ops = NULL;
> 
>-- 
>2.5.0

-- 
Wei Yang
Help you, Help me
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [Patch V2 2/2] iommu: remove sysfs_link to device in iommu_group/devices when failed

2016-03-23 Thread Alex Williamson
On Wed, 23 Mar 2016 22:25:11 +
Wei Yang  wrote:

> The original code forgets to remove the sysfs_link to a device in
> iommu_group/devices directory, when the creation fails or conflicts on the
> name.
> 
> This patch tries to remove the sysfs_link on the failure.
> 
> Signed-off-by: Wei Yang 
> ---
>  drivers/iommu/iommu.c |1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 2696a38..8f480ba 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -403,6 +403,7 @@ rename:
>   ret = sysfs_create_link_nowarn(group->devices_kobj,
>  &dev->kobj, device->name);
>   if (ret) {
> + sysfs_remove_link(group->devices_kobj, device->name);
>   kfree(device->name);
>   if (ret == -EEXIST && i >= 0) {
>   /*

If we failed to create a link, potentially due to a conflicting link
already present, then aren't we arbitrarily removing that conflicting
link with this change?  If sysfs_create_link_nowarn() fails then we
haven't created a link of our own to remove.  This looks wrong.  Thanks,

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