All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/11] acpi: arm: IORT Support for Xen
@ 2018-01-02  9:27 manish.jaggi
  2018-01-02  9:27 ` [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid manish.jaggi
                   ` (11 more replies)
  0 siblings, 12 replies; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:27 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

This patch aims to add the support of IORT in Xen. Below is the list
of major components which this patchset provides.
a. Add support for parsing the IORT 
b. Provides API to populate/query requesterid - streamID mappings and
   reuqesterid - deviceid mappings
c. The requesterid - deviceid mappings is used to create the IORT for
   hardware domain (which hides smmu nodes from IORT)
d. iort.c fwnode.h fwspec code is imported from linux and modified.
e. Few kernel helper routines are also imported from linux.

This patchset compiles with [1]  [RFC v4 0/8] SMMUv3 driver.

[1] https://lists.xen.org/archives/html/xen-devel/2017-12/msg01294.html

Manish Jaggi (11):
  acpi: arm: Public API for populating and query based on requesterid
  acpi: arm: API to query estimated size of hardware domain's IORT
  acpi: arm: Code to generate Hardware Domains IORT
  acpi: arm: Import iort.c and acpi_iort.h
  acpi: arm: Import fwnode.h from linux
  acpi: arm: fwnode xen spacific changes
  Add kernel helper functions
  Add ACPI_IORT config
  acpi: arm: Xen IORT Changes
  acpi: arm: IORT parsing functions to prepare requesterId maps
  Add to_pci_dev macro

 xen/arch/arm/Kconfig            |   5 +
 xen/arch/arm/domain_build.c     |  40 ++-
 xen/arch/arm/setup.c            |   2 +
 xen/drivers/acpi/Kconfig        |   3 +
 xen/drivers/acpi/Makefile       |   1 +
 xen/drivers/acpi/arm/Makefile   |   3 +
 xen/drivers/acpi/arm/gen-iort.c | 352 +++++++++++++++++++++++++
 xen/drivers/acpi/arm/iort.c     | 569 ++++++++++++++++++++++++++++++++++++++++
 xen/drivers/acpi/arm/ridmap.c   | 124 +++++++++
 xen/drivers/passthrough/iommu.c |  75 ++++++
 xen/include/acpi/acpi_iort.h    |  57 ++++
 xen/include/acpi/gen-iort.h     |   7 +
 xen/include/acpi/ridmap.h       |  77 ++++++
 xen/include/asm-arm/acpi.h      |   1 +
 xen/include/asm-arm/device.h    |  11 +-
 xen/include/xen/fwnode.h        | 125 +++++++++
 xen/include/xen/iommu.h         |  22 ++
 xen/include/xen/kernel.h        |  10 +
 xen/include/xen/pci.h           |   3 +
 19 files changed, 1484 insertions(+), 3 deletions(-)
 create mode 100644 xen/drivers/acpi/arm/Makefile
 create mode 100644 xen/drivers/acpi/arm/gen-iort.c
 create mode 100644 xen/drivers/acpi/arm/iort.c
 create mode 100644 xen/drivers/acpi/arm/ridmap.c
 create mode 100644 xen/include/acpi/acpi_iort.h
 create mode 100644 xen/include/acpi/gen-iort.h
 create mode 100644 xen/include/acpi/ridmap.h
 create mode 100644 xen/include/xen/fwnode.h

-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
@ 2018-01-02  9:27 ` manish.jaggi
  2018-01-16 17:53   ` Julien Grall
  2018-01-16 18:31   ` Julien Grall
  2018-01-02  9:28 ` [RFC 02/11] acpi: arm: API to query estimated size of hardware domain's IORT manish.jaggi
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:27 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

 Public API to populate and query map between requester id and
 streamId/DeviceID. IORT is parsed one time (outside this patch)
 and two lists are created one for mapping between reuesterId and streamid
 and another between requesterID and deviceID.

 These lists eliminate the need to reparse IORT for querying streamid
 or deviceid using requesterid.

 Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
---
 xen/drivers/acpi/Makefile     |   1 +
 xen/drivers/acpi/arm/Makefile |   1 +
 xen/drivers/acpi/arm/ridmap.c | 124 ++++++++++++++++++++++++++++++++++++++++++
 xen/include/acpi/ridmap.h     |  77 ++++++++++++++++++++++++++
 4 files changed, 203 insertions(+)

diff --git a/xen/drivers/acpi/Makefile b/xen/drivers/acpi/Makefile
index 444b11d583..80a074e007 100644
--- a/xen/drivers/acpi/Makefile
+++ b/xen/drivers/acpi/Makefile
@@ -1,6 +1,7 @@
 subdir-y += tables
 subdir-y += utilities
 subdir-$(CONFIG_X86) += apei
+subdir-$(CONFIG_ARM) += arm
 
 obj-bin-y += tables.init.o
 obj-$(CONFIG_NUMA) += numa.o
diff --git a/xen/drivers/acpi/arm/Makefile b/xen/drivers/acpi/arm/Makefile
new file mode 100644
index 0000000000..046fad5e3d
--- /dev/null
+++ b/xen/drivers/acpi/arm/Makefile
@@ -0,0 +1 @@
+obj-y = ridmap.o
diff --git a/xen/drivers/acpi/arm/ridmap.c b/xen/drivers/acpi/arm/ridmap.c
new file mode 100644
index 0000000000..2c3a8876ea
--- /dev/null
+++ b/xen/drivers/acpi/arm/ridmap.c
@@ -0,0 +1,124 @@
+/*
+ * xen/drivers/acpi/arm/ridmap.c
+ *
+ * Public API to populate and query map between requester id and
+ * streamId/DeviceID
+ *
+ * Manish Jaggi <manish.jaggi@linaro.org>
+ * Copyright (c) 2018 Linaro.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <acpi/ridmap.h>
+#include <xen/iommu.h>
+#include <xen/kernel.h>
+#include <xen/list.h>
+#include <xen/pci.h>
+
+struct list_head rid_streamid_map_list;
+struct list_head rid_deviceid_map_list;
+
+void init_ridmaps(void)
+{
+    INIT_LIST_HEAD(&rid_deviceid_map_list);
+    INIT_LIST_HEAD(&rid_streamid_map_list);
+}
+
+int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
+                         struct acpi_iort_node *smmu_node,
+                         u32 input_base, u32 output_base, u32 id_count)
+{
+    struct rid_streamid_map *rid_map;
+    rid_map = xzalloc(struct rid_streamid_map);
+
+    if (!rid_map)
+        return -ENOMEM;
+
+    rid_map->idmap.input_base = input_base;
+    rid_map->idmap.output_base = output_base;
+    rid_map->idmap.id_count = id_count;
+    rid_map->pcirc_node = pcirc_node;
+    rid_map->smmu_node = smmu_node;
+
+    list_add_tail(&rid_map->entry, &rid_streamid_map_list);
+    return 0;
+}
+
+int add_rid_deviceid_map(struct acpi_iort_node *pcirc_node,
+                         struct acpi_iort_node *its_node,
+                         u32 input_base, u32 output_base, u32 id_count)
+{
+    struct rid_deviceid_map *rid_map;
+    rid_map = xzalloc(struct rid_deviceid_map);
+
+    if (!rid_map)
+        return -ENOMEM;
+
+    rid_map->idmap.input_base = input_base;
+    rid_map->idmap.output_base = output_base;
+    rid_map->idmap.id_count = id_count;
+    rid_map->pcirc_node = pcirc_node;
+    rid_map->its_node = its_node;
+
+    list_add_tail(&rid_map->entry, &rid_deviceid_map_list);
+    return 0;
+}
+
+void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, u32 *streamid,
+                    struct acpi_iort_node **smmu_node)
+{
+    struct rid_streamid_map *rmap;
+
+    list_for_each_entry(rmap, &rid_streamid_map_list, entry)
+    {
+        if (rmap->pcirc_node == pcirc_node)
+        {
+            if ( (rid >= rmap->idmap.input_base) &&
+                 (rid < rmap->idmap.input_base + rmap->idmap.id_count) )
+            {
+                *streamid = rid - rmap->idmap.input_base +
+                            rmap->idmap.output_base;
+                *smmu_node = rmap->smmu_node;
+                break;
+            }
+        }
+    }
+
+}
+
+void query_deviceid(struct acpi_iort_node *pcirc_node, u16 rid, u32 *deviceid)
+{
+    struct rid_deviceid_map *rmap;
+
+    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
+    {
+        if (rmap->pcirc_node == pcirc_node)
+        {
+            if ( (rid >= rmap->idmap.input_base) &&
+                 (rid < rmap->idmap.input_base + rmap->idmap.id_count) )
+            {
+                *deviceid = rid - rmap->idmap.input_base +
+                            rmap->idmap.output_base;
+                break;
+            }
+        }
+    }
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/acpi/ridmap.h b/xen/include/acpi/ridmap.h
new file mode 100644
index 0000000000..806f401d89
--- /dev/null
+++ b/xen/include/acpi/ridmap.h
@@ -0,0 +1,77 @@
+/*
+ * xen/include/acpi/ridmap.h
+ *
+ * Mapping structures to hold map between requester id and streamId/DeviceID
+ * after paring the IORT table.
+ *
+ * Manish Jaggi <manish.jaggi@linaro.org>
+ * Copyright (c) 2018 Linaro.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#ifndef RID_MAP_H
+#define RID_MAP_H
+
+#include <xen/acpi.h>
+
+struct id_map_struct
+{
+    u16 input_base;
+    u32 output_base;
+    u16 id_count;
+};
+
+struct rid_streamid_map
+{
+    struct acpi_iort_node *pcirc_node;
+    struct id_map_struct idmap;
+    struct list_head entry;
+    struct acpi_iort_node *smmu_node;
+};
+
+struct rid_deviceid_map
+{
+    struct acpi_iort_node *pcirc_node;
+    struct acpi_iort_node *its_node;
+    struct id_map_struct idmap;
+    struct list_head entry;
+};
+
+extern struct list_head rid_streamid_map_list;
+extern struct list_head rid_deviceid_map_list;
+
+int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
+                         struct acpi_iort_node *smmu_node,
+                         u32 input_base, u32 output_base, u32 id_count);
+
+int add_rid_deviceid_map(struct acpi_iort_node *pcirc_node,
+                         struct acpi_iort_node *its_node,
+                         u32 input_base, u32 output_base, u32 id_count);
+
+void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, u32 *streamid,
+                    struct acpi_iort_node **smmu_node);
+
+void query_deviceid(struct acpi_iort_node *pcirc_node,
+                    u16 rid, u32 *deviceid);
+
+void init_ridmaps(void);
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 02/11] acpi: arm: API to query estimated size of hardware domain's IORT
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
  2018-01-02  9:27 ` [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-16 18:52   ` Julien Grall
  2018-01-02  9:28 ` [RFC 03/11] acpi: arm: Code to generate Hardware Domains IORT manish.jaggi
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

 Code to query estimated IORT size for hardware domain.
 IORT for hardware domain is generated using the requesterId and deviceId map.

 Signed-off-by: Manish Jaggi <manish.jaggi@linaro.com>
---
 xen/arch/arm/domain_build.c     |  12 ++++-
 xen/drivers/acpi/arm/Makefile   |   1 +
 xen/drivers/acpi/arm/gen-iort.c | 101 ++++++++++++++++++++++++++++++++++++++++
 xen/include/acpi/gen-iort.h     |   6 +++
 4 files changed, 119 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index c74f4dd69d..f5d5e3d271 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -14,6 +14,7 @@
 #include <xen/acpi.h>
 #include <xen/warning.h>
 #include <acpi/actables.h>
+#include <acpi/gen-iort.h>
 #include <asm/device.h>
 #include <asm/setup.h>
 #include <asm/platform.h>
@@ -1799,7 +1800,7 @@ static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])
 
 static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
 {
-    size_t efi_size, acpi_size, madt_size;
+    size_t efi_size, acpi_size, madt_size, iort_size;
     u64 addr;
     struct acpi_table_rsdp *rsdp_tbl;
     struct acpi_table_header *table;
@@ -1840,6 +1841,15 @@ static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
     acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
 
     acpi_size += ROUNDUP(sizeof(struct acpi_table_rsdp), 8);
+
+    if( estimate_iort_size(&iort_size) )
+    {
+        printk("Unable to get hwdom iort size\n");
+        return -EINVAL;
+    }
+
+    acpi_size += ROUNDUP(iort_size, 8);
+
     d->arch.efi_acpi_len = PAGE_ALIGN(ROUNDUP(efi_size, 8)
                                       + ROUNDUP(acpi_size, 8));
 
diff --git a/xen/drivers/acpi/arm/Makefile b/xen/drivers/acpi/arm/Makefile
index 046fad5e3d..13f1a9159f 100644
--- a/xen/drivers/acpi/arm/Makefile
+++ b/xen/drivers/acpi/arm/Makefile
@@ -1 +1,2 @@
 obj-y = ridmap.o
+obj-y += gen-iort.o
diff --git a/xen/drivers/acpi/arm/gen-iort.c b/xen/drivers/acpi/arm/gen-iort.c
new file mode 100644
index 0000000000..3fc32959c6
--- /dev/null
+++ b/xen/drivers/acpi/arm/gen-iort.c
@@ -0,0 +1,101 @@
+/*
+ * xen/drivers/acpi/arm/gen-iort.c
+ *
+ * Code to generate IORT for hardware domain using the requesterId
+ * and deviceId map.
+ *
+ * Manish Jaggi <manish.jaggi@linaro.com>
+ * Copyright (c) 2018 Linaro.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <acpi/ridmap.h>
+#include <xen/acpi.h>
+
+/*
+ * Size of hardware domains iort is calulcated based on the number of
+ * mappings in the requesterId - deviceId mapping list.
+ */
+int estimate_iort_size(size_t *iort_size)
+{
+    int count = 0;
+    int pcirc_count = 0;
+    int itsg_count = 0;
+    uint64_t *pcirc_array;
+    uint64_t *itsg_array;
+    struct rid_deviceid_map *rmap;
+
+    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
+        count++;
+
+    pcirc_array = xzalloc_bytes(sizeof(uint64_t)*count);
+    if ( !pcirc_array )
+        return -ENOMEM;
+
+    itsg_array = xzalloc_bytes(sizeof(uint64_t)*count);
+    if ( !itsg_array )
+        return -ENOMEM;
+
+    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
+    {
+        int i = 0;
+
+        for (i=0; i <= pcirc_count; i++)
+        {
+            if ( pcirc_array[i] == (uint64_t)rmap->pcirc_node )
+                break;
+            if ( i == pcirc_count )
+            {
+                pcirc_array[i] = (uint64_t)rmap->pcirc_node;
+                pcirc_count++;
+                break;
+            }
+        }
+
+        for ( i=0; i <= itsg_count; i++ )
+        {
+            if ( itsg_array[i] == (uint64_t) rmap->its_node )
+                break;
+            if ( i == itsg_count )
+            {
+                itsg_array[i] = (uint64_t)rmap->its_node;
+                itsg_count++;
+                break;
+            }
+        }
+    }
+
+    /* Size of IORT
+     * = Size of IORT Table Header + Size of PCIRC Header Nodes +
+     *   Size of PCIRC nodes + Size of ITS Header nodes + Size of ITS Nodes
+     *   + Size of Idmap nodes
+     */
+    *iort_size = sizeof(struct acpi_table_iort) +
+                 pcirc_count*( (sizeof(struct acpi_iort_node) -1) +
+                               sizeof(struct acpi_iort_root_complex) ) +
+                 itsg_count*( (sizeof(struct acpi_iort_node) -1) +
+                               sizeof(struct acpi_iort_its_group) ) +
+                 count*( sizeof(struct acpi_iort_id_mapping) );
+
+    xfree(itsg_array);
+    xfree(pcirc_array);
+
+    return 0;
+}
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/acpi/gen-iort.h b/xen/include/acpi/gen-iort.h
new file mode 100644
index 0000000000..68e666fdce
--- /dev/null
+++ b/xen/include/acpi/gen-iort.h
@@ -0,0 +1,6 @@
+#ifndef _GEN_IORT_H
+#define _GEN_IORT_H
+
+int estimate_iort_size(size_t *iort_size);
+
+#endif
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 03/11] acpi: arm: Code to generate Hardware Domains IORT
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
  2018-01-02  9:27 ` [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid manish.jaggi
  2018-01-02  9:28 ` [RFC 02/11] acpi: arm: API to query estimated size of hardware domain's IORT manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-18 18:32   ` Julien Grall
  2018-01-02  9:28 ` [RFC 04/11] Import iort.c and acpi_iort.h manish.jaggi
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

Singed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
---
 xen/arch/arm/domain_build.c     |  28 +++++
 xen/drivers/acpi/arm/gen-iort.c | 253 +++++++++++++++++++++++++++++++++++++++-
 xen/include/acpi/gen-iort.h     |   1 +
 xen/include/asm-arm/acpi.h      |   1 +
 4 files changed, 282 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index f5d5e3d271..9831943147 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1654,6 +1654,8 @@ static int acpi_create_xsdt(struct domain *d, struct membank tbl_add[])
                            ACPI_SIG_FADT, tbl_add[TBL_FADT].start);
     acpi_xsdt_modify_entry(xsdt->table_offset_entry, entry_count,
                            ACPI_SIG_MADT, tbl_add[TBL_MADT].start);
+    acpi_xsdt_modify_entry(xsdt->table_offset_entry, entry_count,
+                           ACPI_SIG_IORT, tbl_add[TBL_IORT].start);
     xsdt->table_offset_entry[entry_count] = tbl_add[TBL_STAO].start;
 
     xsdt->header.length = table_size;
@@ -1704,6 +1706,28 @@ static int acpi_create_stao(struct domain *d, struct membank tbl_add[])
     return 0;
 }
 
+static int acpi_create_iort(struct domain *d, struct membank tbl_add[])
+{
+    struct acpi_table_iort *hwdom_table;
+    unsigned int size = 0;
+
+    tbl_add[TBL_IORT].start = d->arch.efi_acpi_gpa
+                              + acpi_get_table_offset(tbl_add, TBL_IORT);
+    hwdom_table = d->arch.efi_acpi_table
+                              + acpi_get_table_offset(tbl_add, TBL_IORT);
+
+    if ( prepare_iort(hwdom_table, &size) )
+    {
+        printk("Failed to write IORT table\n");
+        return -EINVAL;
+    }
+    printk("%s %d %d \r\n", __func__, __LINE__, size);
+
+    tbl_add[TBL_IORT].size = size;
+    printk("%s %d %d \r\n", __func__, __LINE__, size);
+    return 0;
+}
+
 static int acpi_create_madt(struct domain *d, struct membank tbl_add[])
 {
     struct acpi_table_header *table = NULL;
@@ -1899,6 +1923,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
     if ( rc != 0 )
         return rc;
 
+    rc = acpi_create_iort(d, tbl_add);
+    if ( rc != 0 )
+        return rc;
+
     rc = acpi_create_xsdt(d, tbl_add);
     if ( rc != 0 )
         return rc;
diff --git a/xen/drivers/acpi/arm/gen-iort.c b/xen/drivers/acpi/arm/gen-iort.c
index 3fc32959c6..f368000753 100644
--- a/xen/drivers/acpi/arm/gen-iort.c
+++ b/xen/drivers/acpi/arm/gen-iort.c
@@ -21,6 +21,257 @@
 #include <acpi/ridmap.h>
 #include <xen/acpi.h>
 
+/*
+ * Structure of Hardware domain's IORT
+ * -----------------------------------
+ *
+ * Below is the structure of the IORT which this code generates.
+ *
+ * [IORT Header]
+ * [ITS Group 1 ]
+ * [ITS Group N ]
+ * [PCIRC Node 1]
+ * [PCIRC IDMAP entry 1]
+ * [PCIRC IDMAP entry N]
+ * [PCIRC Node N]
+ *
+ * requesterId- deviceId mapping list poplated by parsing IORT is used
+ * to create nodes and idmaps.
+ * We have one small problem, how to resolve the its grooup node offset from
+ * the firmware iort to the ones in hardware domains IORT.
+ *
+ * Since the ITS group node pointer stored with the rid-devid map is used
+ * to populate the ITS Group nodes in the hardware domains' IORT.
+ * We create another map to save the offset of the ITS group node written
+ * in the hardware domain IORT with the ITS node pointer in the firmware IORT.
+ *
+ * This offset is later used when writing pcirc idmaps output_reference.
+ */
+struct its_node_offset_map
+{
+    struct acpi_iort_node *its_node;
+    unsigned int offset;
+    struct list_head entry;
+};
+struct list_head its_map_list;
+
+int set_its_node_offset(struct acpi_iort_node *its_node, unsigned int offset)
+{
+    struct its_node_offset_map *its_map;
+    list_for_each_entry(its_map, &its_map_list, entry)
+    {
+        if ( its_map->its_node == its_node )
+            return 0;
+    }
+
+    its_map = xzalloc(struct its_node_offset_map);
+    if ( !its_map )
+        return -ENOMEM;
+
+    its_map->its_node = its_node;
+    its_map->offset = offset;
+    list_add_tail(&its_map->entry, &its_map_list);
+
+    return 0;
+}
+/*
+ * This method would be used in write_pcirc_nodes when writing idmaps
+ */
+unsigned int get_its_node_offset(struct acpi_iort_node *its_node)
+{
+    struct its_node_offset_map *its_map;
+    list_for_each_entry(its_map, &its_map_list, entry)
+    {
+        if ( its_map->its_node == its_node )
+            return its_map->offset;
+    }
+
+    return 0;
+}
+
+void free_its_node_offset_list(void)
+{
+
+    struct its_node_offset_map *its_map;
+    list_for_each_entry(its_map, &its_map_list, entry)
+        xfree(its_map);
+
+    list_del(&its_map_list);
+}
+
+void write_its_group(u8 *iort, unsigned int *offset, unsigned int *num_nodes)
+{
+    struct rid_deviceid_map *rmap;
+    unsigned int of = *offset;
+    int n=0;
+    INIT_LIST_HEAD(&its_map_list);
+    /*
+     * rid_deviceid_map_list is iterated to get unique its group nodes
+     * Each unique ITS group node is written in hardware domains IORT
+     * by using some values from the firmware ITS group node.
+     */
+    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
+    {
+        struct acpi_iort_node *node;
+        struct acpi_iort_its_group *grp;
+        struct acpi_iort_its_group *fw_grp;
+
+        /* save its_node_offset_map in a list uniquely */
+        if ( !set_its_node_offset(rmap->its_node, of) )
+        {
+            node = (struct acpi_iort_node *) &iort[of];
+            grp = (struct acpi_iort_its_group *)(&node->node_data);
+
+            node->type = ACPI_IORT_NODE_ITS_GROUP;
+            node->length = sizeof(struct acpi_iort_node) +
+                           sizeof(struct acpi_iort_its_group) -
+                           sizeof(node->node_data);
+
+            node->revision = rmap->its_node->revision;
+            node->reserved = 0;
+            node->mapping_count = 0;
+            node->mapping_offset= 0;
+
+            fw_grp = (struct acpi_iort_its_group *)(&rmap->its_node->node_data);
+
+            grp->its_count = fw_grp->its_count;
+            grp->identifiers[0] = fw_grp->identifiers[0];
+
+            of += node->length;
+            n++;
+        }
+    }
+    *offset = of;
+    *num_nodes = n;
+}
+
+/* It is assumed that rid_map_devid is sorted by pcirc_nodes */
+void write_pcirc_nodes(u8 *iort, unsigned int *pos, unsigned int *num_nodes)
+{
+    struct acpi_iort_node *opcirc_node, *pcirc_node;
+    struct acpi_iort_node *hwdom_pcirc_node = NULL;
+    struct rid_deviceid_map *rmap;
+    struct acpi_iort_id_mapping *idmap;
+    int num_idmap = 0, n = 0;
+    unsigned int old_pos = *pos;
+
+    opcirc_node = NULL;
+    /* Iterate rid_map_devid list */
+    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
+    {
+        struct acpi_iort_root_complex *rc;
+        struct acpi_iort_root_complex *rc_fw;
+        int add_node = 0;
+        pcirc_node = rmap->pcirc_node;
+
+        if ( opcirc_node == NULL ) /* First entry */
+        {
+            add_node = 1;
+        }
+        else if ( opcirc_node != pcirc_node ) /* another pci_rc_node found*/
+        {
+            /* All the idmaps of a pcirc are written, now update node info*/
+            hwdom_pcirc_node->length = num_idmap *
+                                       sizeof(struct acpi_iort_id_mapping) +
+                                       sizeof(struct acpi_iort_node) +
+                                       sizeof(struct acpi_iort_root_complex) -
+                                       sizeof(pcirc_node->node_data);
+
+            hwdom_pcirc_node->mapping_count = num_idmap;
+            hwdom_pcirc_node->mapping_offset = sizeof(struct acpi_iort_node) +
+                                               sizeof(struct acpi_iort_root_complex) -
+                                               sizeof(pcirc_node->node_data);
+            old_pos += hwdom_pcirc_node->length;
+            add_node = 1;
+        }
+
+        if ( add_node ) /* create the pcirc node */
+        {
+            opcirc_node = pcirc_node;
+            hwdom_pcirc_node = (struct acpi_iort_node *)&iort[old_pos];
+            hwdom_pcirc_node->type = ACPI_IORT_NODE_PCI_ROOT_COMPLEX;
+            hwdom_pcirc_node->mapping_offset = sizeof(struct acpi_iort_node) +
+                                               sizeof(struct acpi_iort_root_complex) -
+                                               sizeof(hwdom_pcirc_node->node_data);
+
+            rc = (struct acpi_iort_root_complex *)
+                  &hwdom_pcirc_node->node_data;
+
+            rc_fw = (struct acpi_iort_root_complex *)
+                     &pcirc_node->node_data;
+
+            rc->pci_segment_number = rc_fw->pci_segment_number;
+            rc->ats_attribute = rc_fw->ats_attribute;
+            rc->memory_properties = rc_fw->memory_properties;
+
+            idmap = ACPI_ADD_PTR(struct acpi_iort_id_mapping,
+                                 hwdom_pcirc_node,
+                                 hwdom_pcirc_node->mapping_offset);
+            n++;
+            num_idmap = 0;
+        }
+
+        idmap->input_base = rmap->idmap.input_base;
+        idmap->id_count = rmap->idmap.id_count;
+        idmap->output_base = rmap->idmap.output_base;
+        idmap->output_reference = get_its_node_offset(rmap->its_node);
+        idmap->flags = 0;
+
+        idmap++;
+        num_idmap++;
+    }
+
+    if ( hwdom_pcirc_node ) /* if no further PCIRC nodes found */
+    {
+        /* All the idmaps of a pcirc are written, now update node info*/
+        hwdom_pcirc_node->length = num_idmap *
+                                   sizeof(struct acpi_iort_id_mapping) +
+                                   sizeof(struct acpi_iort_node) +
+                                   sizeof(struct acpi_iort_root_complex) -1;
+
+        hwdom_pcirc_node->mapping_count = num_idmap;
+        old_pos += hwdom_pcirc_node->length;
+    }
+
+    *pos = old_pos;
+    *num_nodes = n;
+}
+
+int prepare_iort(struct acpi_table_iort *hwdom_iort, unsigned int *iort_size)
+{
+    struct acpi_table_iort *fw_iort;
+    unsigned int num_nodes = 0;
+    unsigned int pos;
+
+    pos = sizeof(struct acpi_table_iort);
+
+    if ( acpi_get_table(ACPI_SIG_IORT, 0,
+         (struct acpi_table_header **)&fw_iort) )
+    {
+        printk("Failed to get IORT table\n");
+        return -ENODEV;
+    }
+
+    /* Write IORT header */
+    ACPI_MEMCPY(hwdom_iort, fw_iort, sizeof(struct acpi_table_iort));
+    hwdom_iort->node_offset = pos;
+    hwdom_iort->node_count = 0;
+
+    /* Write its group nodes */
+    write_its_group((u8*)hwdom_iort, &pos, &num_nodes);
+    hwdom_iort->node_count = num_nodes;
+    /* Write pcirc_nodes*/
+    write_pcirc_nodes((u8*)hwdom_iort, &pos, &num_nodes);
+    /* Update IORT Size in IORT header */
+    hwdom_iort->node_count += num_nodes;
+    hwdom_iort->header.length = pos;
+    hwdom_iort->header.checksum = 0; /* TODO */
+
+    *iort_size = hwdom_iort->header.length;
+
+    return 0;
+}
+
 /*
  * Size of hardware domains iort is calulcated based on the number of
  * mappings in the requesterId - deviceId mapping list.
@@ -49,7 +300,7 @@ int estimate_iort_size(size_t *iort_size)
     {
         int i = 0;
 
-        for (i=0; i <= pcirc_count; i++)
+        for ( i=0; i <= pcirc_count; i++ )
         {
             if ( pcirc_array[i] == (uint64_t)rmap->pcirc_node )
                 break;
diff --git a/xen/include/acpi/gen-iort.h b/xen/include/acpi/gen-iort.h
index 68e666fdce..4de31b7b9f 100644
--- a/xen/include/acpi/gen-iort.h
+++ b/xen/include/acpi/gen-iort.h
@@ -2,5 +2,6 @@
 #define _GEN_IORT_H
 
 int estimate_iort_size(size_t *iort_size);
+int prepare_iort(struct acpi_table_iort *hwdom_iort, unsigned int *iort_size);
 
 #endif
diff --git a/xen/include/asm-arm/acpi.h b/xen/include/asm-arm/acpi.h
index c183b6bb6e..f8b5254621 100644
--- a/xen/include/asm-arm/acpi.h
+++ b/xen/include/asm-arm/acpi.h
@@ -36,6 +36,7 @@ typedef enum {
     TBL_FADT,
     TBL_MADT,
     TBL_STAO,
+    TBL_IORT,
     TBL_XSDT,
     TBL_RSDP,
     TBL_EFIT,
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 04/11] Import iort.c and acpi_iort.h
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
                   ` (2 preceding siblings ...)
  2018-01-02  9:28 ` [RFC 03/11] acpi: arm: Code to generate Hardware Domains IORT manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-02  9:28 ` [RFC 05/11] Import fwnode.h from linux manish.jaggi
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

Import iort.c and acpi_iort.h from linux kernel tag v4.14

Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
---
 xen/drivers/acpi/arm/iort.c  | 1279 ++++++++++++++++++++++++++++++++++++++++++
 xen/include/acpi/acpi_iort.h |   57 ++
 2 files changed, 1336 insertions(+)

diff --git a/xen/drivers/acpi/arm/iort.c b/xen/drivers/acpi/arm/iort.c
new file mode 100644
index 0000000000..de56394dd1
--- /dev/null
+++ b/xen/drivers/acpi/arm/iort.c
@@ -0,0 +1,1279 @@
+/*
+ * Copyright (C) 2016, Semihalf
+ *	Author: Tomasz Nowicki <tn@semihalf.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * This file implements early detection/parsing of I/O mapping
+ * reported to OS through firmware via I/O Remapping Table (IORT)
+ * IORT document number: ARM DEN 0049A
+ */
+
+#define pr_fmt(fmt)	"ACPI: IORT: " fmt
+
+#include <linux/acpi_iort.h>
+#include <linux/iommu.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define IORT_TYPE_MASK(type)	(1 << (type))
+#define IORT_MSI_TYPE		(1 << ACPI_IORT_NODE_ITS_GROUP)
+#define IORT_IOMMU_TYPE		((1 << ACPI_IORT_NODE_SMMU) |	\
+				(1 << ACPI_IORT_NODE_SMMU_V3))
+
+/* Until ACPICA headers cover IORT rev. C */
+#ifndef ACPI_IORT_SMMU_V3_CAVIUM_CN99XX
+#define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX		0x2
+#endif
+
+struct iort_its_msi_chip {
+	struct list_head	list;
+	struct fwnode_handle	*fw_node;
+	u32			translation_id;
+};
+
+struct iort_fwnode {
+	struct list_head list;
+	struct acpi_iort_node *iort_node;
+	struct fwnode_handle *fwnode;
+};
+static LIST_HEAD(iort_fwnode_list);
+static DEFINE_SPINLOCK(iort_fwnode_lock);
+
+/**
+ * iort_set_fwnode() - Create iort_fwnode and use it to register
+ *		       iommu data in the iort_fwnode_list
+ *
+ * @node: IORT table node associated with the IOMMU
+ * @fwnode: fwnode associated with the IORT node
+ *
+ * Returns: 0 on success
+ *          <0 on failure
+ */
+static inline int iort_set_fwnode(struct acpi_iort_node *iort_node,
+				  struct fwnode_handle *fwnode)
+{
+	struct iort_fwnode *np;
+
+	np = kzalloc(sizeof(struct iort_fwnode), GFP_ATOMIC);
+
+	if (WARN_ON(!np))
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&np->list);
+	np->iort_node = iort_node;
+	np->fwnode = fwnode;
+
+	spin_lock(&iort_fwnode_lock);
+	list_add_tail(&np->list, &iort_fwnode_list);
+	spin_unlock(&iort_fwnode_lock);
+
+	return 0;
+}
+
+/**
+ * iort_get_fwnode() - Retrieve fwnode associated with an IORT node
+ *
+ * @node: IORT table node to be looked-up
+ *
+ * Returns: fwnode_handle pointer on success, NULL on failure
+ */
+static inline
+struct fwnode_handle *iort_get_fwnode(struct acpi_iort_node *node)
+{
+	struct iort_fwnode *curr;
+	struct fwnode_handle *fwnode = NULL;
+
+	spin_lock(&iort_fwnode_lock);
+	list_for_each_entry(curr, &iort_fwnode_list, list) {
+		if (curr->iort_node == node) {
+			fwnode = curr->fwnode;
+			break;
+		}
+	}
+	spin_unlock(&iort_fwnode_lock);
+
+	return fwnode;
+}
+
+/**
+ * iort_delete_fwnode() - Delete fwnode associated with an IORT node
+ *
+ * @node: IORT table node associated with fwnode to delete
+ */
+static inline void iort_delete_fwnode(struct acpi_iort_node *node)
+{
+	struct iort_fwnode *curr, *tmp;
+
+	spin_lock(&iort_fwnode_lock);
+	list_for_each_entry_safe(curr, tmp, &iort_fwnode_list, list) {
+		if (curr->iort_node == node) {
+			list_del(&curr->list);
+			kfree(curr);
+			break;
+		}
+	}
+	spin_unlock(&iort_fwnode_lock);
+}
+
+typedef acpi_status (*iort_find_node_callback)
+	(struct acpi_iort_node *node, void *context);
+
+/* Root pointer to the mapped IORT table */
+static struct acpi_table_header *iort_table;
+
+static LIST_HEAD(iort_msi_chip_list);
+static DEFINE_SPINLOCK(iort_msi_chip_lock);
+
+/**
+ * iort_register_domain_token() - register domain token and related ITS ID
+ * to the list from where we can get it back later on.
+ * @trans_id: ITS ID.
+ * @fw_node: Domain token.
+ *
+ * Returns: 0 on success, -ENOMEM if no memory when allocating list element
+ */
+int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node)
+{
+	struct iort_its_msi_chip *its_msi_chip;
+
+	its_msi_chip = kzalloc(sizeof(*its_msi_chip), GFP_KERNEL);
+	if (!its_msi_chip)
+		return -ENOMEM;
+
+	its_msi_chip->fw_node = fw_node;
+	its_msi_chip->translation_id = trans_id;
+
+	spin_lock(&iort_msi_chip_lock);
+	list_add(&its_msi_chip->list, &iort_msi_chip_list);
+	spin_unlock(&iort_msi_chip_lock);
+
+	return 0;
+}
+
+/**
+ * iort_deregister_domain_token() - Deregister domain token based on ITS ID
+ * @trans_id: ITS ID.
+ *
+ * Returns: none.
+ */
+void iort_deregister_domain_token(int trans_id)
+{
+	struct iort_its_msi_chip *its_msi_chip, *t;
+
+	spin_lock(&iort_msi_chip_lock);
+	list_for_each_entry_safe(its_msi_chip, t, &iort_msi_chip_list, list) {
+		if (its_msi_chip->translation_id == trans_id) {
+			list_del(&its_msi_chip->list);
+			kfree(its_msi_chip);
+			break;
+		}
+	}
+	spin_unlock(&iort_msi_chip_lock);
+}
+
+/**
+ * iort_find_domain_token() - Find domain token based on given ITS ID
+ * @trans_id: ITS ID.
+ *
+ * Returns: domain token when find on the list, NULL otherwise
+ */
+struct fwnode_handle *iort_find_domain_token(int trans_id)
+{
+	struct fwnode_handle *fw_node = NULL;
+	struct iort_its_msi_chip *its_msi_chip;
+
+	spin_lock(&iort_msi_chip_lock);
+	list_for_each_entry(its_msi_chip, &iort_msi_chip_list, list) {
+		if (its_msi_chip->translation_id == trans_id) {
+			fw_node = its_msi_chip->fw_node;
+			break;
+		}
+	}
+	spin_unlock(&iort_msi_chip_lock);
+
+	return fw_node;
+}
+
+static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type,
+					     iort_find_node_callback callback,
+					     void *context)
+{
+	struct acpi_iort_node *iort_node, *iort_end;
+	struct acpi_table_iort *iort;
+	int i;
+
+	if (!iort_table)
+		return NULL;
+
+	/* Get the first IORT node */
+	iort = (struct acpi_table_iort *)iort_table;
+	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				 iort->node_offset);
+	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+				iort_table->length);
+
+	for (i = 0; i < iort->node_count; i++) {
+		if (WARN_TAINT(iort_node >= iort_end, TAINT_FIRMWARE_WORKAROUND,
+			       "IORT node pointer overflows, bad table!\n"))
+			return NULL;
+
+		if (iort_node->type == type &&
+		    ACPI_SUCCESS(callback(iort_node, context)))
+			return iort_node;
+
+		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+					 iort_node->length);
+	}
+
+	return NULL;
+}
+
+static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
+					    void *context)
+{
+	struct device *dev = context;
+	acpi_status status = AE_NOT_FOUND;
+
+	if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) {
+		struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
+		struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
+		struct acpi_iort_named_component *ncomp;
+
+		if (!adev)
+			goto out;
+
+		status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf);
+		if (ACPI_FAILURE(status)) {
+			dev_warn(dev, "Can't get device full path name\n");
+			goto out;
+		}
+
+		ncomp = (struct acpi_iort_named_component *)node->node_data;
+		status = !strcmp(ncomp->device_name, buf.pointer) ?
+							AE_OK : AE_NOT_FOUND;
+		acpi_os_free(buf.pointer);
+	} else if (node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
+		struct acpi_iort_root_complex *pci_rc;
+		struct pci_bus *bus;
+
+		bus = to_pci_bus(dev);
+		pci_rc = (struct acpi_iort_root_complex *)node->node_data;
+
+		/*
+		 * It is assumed that PCI segment numbers maps one-to-one
+		 * with root complexes. Each segment number can represent only
+		 * one root complex.
+		 */
+		status = pci_rc->pci_segment_number == pci_domain_nr(bus) ?
+							AE_OK : AE_NOT_FOUND;
+	}
+out:
+	return status;
+}
+
+static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
+		       u32 *rid_out)
+{
+	/* Single mapping does not care for input id */
+	if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
+		if (type == ACPI_IORT_NODE_NAMED_COMPONENT ||
+		    type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
+			*rid_out = map->output_base;
+			return 0;
+		}
+
+		pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n",
+			map, type);
+		return -ENXIO;
+	}
+
+	if (rid_in < map->input_base ||
+	    (rid_in >= map->input_base + map->id_count))
+		return -ENXIO;
+
+	*rid_out = map->output_base + (rid_in - map->input_base);
+	return 0;
+}
+
+static
+struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
+					u32 *id_out, int index)
+{
+	struct acpi_iort_node *parent;
+	struct acpi_iort_id_mapping *map;
+
+	if (!node->mapping_offset || !node->mapping_count ||
+				     index >= node->mapping_count)
+		return NULL;
+
+	map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
+			   node->mapping_offset + index * sizeof(*map));
+
+	/* Firmware bug! */
+	if (!map->output_reference) {
+		pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
+		       node, node->type);
+		return NULL;
+	}
+
+	parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+			       map->output_reference);
+
+	if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
+		if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
+		    node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
+			*id_out = map->output_base;
+			return parent;
+		}
+	}
+
+	return NULL;
+}
+
+static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
+					       u32 id_in, u32 *id_out,
+					       u8 type_mask)
+{
+	u32 id = id_in;
+
+	/* Parse the ID mapping tree to find specified node type */
+	while (node) {
+		struct acpi_iort_id_mapping *map;
+		int i;
+
+		if (IORT_TYPE_MASK(node->type) & type_mask) {
+			if (id_out)
+				*id_out = id;
+			return node;
+		}
+
+		if (!node->mapping_offset || !node->mapping_count)
+			goto fail_map;
+
+		map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
+				   node->mapping_offset);
+
+		/* Firmware bug! */
+		if (!map->output_reference) {
+			pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
+			       node, node->type);
+			goto fail_map;
+		}
+
+		/* Do the ID translation */
+		for (i = 0; i < node->mapping_count; i++, map++) {
+			if (!iort_id_map(map, node->type, id, &id))
+				break;
+		}
+
+		if (i == node->mapping_count)
+			goto fail_map;
+
+		node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+				    map->output_reference);
+	}
+
+fail_map:
+	/* Map input ID to output ID unchanged on mapping failure */
+	if (id_out)
+		*id_out = id_in;
+
+	return NULL;
+}
+
+static
+struct acpi_iort_node *iort_node_map_platform_id(struct acpi_iort_node *node,
+						 u32 *id_out, u8 type_mask,
+						 int index)
+{
+	struct acpi_iort_node *parent;
+	u32 id;
+
+	/* step 1: retrieve the initial dev id */
+	parent = iort_node_get_id(node, &id, index);
+	if (!parent)
+		return NULL;
+
+	/*
+	 * optional step 2: map the initial dev id if its parent is not
+	 * the target type we want, map it again for the use cases such
+	 * as NC (named component) -> SMMU -> ITS. If the type is matched,
+	 * return the initial dev id and its parent pointer directly.
+	 */
+	if (!(IORT_TYPE_MASK(parent->type) & type_mask))
+		parent = iort_node_map_id(parent, id, id_out, type_mask);
+	else
+		if (id_out)
+			*id_out = id;
+
+	return parent;
+}
+
+static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
+{
+	struct pci_bus *pbus;
+
+	if (!dev_is_pci(dev))
+		return iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+				      iort_match_node_callback, dev);
+
+	/* Find a PCI root bus */
+	pbus = to_pci_dev(dev)->bus;
+	while (!pci_is_root_bus(pbus))
+		pbus = pbus->parent;
+
+	return iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
+			      iort_match_node_callback, &pbus->dev);
+}
+
+/**
+ * iort_msi_map_rid() - Map a MSI requester ID for a device
+ * @dev: The device for which the mapping is to be done.
+ * @req_id: The device requester ID.
+ *
+ * Returns: mapped MSI RID on success, input requester ID otherwise
+ */
+u32 iort_msi_map_rid(struct device *dev, u32 req_id)
+{
+	struct acpi_iort_node *node;
+	u32 dev_id;
+
+	node = iort_find_dev_node(dev);
+	if (!node)
+		return req_id;
+
+	iort_node_map_id(node, req_id, &dev_id, IORT_MSI_TYPE);
+	return dev_id;
+}
+
+/**
+ * iort_pmsi_get_dev_id() - Get the device id for a device
+ * @dev: The device for which the mapping is to be done.
+ * @dev_id: The device ID found.
+ *
+ * Returns: 0 for successful find a dev id, -ENODEV on error
+ */
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+	int i;
+	struct acpi_iort_node *node;
+
+	node = iort_find_dev_node(dev);
+	if (!node)
+		return -ENODEV;
+
+	for (i = 0; i < node->mapping_count; i++) {
+		if (iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, i))
+			return 0;
+	}
+
+	return -ENODEV;
+}
+
+/**
+ * iort_dev_find_its_id() - Find the ITS identifier for a device
+ * @dev: The device.
+ * @req_id: Device's requester ID
+ * @idx: Index of the ITS identifier list.
+ * @its_id: ITS identifier.
+ *
+ * Returns: 0 on success, appropriate error value otherwise
+ */
+static int iort_dev_find_its_id(struct device *dev, u32 req_id,
+				unsigned int idx, int *its_id)
+{
+	struct acpi_iort_its_group *its;
+	struct acpi_iort_node *node;
+
+	node = iort_find_dev_node(dev);
+	if (!node)
+		return -ENXIO;
+
+	node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE);
+	if (!node)
+		return -ENXIO;
+
+	/* Move to ITS specific data */
+	its = (struct acpi_iort_its_group *)node->node_data;
+	if (idx > its->its_count) {
+		dev_err(dev, "requested ITS ID index [%d] is greater than available [%d]\n",
+			idx, its->its_count);
+		return -ENXIO;
+	}
+
+	*its_id = its->identifiers[idx];
+	return 0;
+}
+
+/**
+ * iort_get_device_domain() - Find MSI domain related to a device
+ * @dev: The device.
+ * @req_id: Requester ID for the device.
+ *
+ * Returns: the MSI domain for this device, NULL otherwise
+ */
+struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
+{
+	struct fwnode_handle *handle;
+	int its_id;
+
+	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
+		return NULL;
+
+	handle = iort_find_domain_token(its_id);
+	if (!handle)
+		return NULL;
+
+	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
+}
+
+/**
+ * iort_get_platform_device_domain() - Find MSI domain related to a
+ * platform device
+ * @dev: the dev pointer associated with the platform device
+ *
+ * Returns: the MSI domain for this device, NULL otherwise
+ */
+static struct irq_domain *iort_get_platform_device_domain(struct device *dev)
+{
+	struct acpi_iort_node *node, *msi_parent;
+	struct fwnode_handle *iort_fwnode;
+	struct acpi_iort_its_group *its;
+	int i;
+
+	/* find its associated iort node */
+	node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+			      iort_match_node_callback, dev);
+	if (!node)
+		return NULL;
+
+	/* then find its msi parent node */
+	for (i = 0; i < node->mapping_count; i++) {
+		msi_parent = iort_node_map_platform_id(node, NULL,
+						       IORT_MSI_TYPE, i);
+		if (msi_parent)
+			break;
+	}
+
+	if (!msi_parent)
+		return NULL;
+
+	/* Move to ITS specific data */
+	its = (struct acpi_iort_its_group *)msi_parent->node_data;
+
+	iort_fwnode = iort_find_domain_token(its->identifiers[0]);
+	if (!iort_fwnode)
+		return NULL;
+
+	return irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI);
+}
+
+void acpi_configure_pmsi_domain(struct device *dev)
+{
+	struct irq_domain *msi_domain;
+
+	msi_domain = iort_get_platform_device_domain(dev);
+	if (msi_domain)
+		dev_set_msi_domain(dev, msi_domain);
+}
+
+static int __maybe_unused __get_pci_rid(struct pci_dev *pdev, u16 alias,
+					void *data)
+{
+	u32 *rid = data;
+
+	*rid = alias;
+	return 0;
+}
+
+static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
+			       struct fwnode_handle *fwnode,
+			       const struct iommu_ops *ops)
+{
+	int ret = iommu_fwspec_init(dev, fwnode, ops);
+
+	if (!ret)
+		ret = iommu_fwspec_add_ids(dev, &streamid, 1);
+
+	return ret;
+}
+
+static inline bool iort_iommu_driver_enabled(u8 type)
+{
+	switch (type) {
+	case ACPI_IORT_NODE_SMMU_V3:
+		return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
+	case ACPI_IORT_NODE_SMMU:
+		return IS_BUILTIN(CONFIG_ARM_SMMU);
+	default:
+		pr_warn("IORT node type %u does not describe an SMMU\n", type);
+		return false;
+	}
+}
+
+#ifdef CONFIG_IOMMU_API
+static inline
+const struct iommu_ops *iort_fwspec_iommu_ops(struct iommu_fwspec *fwspec)
+{
+	return (fwspec && fwspec->ops) ? fwspec->ops : NULL;
+}
+
+static inline
+int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev)
+{
+	int err = 0;
+
+	if (ops->add_device && dev->bus && !dev->iommu_group)
+		err = ops->add_device(dev);
+
+	return err;
+}
+#else
+static inline
+const struct iommu_ops *iort_fwspec_iommu_ops(struct iommu_fwspec *fwspec)
+{ return NULL; }
+static inline
+int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev)
+{ return 0; }
+#endif
+
+static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
+			    u32 streamid)
+{
+	const struct iommu_ops *ops;
+	struct fwnode_handle *iort_fwnode;
+
+	if (!node)
+		return -ENODEV;
+
+	iort_fwnode = iort_get_fwnode(node);
+	if (!iort_fwnode)
+		return -ENODEV;
+
+	/*
+	 * If the ops look-up fails, this means that either
+	 * the SMMU drivers have not been probed yet or that
+	 * the SMMU drivers are not built in the kernel;
+	 * Depending on whether the SMMU drivers are built-in
+	 * in the kernel or not, defer the IOMMU configuration
+	 * or just abort it.
+	 */
+	ops = iommu_ops_from_fwnode(iort_fwnode);
+	if (!ops)
+		return iort_iommu_driver_enabled(node->type) ?
+		       -EPROBE_DEFER : -ENODEV;
+
+	return arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
+}
+
+struct iort_pci_alias_info {
+	struct device *dev;
+	struct acpi_iort_node *node;
+};
+
+static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
+{
+	struct iort_pci_alias_info *info = data;
+	struct acpi_iort_node *parent;
+	u32 streamid;
+
+	parent = iort_node_map_id(info->node, alias, &streamid,
+				  IORT_IOMMU_TYPE);
+	return iort_iommu_xlate(info->dev, parent, streamid);
+}
+
+static int nc_dma_get_range(struct device *dev, u64 *size)
+{
+	struct acpi_iort_node *node;
+	struct acpi_iort_named_component *ncomp;
+
+	node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+			      iort_match_node_callback, dev);
+	if (!node)
+		return -ENODEV;
+
+	ncomp = (struct acpi_iort_named_component *)node->node_data;
+
+	*size = ncomp->memory_address_limit >= 64 ? U64_MAX :
+			1ULL<<ncomp->memory_address_limit;
+
+	return 0;
+}
+
+/**
+ * iort_dma_setup() - Set-up device DMA parameters.
+ *
+ * @dev: device to configure
+ * @dma_addr: device DMA address result pointer
+ * @size: DMA range size result pointer
+ */
+void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
+{
+	u64 mask, dmaaddr = 0, size = 0, offset = 0;
+	int ret, msb;
+
+	/*
+	 * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
+	 * setup the correct supported mask.
+	 */
+	if (!dev->coherent_dma_mask)
+		dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+	/*
+	 * Set it to coherent_dma_mask by default if the architecture
+	 * code has not set it.
+	 */
+	if (!dev->dma_mask)
+		dev->dma_mask = &dev->coherent_dma_mask;
+
+	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
+
+	if (dev_is_pci(dev))
+		ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
+	else
+		ret = nc_dma_get_range(dev, &size);
+
+	if (!ret) {
+		msb = fls64(dmaaddr + size - 1);
+		/*
+		 * Round-up to the power-of-two mask or set
+		 * the mask to the whole 64-bit address space
+		 * in case the DMA region covers the full
+		 * memory window.
+		 */
+		mask = msb == 64 ? U64_MAX : (1ULL << msb) - 1;
+		/*
+		 * Limit coherent and dma mask based on size
+		 * retrieved from firmware.
+		 */
+		dev->coherent_dma_mask = mask;
+		*dev->dma_mask = mask;
+	}
+
+	*dma_addr = dmaaddr;
+	*dma_size = size;
+
+	dev->dma_pfn_offset = PFN_DOWN(offset);
+	dev_dbg(dev, "dma_pfn_offset(%#08llx)\n", offset);
+}
+
+/**
+ * iort_iommu_configure - Set-up IOMMU configuration for a device.
+ *
+ * @dev: device to configure
+ *
+ * Returns: iommu_ops pointer on configuration success
+ *          NULL on configuration failure
+ */
+const struct iommu_ops *iort_iommu_configure(struct device *dev)
+{
+	struct acpi_iort_node *node, *parent;
+	const struct iommu_ops *ops;
+	u32 streamid = 0;
+	int err = -ENODEV;
+
+	/*
+	 * If we already translated the fwspec there
+	 * is nothing left to do, return the iommu_ops.
+	 */
+	ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
+	if (ops)
+		return ops;
+
+	if (dev_is_pci(dev)) {
+		struct pci_bus *bus = to_pci_dev(dev)->bus;
+		struct iort_pci_alias_info info = { .dev = dev };
+
+		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
+				      iort_match_node_callback, &bus->dev);
+		if (!node)
+			return NULL;
+
+		info.node = node;
+		err = pci_for_each_dma_alias(to_pci_dev(dev),
+					     iort_pci_iommu_init, &info);
+	} else {
+		int i = 0;
+
+		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+				      iort_match_node_callback, dev);
+		if (!node)
+			return NULL;
+
+		do {
+			parent = iort_node_map_platform_id(node, &streamid,
+							   IORT_IOMMU_TYPE,
+							   i++);
+
+			if (parent)
+				err = iort_iommu_xlate(dev, parent, streamid);
+		} while (parent && !err);
+	}
+
+	/*
+	 * If we have reason to believe the IOMMU driver missed the initial
+	 * add_device callback for dev, replay it to get things in order.
+	 */
+	if (!err) {
+		ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
+		err = iort_add_device_replay(ops, dev);
+	}
+
+	/* Ignore all other errors apart from EPROBE_DEFER */
+	if (err == -EPROBE_DEFER) {
+		ops = ERR_PTR(err);
+	} else if (err) {
+		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
+		ops = NULL;
+	}
+
+	return ops;
+}
+
+static void __init acpi_iort_register_irq(int hwirq, const char *name,
+					  int trigger,
+					  struct resource *res)
+{
+	int irq = acpi_register_gsi(NULL, hwirq, trigger,
+				    ACPI_ACTIVE_HIGH);
+
+	if (irq <= 0) {
+		pr_err("could not register gsi hwirq %d name [%s]\n", hwirq,
+								      name);
+		return;
+	}
+
+	res->start = irq;
+	res->end = irq;
+	res->flags = IORESOURCE_IRQ;
+	res->name = name;
+}
+
+static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node)
+{
+	struct acpi_iort_smmu_v3 *smmu;
+	/* Always present mem resource */
+	int num_res = 1;
+
+	/* Retrieve SMMUv3 specific data */
+	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+	if (smmu->event_gsiv)
+		num_res++;
+
+	if (smmu->pri_gsiv)
+		num_res++;
+
+	if (smmu->gerr_gsiv)
+		num_res++;
+
+	if (smmu->sync_gsiv)
+		num_res++;
+
+	return num_res;
+}
+
+static bool arm_smmu_v3_is_combined_irq(struct acpi_iort_smmu_v3 *smmu)
+{
+	/*
+	 * Cavium ThunderX2 implementation doesn't not support unique
+	 * irq line. Use single irq line for all the SMMUv3 interrupts.
+	 */
+	if (smmu->model != ACPI_IORT_SMMU_V3_CAVIUM_CN99XX)
+		return false;
+
+	/*
+	 * ThunderX2 doesn't support MSIs from the SMMU, so we're checking
+	 * SPI numbers here.
+	 */
+	return smmu->event_gsiv == smmu->pri_gsiv &&
+	       smmu->event_gsiv == smmu->gerr_gsiv &&
+	       smmu->event_gsiv == smmu->sync_gsiv;
+}
+
+static unsigned long arm_smmu_v3_resource_size(struct acpi_iort_smmu_v3 *smmu)
+{
+	/*
+	 * Override the size, for Cavium ThunderX2 implementation
+	 * which doesn't support the page 1 SMMU register space.
+	 */
+	if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX)
+		return SZ_64K;
+
+	return SZ_128K;
+}
+
+static void __init arm_smmu_v3_init_resources(struct resource *res,
+					      struct acpi_iort_node *node)
+{
+	struct acpi_iort_smmu_v3 *smmu;
+	int num_res = 0;
+
+	/* Retrieve SMMUv3 specific data */
+	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+	res[num_res].start = smmu->base_address;
+	res[num_res].end = smmu->base_address +
+				arm_smmu_v3_resource_size(smmu) - 1;
+	res[num_res].flags = IORESOURCE_MEM;
+
+	num_res++;
+	if (arm_smmu_v3_is_combined_irq(smmu)) {
+		if (smmu->event_gsiv)
+			acpi_iort_register_irq(smmu->event_gsiv, "combined",
+					       ACPI_EDGE_SENSITIVE,
+					       &res[num_res++]);
+	} else {
+
+		if (smmu->event_gsiv)
+			acpi_iort_register_irq(smmu->event_gsiv, "eventq",
+					       ACPI_EDGE_SENSITIVE,
+					       &res[num_res++]);
+
+		if (smmu->pri_gsiv)
+			acpi_iort_register_irq(smmu->pri_gsiv, "priq",
+					       ACPI_EDGE_SENSITIVE,
+					       &res[num_res++]);
+
+		if (smmu->gerr_gsiv)
+			acpi_iort_register_irq(smmu->gerr_gsiv, "gerror",
+					       ACPI_EDGE_SENSITIVE,
+					       &res[num_res++]);
+
+		if (smmu->sync_gsiv)
+			acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync",
+					       ACPI_EDGE_SENSITIVE,
+					       &res[num_res++]);
+	}
+}
+
+static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
+{
+	struct acpi_iort_smmu_v3 *smmu;
+
+	/* Retrieve SMMUv3 specific data */
+	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+
+	return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
+}
+
+#if defined(CONFIG_ACPI_NUMA) && defined(ACPI_IORT_SMMU_V3_PXM_VALID)
+/*
+ * set numa proximity domain for smmuv3 device
+ */
+static void  __init arm_smmu_v3_set_proximity(struct device *dev,
+					      struct acpi_iort_node *node)
+{
+	struct acpi_iort_smmu_v3 *smmu;
+
+	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
+	if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) {
+		set_dev_node(dev, acpi_map_pxm_to_node(smmu->pxm));
+		pr_info("SMMU-v3[%llx] Mapped to Proximity domain %d\n",
+			smmu->base_address,
+			smmu->pxm);
+	}
+}
+#else
+#define arm_smmu_v3_set_proximity NULL
+#endif
+
+static int __init arm_smmu_count_resources(struct acpi_iort_node *node)
+{
+	struct acpi_iort_smmu *smmu;
+
+	/* Retrieve SMMU specific data */
+	smmu = (struct acpi_iort_smmu *)node->node_data;
+
+	/*
+	 * Only consider the global fault interrupt and ignore the
+	 * configuration access interrupt.
+	 *
+	 * MMIO address and global fault interrupt resources are always
+	 * present so add them to the context interrupt count as a static
+	 * value.
+	 */
+	return smmu->context_interrupt_count + 2;
+}
+
+static void __init arm_smmu_init_resources(struct resource *res,
+					   struct acpi_iort_node *node)
+{
+	struct acpi_iort_smmu *smmu;
+	int i, hw_irq, trigger, num_res = 0;
+	u64 *ctx_irq, *glb_irq;
+
+	/* Retrieve SMMU specific data */
+	smmu = (struct acpi_iort_smmu *)node->node_data;
+
+	res[num_res].start = smmu->base_address;
+	res[num_res].end = smmu->base_address + smmu->span - 1;
+	res[num_res].flags = IORESOURCE_MEM;
+	num_res++;
+
+	glb_irq = ACPI_ADD_PTR(u64, node, smmu->global_interrupt_offset);
+	/* Global IRQs */
+	hw_irq = IORT_IRQ_MASK(glb_irq[0]);
+	trigger = IORT_IRQ_TRIGGER_MASK(glb_irq[0]);
+
+	acpi_iort_register_irq(hw_irq, "arm-smmu-global", trigger,
+				     &res[num_res++]);
+
+	/* Context IRQs */
+	ctx_irq = ACPI_ADD_PTR(u64, node, smmu->context_interrupt_offset);
+	for (i = 0; i < smmu->context_interrupt_count; i++) {
+		hw_irq = IORT_IRQ_MASK(ctx_irq[i]);
+		trigger = IORT_IRQ_TRIGGER_MASK(ctx_irq[i]);
+
+		acpi_iort_register_irq(hw_irq, "arm-smmu-context", trigger,
+				       &res[num_res++]);
+	}
+}
+
+static bool __init arm_smmu_is_coherent(struct acpi_iort_node *node)
+{
+	struct acpi_iort_smmu *smmu;
+
+	/* Retrieve SMMU specific data */
+	smmu = (struct acpi_iort_smmu *)node->node_data;
+
+	return smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK;
+}
+
+struct iort_iommu_config {
+	const char *name;
+	int (*iommu_init)(struct acpi_iort_node *node);
+	bool (*iommu_is_coherent)(struct acpi_iort_node *node);
+	int (*iommu_count_resources)(struct acpi_iort_node *node);
+	void (*iommu_init_resources)(struct resource *res,
+				     struct acpi_iort_node *node);
+	void (*iommu_set_proximity)(struct device *dev,
+				    struct acpi_iort_node *node);
+};
+
+static const struct iort_iommu_config iort_arm_smmu_v3_cfg __initconst = {
+	.name = "arm-smmu-v3",
+	.iommu_is_coherent = arm_smmu_v3_is_coherent,
+	.iommu_count_resources = arm_smmu_v3_count_resources,
+	.iommu_init_resources = arm_smmu_v3_init_resources,
+	.iommu_set_proximity = arm_smmu_v3_set_proximity,
+};
+
+static const struct iort_iommu_config iort_arm_smmu_cfg __initconst = {
+	.name = "arm-smmu",
+	.iommu_is_coherent = arm_smmu_is_coherent,
+	.iommu_count_resources = arm_smmu_count_resources,
+	.iommu_init_resources = arm_smmu_init_resources
+};
+
+static __init
+const struct iort_iommu_config *iort_get_iommu_cfg(struct acpi_iort_node *node)
+{
+	switch (node->type) {
+	case ACPI_IORT_NODE_SMMU_V3:
+		return &iort_arm_smmu_v3_cfg;
+	case ACPI_IORT_NODE_SMMU:
+		return &iort_arm_smmu_cfg;
+	default:
+		return NULL;
+	}
+}
+
+/**
+ * iort_add_smmu_platform_device() - Allocate a platform device for SMMU
+ * @node: Pointer to SMMU ACPI IORT node
+ *
+ * Returns: 0 on success, <0 failure
+ */
+static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node)
+{
+	struct fwnode_handle *fwnode;
+	struct platform_device *pdev;
+	struct resource *r;
+	enum dev_dma_attr attr;
+	int ret, count;
+	const struct iort_iommu_config *ops = iort_get_iommu_cfg(node);
+
+	if (!ops)
+		return -ENODEV;
+
+	pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO);
+	if (!pdev)
+		return -ENOMEM;
+
+	if (ops->iommu_set_proximity)
+		ops->iommu_set_proximity(&pdev->dev, node);
+
+	count = ops->iommu_count_resources(node);
+
+	r = kcalloc(count, sizeof(*r), GFP_KERNEL);
+	if (!r) {
+		ret = -ENOMEM;
+		goto dev_put;
+	}
+
+	ops->iommu_init_resources(r, node);
+
+	ret = platform_device_add_resources(pdev, r, count);
+	/*
+	 * Resources are duplicated in platform_device_add_resources,
+	 * free their allocated memory
+	 */
+	kfree(r);
+
+	if (ret)
+		goto dev_put;
+
+	/*
+	 * Add a copy of IORT node pointer to platform_data to
+	 * be used to retrieve IORT data information.
+	 */
+	ret = platform_device_add_data(pdev, &node, sizeof(node));
+	if (ret)
+		goto dev_put;
+
+	/*
+	 * We expect the dma masks to be equivalent for
+	 * all SMMUs set-ups
+	 */
+	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+
+	fwnode = iort_get_fwnode(node);
+
+	if (!fwnode) {
+		ret = -ENODEV;
+		goto dev_put;
+	}
+
+	pdev->dev.fwnode = fwnode;
+
+	attr = ops->iommu_is_coherent(node) ?
+			     DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
+
+	/* Configure DMA for the page table walker */
+	acpi_dma_configure(&pdev->dev, attr);
+
+	ret = platform_device_add(pdev);
+	if (ret)
+		goto dma_deconfigure;
+
+	return 0;
+
+dma_deconfigure:
+	acpi_dma_deconfigure(&pdev->dev);
+dev_put:
+	platform_device_put(pdev);
+
+	return ret;
+}
+
+static bool __init iort_enable_acs(struct acpi_iort_node *iort_node)
+{
+	if (iort_node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
+		struct acpi_iort_node *parent;
+		struct acpi_iort_id_mapping *map;
+		int i;
+
+		map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, iort_node,
+				   iort_node->mapping_offset);
+
+		for (i = 0; i < iort_node->mapping_count; i++, map++) {
+			if (!map->output_reference)
+				continue;
+
+			parent = ACPI_ADD_PTR(struct acpi_iort_node,
+					iort_table,  map->output_reference);
+			/*
+			 * If we detect a RC->SMMU mapping, make sure
+			 * we enable ACS on the system.
+			 */
+			if ((parent->type == ACPI_IORT_NODE_SMMU) ||
+				(parent->type == ACPI_IORT_NODE_SMMU_V3)) {
+				pci_request_acs();
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+static void __init iort_init_platform_devices(void)
+{
+	struct acpi_iort_node *iort_node, *iort_end;
+	struct acpi_table_iort *iort;
+	struct fwnode_handle *fwnode;
+	int i, ret;
+	bool acs_enabled = false;
+
+	/*
+	 * iort_table and iort both point to the start of IORT table, but
+	 * have different struct types
+	 */
+	iort = (struct acpi_table_iort *)iort_table;
+
+	/* Get the first IORT node */
+	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				 iort->node_offset);
+	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				iort_table->length);
+
+	for (i = 0; i < iort->node_count; i++) {
+		if (iort_node >= iort_end) {
+			pr_err("iort node pointer overflows, bad table\n");
+			return;
+		}
+
+		if (!acs_enabled)
+			acs_enabled = iort_enable_acs(iort_node);
+
+		if ((iort_node->type == ACPI_IORT_NODE_SMMU) ||
+			(iort_node->type == ACPI_IORT_NODE_SMMU_V3)) {
+
+			fwnode = acpi_alloc_fwnode_static();
+			if (!fwnode)
+				return;
+
+			iort_set_fwnode(iort_node, fwnode);
+
+			ret = iort_add_smmu_platform_device(iort_node);
+			if (ret) {
+				iort_delete_fwnode(iort_node);
+				acpi_free_fwnode_static(fwnode);
+				return;
+			}
+		}
+
+		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+					 iort_node->length);
+	}
+}
+
+void __init acpi_iort_init(void)
+{
+	acpi_status status;
+
+	status = acpi_get_table(ACPI_SIG_IORT, 0, &iort_table);
+	if (ACPI_FAILURE(status)) {
+		if (status != AE_NOT_FOUND) {
+			const char *msg = acpi_format_exception(status);
+
+			pr_err("Failed to get table, %s\n", msg);
+		}
+
+		return;
+	}
+
+	iort_init_platform_devices();
+}
diff --git a/xen/include/acpi/acpi_iort.h b/xen/include/acpi/acpi_iort.h
new file mode 100644
index 0000000000..8d3f0bf803
--- /dev/null
+++ b/xen/include/acpi/acpi_iort.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016, Semihalf
+ *	Author: Tomasz Nowicki <tn@semihalf.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#ifndef __ACPI_IORT_H__
+#define __ACPI_IORT_H__
+
+#include <linux/acpi.h>
+#include <linux/fwnode.h>
+#include <linux/irqdomain.h>
+
+#define IORT_IRQ_MASK(irq)		(irq & 0xffffffffULL)
+#define IORT_IRQ_TRIGGER_MASK(irq)	((irq >> 32) & 0xffffffffULL)
+
+int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node);
+void iort_deregister_domain_token(int trans_id);
+struct fwnode_handle *iort_find_domain_token(int trans_id);
+#ifdef CONFIG_ACPI_IORT
+void acpi_iort_init(void);
+u32 iort_msi_map_rid(struct device *dev, u32 req_id);
+struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
+void acpi_configure_pmsi_domain(struct device *dev);
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
+/* IOMMU interface */
+void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size);
+const struct iommu_ops *iort_iommu_configure(struct device *dev);
+#else
+static inline void acpi_iort_init(void) { }
+static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
+{ return req_id; }
+static inline struct irq_domain *iort_get_device_domain(struct device *dev,
+							u32 req_id)
+{ return NULL; }
+static inline void acpi_configure_pmsi_domain(struct device *dev) { }
+/* IOMMU interface */
+static inline void iort_dma_setup(struct device *dev, u64 *dma_addr,
+				  u64 *size) { }
+static inline
+const struct iommu_ops *iort_iommu_configure(struct device *dev)
+{ return NULL; }
+#endif
+
+#endif /* __ACPI_IORT_H__ */
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 05/11] Import fwnode.h from linux
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
                   ` (3 preceding siblings ...)
  2018-01-02  9:28 ` [RFC 04/11] Import iort.c and acpi_iort.h manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-02  9:28 ` [RFC 06/11] fwnode xen spacific changes manish.jaggi
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

Import fwnode.h from linux kernel tag v4.14

Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
---
 xen/include/xen/fwnode.h | 125 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/xen/include/xen/fwnode.h b/xen/include/xen/fwnode.h
new file mode 100644
index 0000000000..af186a9dc6
--- /dev/null
+++ b/xen/include/xen/fwnode.h
@@ -0,0 +1,125 @@
+/*
+ * fwnode.h - Firmware device node object handle type definition.
+ *
+ * Copyright (C) 2015, Intel Corporation
+ * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.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.
+ */
+
+#ifndef _LINUX_FWNODE_H_
+#define _LINUX_FWNODE_H_
+
+#include <xen/types.h>
+
+struct fwnode_operations;
+
+struct fwnode_handle {
+	struct fwnode_handle *secondary;
+	const struct fwnode_operations *ops;
+};
+
+/**
+ * struct fwnode_endpoint - Fwnode graph endpoint
+ * @port: Port number
+ * @id: Endpoint id
+ * @local_fwnode: reference to the related fwnode
+ */
+struct fwnode_endpoint {
+	unsigned int port;
+	unsigned int id;
+	const struct fwnode_handle *local_fwnode;
+};
+
+#define NR_FWNODE_REFERENCE_ARGS	8
+
+/**
+ * struct fwnode_reference_args - Fwnode reference with additional arguments
+ * @fwnode:- A reference to the base fwnode
+ * @nargs: Number of elements in @args array
+ * @args: Integer arguments on the fwnode
+ */
+struct fwnode_reference_args {
+	struct fwnode_handle *fwnode;
+	unsigned int nargs;
+	unsigned int args[NR_FWNODE_REFERENCE_ARGS];
+};
+
+/**
+ * struct fwnode_operations - Operations for fwnode interface
+ * @get: Get a reference to an fwnode.
+ * @put: Put a reference to an fwnode.
+ * @property_present: Return true if a property is present.
+ * @property_read_integer_array: Read an array of integer properties. Return
+ *				 zero on success, a negative error code
+ *				 otherwise.
+ * @property_read_string_array: Read an array of string properties. Return zero
+ *				on success, a negative error code otherwise.
+ * @get_parent: Return the parent of an fwnode.
+ * @get_next_child_node: Return the next child node in an iteration.
+ * @get_named_child_node: Return a child node with a given name.
+ * @get_reference_args: Return a reference pointed to by a property, with args
+ * @graph_get_next_endpoint: Return an endpoint node in an iteration.
+ * @graph_get_remote_endpoint: Return the remote endpoint node of a local
+ *			       endpoint node.
+ * @graph_get_port_parent: Return the parent node of a port node.
+ * @graph_parse_endpoint: Parse endpoint for port and endpoint id.
+ */
+struct fwnode_operations {
+	void (*get)(struct fwnode_handle *fwnode);
+	void (*put)(struct fwnode_handle *fwnode);
+	bool (*device_is_available)(const struct fwnode_handle *fwnode);
+	bool (*property_present)(const struct fwnode_handle *fwnode,
+				 const char *propname);
+	int (*property_read_int_array)(const struct fwnode_handle *fwnode,
+				       const char *propname,
+				       unsigned int elem_size, void *val,
+				       size_t nval);
+	int
+	(*property_read_string_array)(const struct fwnode_handle *fwnode_handle,
+				      const char *propname, const char **val,
+				      size_t nval);
+	struct fwnode_handle *(*get_parent)(const struct fwnode_handle *fwnode);
+	struct fwnode_handle *
+	(*get_next_child_node)(const struct fwnode_handle *fwnode,
+			       struct fwnode_handle *child);
+	struct fwnode_handle *
+	(*get_named_child_node)(const struct fwnode_handle *fwnode,
+				const char *name);
+	int (*get_reference_args)(const struct fwnode_handle *fwnode,
+				  const char *prop, const char *nargs_prop,
+				  unsigned int nargs, unsigned int index,
+				  struct fwnode_reference_args *args);
+	struct fwnode_handle *
+	(*graph_get_next_endpoint)(const struct fwnode_handle *fwnode,
+				   struct fwnode_handle *prev);
+	struct fwnode_handle *
+	(*graph_get_remote_endpoint)(const struct fwnode_handle *fwnode);
+	struct fwnode_handle *
+	(*graph_get_port_parent)(struct fwnode_handle *fwnode);
+	int (*graph_parse_endpoint)(const struct fwnode_handle *fwnode,
+				    struct fwnode_endpoint *endpoint);
+};
+
+#define fwnode_has_op(fwnode, op)				\
+	((fwnode) && (fwnode)->ops && (fwnode)->ops->op)
+#define fwnode_call_int_op(fwnode, op, ...)				\
+	(fwnode ? (fwnode_has_op(fwnode, op) ?				\
+		   (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : -ENXIO) : \
+	 -EINVAL)
+#define fwnode_call_bool_op(fwnode, op, ...)				\
+	(fwnode ? (fwnode_has_op(fwnode, op) ?				\
+		   (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : false) : \
+	 false)
+#define fwnode_call_ptr_op(fwnode, op, ...)		\
+	(fwnode_has_op(fwnode, op) ?			\
+	 (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : NULL)
+#define fwnode_call_void_op(fwnode, op, ...)				\
+	do {								\
+		if (fwnode_has_op(fwnode, op))				\
+			(fwnode)->ops->op(fwnode, ## __VA_ARGS__);	\
+	} while (false)
+
+#endif
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 06/11] fwnode xen spacific changes
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
                   ` (4 preceding siblings ...)
  2018-01-02  9:28 ` [RFC 05/11] Import fwnode.h from linux manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-18 18:51   ` Julien Grall
  2018-01-02  9:28 ` [RFC 07/11] Add kernel helper functions manish.jaggi
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

Merge few more changes from linux kernel code (v4.14) into iommu.c
Modify code specifc to xen.

Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
---
 xen/drivers/passthrough/iommu.c | 75 +++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/device.h    | 11 ++++--
 xen/include/xen/iommu.h         | 22 ++++++++++++
 3 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
index 1aecf7cf34..408f44106d 100644
--- a/xen/drivers/passthrough/iommu.c
+++ b/xen/drivers/passthrough/iommu.c
@@ -13,6 +13,7 @@
  */
 
 #include <xen/sched.h>
+#include <xen/fwnode.h>
 #include <xen/iommu.h>
 #include <xen/paging.h>
 #include <xen/guest_access.h>
@@ -507,6 +508,80 @@ static void iommu_dump_p2m_table(unsigned char key)
     }
 }
 
+/**
+ * fwnode_handle_put - Drop reference to a device node
+ * @fwnode: Pointer to the device node to drop the reference to.
+ *
+ * This has to be used when terminating device_for_each_child_node() iteration
+ * with break or return to prevent stale device node references from being left
+ * behind.
+ */
+void fwnode_handle_put(struct fwnode_handle *fwnode)
+{
+        fwnode_call_void_op(fwnode, put);
+}
+
+const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
+{
+       return iommu_get_ops();
+}
+
+int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
+                     const struct iommu_ops *ops)
+{
+       struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+
+       if (fwspec)
+               return ops == fwspec->ops ? 0 : -EINVAL;
+
+       fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
+       if (!fwspec)
+               return -ENOMEM;
+#if 0
+       of_node_get(to_of_node(iommu_fwnode));
+#endif
+       fwspec->iommu_fwnode = iommu_fwnode;
+       fwspec->ops = ops;
+       dev->iommu_fwspec = fwspec;
+       return 0;
+}
+
+void iommu_fwspec_free(struct device *dev)
+{
+       struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+
+       if (fwspec) {
+               fwnode_handle_put(fwspec->iommu_fwnode);
+               kfree(fwspec);
+               dev->iommu_fwspec = NULL;
+       }
+}
+
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
+{
+  struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+        size_t size;
+        int i;
+
+        if (!fwspec)
+                return -EINVAL;
+
+        size = offsetof(struct iommu_fwspec, ids[fwspec->num_ids + num_ids]);
+        if (size > sizeof(*fwspec)) {
+                //TBD: fwspec = krealloc(dev->iommu_fwspec, size, GFP_KERNEL);
+                if (!fwspec)
+                        return -ENOMEM;
+
+                dev->iommu_fwspec = fwspec;
+        }
+
+        for (i = 0; i < num_ids; i++)
+                fwspec->ids[fwspec->num_ids + i] = ids[i];
+
+        fwspec->num_ids += num_ids;
+        return 0;
+
+}
 /*
  * Local variables:
  * mode: C
diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
index 6734ae8efd..f78482ca0c 100644
--- a/xen/include/asm-arm/device.h
+++ b/xen/include/asm-arm/device.h
@@ -6,6 +6,8 @@
 enum device_type
 {
     DEV_DT,
+    DEV_ACPI,
+    DEV_PCI,
 };
 
 struct dev_archdata {
@@ -18,8 +20,13 @@ struct device
     enum device_type type;
 #ifdef CONFIG_HAS_DEVICE_TREE
     struct dt_device_node *of_node; /* Used by drivers imported from Linux */
+#endif
+#ifdef CONFIG_ACPI
+    void *acpi_node;
 #endif
     struct dev_archdata archdata;
+    struct fwnode_handle *fwnode; /* firmware device node */
+    struct iommu_fwspec *iommu_fwspec;
 };
 
 typedef struct device device_t;
@@ -27,8 +34,8 @@ typedef struct device device_t;
 #include <xen/device_tree.h>
 
 /* TODO: Correctly implement dev_is_pci when PCI is supported on ARM */
-#define dev_is_pci(dev) ((void)(dev), 0)
-#define dev_is_dt(dev)  ((dev->type == DEV_DT)
+#define dev_is_pci(dev) (dev->type == DEV_PCI)
+#define dev_is_dt(dev)  (dev->type == DEV_DT)
 
 enum device_class
 {
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index 33c8b221dc..56b169bae9 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -208,4 +208,26 @@ DECLARE_PER_CPU(bool_t, iommu_dont_flush_iotlb);
 extern struct spinlock iommu_pt_cleanup_lock;
 extern struct page_list_head iommu_pt_cleanup_list;
 
+/**
+ * struct iommu_fwspec - per-device IOMMU instance data
+ * @ops: ops for this device's IOMMU
+ * @iommu_fwnode: firmware handle for this device's IOMMU
+ * @iommu_priv: IOMMU driver private data for this device
+ * @num_ids: number of associated device IDs
+ * @ids: IDs which this device may present to the IOMMU
+ */
+struct iommu_fwspec {
+        const struct iommu_ops  *ops;
+        struct fwnode_handle    *iommu_fwnode;
+        void                    *iommu_priv;
+        unsigned int            num_ids;
+        u32                     ids[1];
+};
+
+int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
+                      const struct iommu_ops *ops);
+void iommu_fwspec_free(struct device *dev);
+int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
+const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
+
 #endif /* _IOMMU_H_ */
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 07/11] Add kernel helper functions
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
                   ` (5 preceding siblings ...)
  2018-01-02  9:28 ` [RFC 06/11] fwnode xen spacific changes manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-18 18:55   ` Julien Grall
  2018-02-08 21:56   ` Sameer Goel
  2018-01-02  9:28 ` [RFC 08/11] Add ACPI_IORT config manish.jaggi
                   ` (4 subsequent siblings)
  11 siblings, 2 replies; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

Add kalloc kfree functions from linux kernel.

Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
---
 xen/include/xen/kernel.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h
index 548b64da9f..78517f6caa 100644
--- a/xen/include/xen/kernel.h
+++ b/xen/include/xen/kernel.h
@@ -7,6 +7,16 @@
 
 #include <xen/types.h>
 
+/* Xen: Define compatibility functions */
+#define FW_BUG         "[Firmware Bug]: "
+#define pr_err(fmt, ...) printk(XENLOG_ERR fmt, ## __VA_ARGS__)
+#define pr_warn(fmt, ...) printk(XENLOG_WARNING fmt, ## __VA_ARGS__)
+
+/* Alias to Xen allocation helpers */
+#define kfree xfree
+#define kmalloc(size, flags)            _xmalloc(size, sizeof(void *))
+#define kzalloc(size, flags)            _xzalloc(size, sizeof(void *))
+
 /*
  * min()/max() macros that also do
  * strict type-checking.. See the
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 08/11] Add ACPI_IORT config
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
                   ` (6 preceding siblings ...)
  2018-01-02  9:28 ` [RFC 07/11] Add kernel helper functions manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-18 19:01   ` Julien Grall
  2018-01-02  9:28 ` [RFC 09/11] Xen IORT Changes manish.jaggi
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

Add ACPI_IORT config

Singed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
---
 xen/arch/arm/Kconfig     | 5 +++++
 xen/drivers/acpi/Kconfig | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index f58019d6ed..d4767d6ea3 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -42,6 +42,11 @@ config ACPI
 	  Advanced Configuration and Power Interface (ACPI) support for Xen is
 	  an alternative to device tree on ARM64.
 
+config ACPI_IORT
+	bool
+	prompt "ACPI IORT Support" if EXPERT = "y"
+	depends on ACPI
+
 config HAS_GICV3
 	bool
 
diff --git a/xen/drivers/acpi/Kconfig b/xen/drivers/acpi/Kconfig
index b64d3731fb..15ae98140c 100644
--- a/xen/drivers/acpi/Kconfig
+++ b/xen/drivers/acpi/Kconfig
@@ -5,5 +5,8 @@ config ACPI
 config ACPI_LEGACY_TABLES_LOOKUP
 	bool
 
+config ACPI_IORT
+	bool
+
 config NUMA
 	bool
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 09/11] Xen IORT Changes
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
                   ` (7 preceding siblings ...)
  2018-01-02  9:28 ` [RFC 08/11] Add ACPI_IORT config manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-18 19:10   ` Julien Grall
  2018-01-02  9:28 ` [RFC 10/11] IORT parsing functions to prepare requesterId maps manish.jaggi
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

This patch adds xen specific changes to iort.c

Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
---
 xen/arch/arm/setup.c          |    2 +
 xen/drivers/acpi/arm/Makefile |    1 +
 xen/drivers/acpi/arm/iort.c   | 1040 +++--------------------------------------
 xen/include/acpi/acpi_iort.h  |    6 +-
 4 files changed, 71 insertions(+), 978 deletions(-)

diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 16a3b1be8e..7ada48920f 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -37,6 +37,7 @@
 #include <xen/vmap.h>
 #include <xen/libfdt/libfdt.h>
 #include <xen/acpi.h>
+#include <acpi/acpi_iort.h>
 #include <asm/alternative.h>
 #include <asm/page.h>
 #include <asm/current.h>
@@ -800,6 +801,7 @@ void __init start_xen(unsigned long boot_phys_offset,
 
     tasklet_subsys_init();
 
+    acpi_iort_init();
 
     xsm_dt_init();
 
diff --git a/xen/drivers/acpi/arm/Makefile b/xen/drivers/acpi/arm/Makefile
index 13f1a9159f..5d16161016 100644
--- a/xen/drivers/acpi/arm/Makefile
+++ b/xen/drivers/acpi/arm/Makefile
@@ -1,2 +1,3 @@
 obj-y = ridmap.o
 obj-y += gen-iort.o
+obj-y += iort.o
diff --git a/xen/drivers/acpi/arm/iort.c b/xen/drivers/acpi/arm/iort.c
index de56394dd1..a47ee2df4c 100644
--- a/xen/drivers/acpi/arm/iort.c
+++ b/xen/drivers/acpi/arm/iort.c
@@ -14,17 +14,20 @@
  * This file implements early detection/parsing of I/O mapping
  * reported to OS through firmware via I/O Remapping Table (IORT)
  * IORT document number: ARM DEN 0049A
+ *
+ * Imported from Linux 4.14.0
+ * Xen Modifications : Manish Jaggi <manish.jaggi@linaro.org>
  */
 
 #define pr_fmt(fmt)	"ACPI: IORT: " fmt
 
-#include <linux/acpi_iort.h>
-#include <linux/iommu.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
+#include <acpi/acpi_iort.h>
+#include <acpi/ridmap.h>
+#include <xen/iommu.h>
+#include <xen/kernel.h>
+#include <xen/list.h>
+#include <xen/lib.h>
+#include <xen/pci.h>
 
 #define IORT_TYPE_MASK(type)	(1 << (type))
 #define IORT_MSI_TYPE		(1 << ACPI_IORT_NODE_ITS_GROUP)
@@ -36,6 +39,22 @@
 #define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX		0x2
 #endif
 
+/* Redefine WARN macros */
+#undef WARN
+#undef WARN_ON
+#define WARN(condition, format...) ({					\
+	int __ret_warn_on = !!(condition);				\
+	if (unlikely(__ret_warn_on))					\
+		printk(format);						\
+	unlikely(__ret_warn_on);					\
+})
+#define WARN_TAINT(cond, taint, format...) WARN(cond, format)
+#define WARN_ON(cond)                      (!!cond)
+
+
+#define MAX_ERRNO	4095
+#define IS_ERR_VALUE(x) unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO)
+
 struct iort_its_msi_chip {
 	struct list_head	list;
 	struct fwnode_handle	*fw_node;
@@ -49,7 +68,7 @@ struct iort_fwnode {
 };
 static LIST_HEAD(iort_fwnode_list);
 static DEFINE_SPINLOCK(iort_fwnode_lock);
-
+const struct fwnode_operations acpi_static_fwnode_ops;
 /**
  * iort_set_fwnode() - Create iort_fwnode and use it to register
  *		       iommu data in the iort_fwnode_list
@@ -73,7 +92,6 @@ static inline int iort_set_fwnode(struct acpi_iort_node *iort_node,
 	INIT_LIST_HEAD(&np->list);
 	np->iort_node = iort_node;
 	np->fwnode = fwnode;
-
 	spin_lock(&iort_fwnode_lock);
 	list_add_tail(&np->list, &iort_fwnode_list);
 	spin_unlock(&iort_fwnode_lock);
@@ -93,7 +111,6 @@ struct fwnode_handle *iort_get_fwnode(struct acpi_iort_node *node)
 {
 	struct iort_fwnode *curr;
 	struct fwnode_handle *fwnode = NULL;
-
 	spin_lock(&iort_fwnode_lock);
 	list_for_each_entry(curr, &iort_fwnode_list, list) {
 		if (curr->iort_node == node) {
@@ -132,79 +149,6 @@ typedef acpi_status (*iort_find_node_callback)
 /* Root pointer to the mapped IORT table */
 static struct acpi_table_header *iort_table;
 
-static LIST_HEAD(iort_msi_chip_list);
-static DEFINE_SPINLOCK(iort_msi_chip_lock);
-
-/**
- * iort_register_domain_token() - register domain token and related ITS ID
- * to the list from where we can get it back later on.
- * @trans_id: ITS ID.
- * @fw_node: Domain token.
- *
- * Returns: 0 on success, -ENOMEM if no memory when allocating list element
- */
-int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node)
-{
-	struct iort_its_msi_chip *its_msi_chip;
-
-	its_msi_chip = kzalloc(sizeof(*its_msi_chip), GFP_KERNEL);
-	if (!its_msi_chip)
-		return -ENOMEM;
-
-	its_msi_chip->fw_node = fw_node;
-	its_msi_chip->translation_id = trans_id;
-
-	spin_lock(&iort_msi_chip_lock);
-	list_add(&its_msi_chip->list, &iort_msi_chip_list);
-	spin_unlock(&iort_msi_chip_lock);
-
-	return 0;
-}
-
-/**
- * iort_deregister_domain_token() - Deregister domain token based on ITS ID
- * @trans_id: ITS ID.
- *
- * Returns: none.
- */
-void iort_deregister_domain_token(int trans_id)
-{
-	struct iort_its_msi_chip *its_msi_chip, *t;
-
-	spin_lock(&iort_msi_chip_lock);
-	list_for_each_entry_safe(its_msi_chip, t, &iort_msi_chip_list, list) {
-		if (its_msi_chip->translation_id == trans_id) {
-			list_del(&its_msi_chip->list);
-			kfree(its_msi_chip);
-			break;
-		}
-	}
-	spin_unlock(&iort_msi_chip_lock);
-}
-
-/**
- * iort_find_domain_token() - Find domain token based on given ITS ID
- * @trans_id: ITS ID.
- *
- * Returns: domain token when find on the list, NULL otherwise
- */
-struct fwnode_handle *iort_find_domain_token(int trans_id)
-{
-	struct fwnode_handle *fw_node = NULL;
-	struct iort_its_msi_chip *its_msi_chip;
-
-	spin_lock(&iort_msi_chip_lock);
-	list_for_each_entry(its_msi_chip, &iort_msi_chip_list, list) {
-		if (its_msi_chip->translation_id == trans_id) {
-			fw_node = its_msi_chip->fw_node;
-			break;
-		}
-	}
-	spin_unlock(&iort_msi_chip_lock);
-
-	return fw_node;
-}
-
 static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type,
 					     iort_find_node_callback callback,
 					     void *context)
@@ -215,7 +159,6 @@ static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type,
 
 	if (!iort_table)
 		return NULL;
-
 	/* Get the first IORT node */
 	iort = (struct acpi_table_iort *)iort_table;
 	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
@@ -245,29 +188,11 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
 	struct device *dev = context;
 	acpi_status status = AE_NOT_FOUND;
 
-	if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) {
-		struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
-		struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
-		struct acpi_iort_named_component *ncomp;
-
-		if (!adev)
-			goto out;
-
-		status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf);
-		if (ACPI_FAILURE(status)) {
-			dev_warn(dev, "Can't get device full path name\n");
-			goto out;
-		}
-
-		ncomp = (struct acpi_iort_named_component *)node->node_data;
-		status = !strcmp(ncomp->device_name, buf.pointer) ?
-							AE_OK : AE_NOT_FOUND;
-		acpi_os_free(buf.pointer);
-	} else if (node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
+	if (node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
 		struct acpi_iort_root_complex *pci_rc;
-		struct pci_bus *bus;
+		struct pci_dev *pdev;
 
-		bus = to_pci_bus(dev);
+		pdev = to_pci_dev(dev);
 		pci_rc = (struct acpi_iort_root_complex *)node->node_data;
 
 		/*
@@ -275,333 +200,19 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
 		 * with root complexes. Each segment number can represent only
 		 * one root complex.
 		 */
-		status = pci_rc->pci_segment_number == pci_domain_nr(bus) ?
+		status = pci_rc->pci_segment_number == pci_domain_nr(pdev) ?
 							AE_OK : AE_NOT_FOUND;
 	}
-out:
-	return status;
-}
-
-static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
-		       u32 *rid_out)
-{
-	/* Single mapping does not care for input id */
-	if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
-		if (type == ACPI_IORT_NODE_NAMED_COMPONENT ||
-		    type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
-			*rid_out = map->output_base;
-			return 0;
-		}
-
-		pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n",
-			map, type);
-		return -ENXIO;
-	}
-
-	if (rid_in < map->input_base ||
-	    (rid_in >= map->input_base + map->id_count))
-		return -ENXIO;
-
-	*rid_out = map->output_base + (rid_in - map->input_base);
-	return 0;
-}
-
-static
-struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
-					u32 *id_out, int index)
-{
-	struct acpi_iort_node *parent;
-	struct acpi_iort_id_mapping *map;
-
-	if (!node->mapping_offset || !node->mapping_count ||
-				     index >= node->mapping_count)
-		return NULL;
-
-	map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
-			   node->mapping_offset + index * sizeof(*map));
-
-	/* Firmware bug! */
-	if (!map->output_reference) {
-		pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
-		       node, node->type);
-		return NULL;
-	}
-
-	parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
-			       map->output_reference);
-
-	if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
-		if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
-		    node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
-			*id_out = map->output_base;
-			return parent;
-		}
-	}
-
-	return NULL;
-}
-
-static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node,
-					       u32 id_in, u32 *id_out,
-					       u8 type_mask)
-{
-	u32 id = id_in;
-
-	/* Parse the ID mapping tree to find specified node type */
-	while (node) {
-		struct acpi_iort_id_mapping *map;
-		int i;
-
-		if (IORT_TYPE_MASK(node->type) & type_mask) {
-			if (id_out)
-				*id_out = id;
-			return node;
-		}
-
-		if (!node->mapping_offset || !node->mapping_count)
-			goto fail_map;
-
-		map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
-				   node->mapping_offset);
-
-		/* Firmware bug! */
-		if (!map->output_reference) {
-			pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
-			       node, node->type);
-			goto fail_map;
-		}
-
-		/* Do the ID translation */
-		for (i = 0; i < node->mapping_count; i++, map++) {
-			if (!iort_id_map(map, node->type, id, &id))
-				break;
-		}
-
-		if (i == node->mapping_count)
-			goto fail_map;
-
-		node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
-				    map->output_reference);
-	}
-
-fail_map:
-	/* Map input ID to output ID unchanged on mapping failure */
-	if (id_out)
-		*id_out = id_in;
-
-	return NULL;
-}
-
-static
-struct acpi_iort_node *iort_node_map_platform_id(struct acpi_iort_node *node,
-						 u32 *id_out, u8 type_mask,
-						 int index)
-{
-	struct acpi_iort_node *parent;
-	u32 id;
-
-	/* step 1: retrieve the initial dev id */
-	parent = iort_node_get_id(node, &id, index);
-	if (!parent)
-		return NULL;
-
-	/*
-	 * optional step 2: map the initial dev id if its parent is not
-	 * the target type we want, map it again for the use cases such
-	 * as NC (named component) -> SMMU -> ITS. If the type is matched,
-	 * return the initial dev id and its parent pointer directly.
-	 */
-	if (!(IORT_TYPE_MASK(parent->type) & type_mask))
-		parent = iort_node_map_id(parent, id, id_out, type_mask);
-	else
-		if (id_out)
-			*id_out = id;
-
-	return parent;
-}
 
-static struct acpi_iort_node *iort_find_dev_node(struct device *dev)
-{
-	struct pci_bus *pbus;
-
-	if (!dev_is_pci(dev))
-		return iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
-				      iort_match_node_callback, dev);
-
-	/* Find a PCI root bus */
-	pbus = to_pci_dev(dev)->bus;
-	while (!pci_is_root_bus(pbus))
-		pbus = pbus->parent;
-
-	return iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
-			      iort_match_node_callback, &pbus->dev);
-}
-
-/**
- * iort_msi_map_rid() - Map a MSI requester ID for a device
- * @dev: The device for which the mapping is to be done.
- * @req_id: The device requester ID.
- *
- * Returns: mapped MSI RID on success, input requester ID otherwise
- */
-u32 iort_msi_map_rid(struct device *dev, u32 req_id)
-{
-	struct acpi_iort_node *node;
-	u32 dev_id;
-
-	node = iort_find_dev_node(dev);
-	if (!node)
-		return req_id;
-
-	iort_node_map_id(node, req_id, &dev_id, IORT_MSI_TYPE);
-	return dev_id;
-}
-
-/**
- * iort_pmsi_get_dev_id() - Get the device id for a device
- * @dev: The device for which the mapping is to be done.
- * @dev_id: The device ID found.
- *
- * Returns: 0 for successful find a dev id, -ENODEV on error
- */
-int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
-{
-	int i;
-	struct acpi_iort_node *node;
-
-	node = iort_find_dev_node(dev);
-	if (!node)
-		return -ENODEV;
-
-	for (i = 0; i < node->mapping_count; i++) {
-		if (iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, i))
-			return 0;
-	}
-
-	return -ENODEV;
-}
-
-/**
- * iort_dev_find_its_id() - Find the ITS identifier for a device
- * @dev: The device.
- * @req_id: Device's requester ID
- * @idx: Index of the ITS identifier list.
- * @its_id: ITS identifier.
- *
- * Returns: 0 on success, appropriate error value otherwise
- */
-static int iort_dev_find_its_id(struct device *dev, u32 req_id,
-				unsigned int idx, int *its_id)
-{
-	struct acpi_iort_its_group *its;
-	struct acpi_iort_node *node;
-
-	node = iort_find_dev_node(dev);
-	if (!node)
-		return -ENXIO;
-
-	node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE);
-	if (!node)
-		return -ENXIO;
-
-	/* Move to ITS specific data */
-	its = (struct acpi_iort_its_group *)node->node_data;
-	if (idx > its->its_count) {
-		dev_err(dev, "requested ITS ID index [%d] is greater than available [%d]\n",
-			idx, its->its_count);
-		return -ENXIO;
-	}
-
-	*its_id = its->identifiers[idx];
-	return 0;
-}
-
-/**
- * iort_get_device_domain() - Find MSI domain related to a device
- * @dev: The device.
- * @req_id: Requester ID for the device.
- *
- * Returns: the MSI domain for this device, NULL otherwise
- */
-struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
-{
-	struct fwnode_handle *handle;
-	int its_id;
-
-	if (iort_dev_find_its_id(dev, req_id, 0, &its_id))
-		return NULL;
-
-	handle = iort_find_domain_token(its_id);
-	if (!handle)
-		return NULL;
-
-	return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
-}
-
-/**
- * iort_get_platform_device_domain() - Find MSI domain related to a
- * platform device
- * @dev: the dev pointer associated with the platform device
- *
- * Returns: the MSI domain for this device, NULL otherwise
- */
-static struct irq_domain *iort_get_platform_device_domain(struct device *dev)
-{
-	struct acpi_iort_node *node, *msi_parent;
-	struct fwnode_handle *iort_fwnode;
-	struct acpi_iort_its_group *its;
-	int i;
-
-	/* find its associated iort node */
-	node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
-			      iort_match_node_callback, dev);
-	if (!node)
-		return NULL;
-
-	/* then find its msi parent node */
-	for (i = 0; i < node->mapping_count; i++) {
-		msi_parent = iort_node_map_platform_id(node, NULL,
-						       IORT_MSI_TYPE, i);
-		if (msi_parent)
-			break;
-	}
-
-	if (!msi_parent)
-		return NULL;
-
-	/* Move to ITS specific data */
-	its = (struct acpi_iort_its_group *)msi_parent->node_data;
-
-	iort_fwnode = iort_find_domain_token(its->identifiers[0]);
-	if (!iort_fwnode)
-		return NULL;
-
-	return irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI);
-}
-
-void acpi_configure_pmsi_domain(struct device *dev)
-{
-	struct irq_domain *msi_domain;
-
-	msi_domain = iort_get_platform_device_domain(dev);
-	if (msi_domain)
-		dev_set_msi_domain(dev, msi_domain);
-}
-
-static int __maybe_unused __get_pci_rid(struct pci_dev *pdev, u16 alias,
-					void *data)
-{
-	u32 *rid = data;
-
-	*rid = alias;
-	return 0;
+	return status;
 }
 
 static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
 			       struct fwnode_handle *fwnode,
 			       const struct iommu_ops *ops)
 {
-	int ret = iommu_fwspec_init(dev, fwnode, ops);
+	int ret;
+	ret  = iommu_fwspec_init(dev, fwnode, ops);
 
 	if (!ret)
 		ret = iommu_fwspec_add_ids(dev, &streamid, 1);
@@ -609,45 +220,12 @@ static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
 	return ret;
 }
 
-static inline bool iort_iommu_driver_enabled(u8 type)
-{
-	switch (type) {
-	case ACPI_IORT_NODE_SMMU_V3:
-		return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
-	case ACPI_IORT_NODE_SMMU:
-		return IS_BUILTIN(CONFIG_ARM_SMMU);
-	default:
-		pr_warn("IORT node type %u does not describe an SMMU\n", type);
-		return false;
-	}
-}
-
-#ifdef CONFIG_IOMMU_API
 static inline
 const struct iommu_ops *iort_fwspec_iommu_ops(struct iommu_fwspec *fwspec)
 {
 	return (fwspec && fwspec->ops) ? fwspec->ops : NULL;
 }
 
-static inline
-int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev)
-{
-	int err = 0;
-
-	if (ops->add_device && dev->bus && !dev->iommu_group)
-		err = ops->add_device(dev);
-
-	return err;
-}
-#else
-static inline
-const struct iommu_ops *iort_fwspec_iommu_ops(struct iommu_fwspec *fwspec)
-{ return NULL; }
-static inline
-int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev)
-{ return 0; }
-#endif
-
 static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
 			    u32 streamid)
 {
@@ -670,9 +248,9 @@ static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
 	 * or just abort it.
 	 */
 	ops = iommu_ops_from_fwnode(iort_fwnode);
-	if (!ops)
-		return iort_iommu_driver_enabled(node->type) ?
-		       -EPROBE_DEFER : -ENODEV;
+	if (!ops) {
+		return -1;
+        }
 
 	return arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
 }
@@ -685,89 +263,19 @@ struct iort_pci_alias_info {
 static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
 {
 	struct iort_pci_alias_info *info = data;
-	struct acpi_iort_node *parent;
+	struct acpi_iort_node *smmu_node;
 	u32 streamid;
 
-	parent = iort_node_map_id(info->node, alias, &streamid,
-				  IORT_IOMMU_TYPE);
-	return iort_iommu_xlate(info->dev, parent, streamid);
+	query_streamid(info->node, alias, &streamid, &smmu_node);
+	return iort_iommu_xlate(info->dev, smmu_node, streamid);
 }
 
-static int nc_dma_get_range(struct device *dev, u64 *size)
+int pci_for_each_dma_alias(struct pci_dev *pdev,
+			   int (*fn)(struct pci_dev *pdev,
+		           u16 alias, void *data), void *data)
 {
-	struct acpi_iort_node *node;
-	struct acpi_iort_named_component *ncomp;
-
-	node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
-			      iort_match_node_callback, dev);
-	if (!node)
-		return -ENODEV;
-
-	ncomp = (struct acpi_iort_named_component *)node->node_data;
-
-	*size = ncomp->memory_address_limit >= 64 ? U64_MAX :
-			1ULL<<ncomp->memory_address_limit;
-
-	return 0;
-}
-
-/**
- * iort_dma_setup() - Set-up device DMA parameters.
- *
- * @dev: device to configure
- * @dma_addr: device DMA address result pointer
- * @size: DMA range size result pointer
- */
-void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
-{
-	u64 mask, dmaaddr = 0, size = 0, offset = 0;
-	int ret, msb;
-
-	/*
-	 * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
-	 * setup the correct supported mask.
-	 */
-	if (!dev->coherent_dma_mask)
-		dev->coherent_dma_mask = DMA_BIT_MASK(32);
-
-	/*
-	 * Set it to coherent_dma_mask by default if the architecture
-	 * code has not set it.
-	 */
-	if (!dev->dma_mask)
-		dev->dma_mask = &dev->coherent_dma_mask;
-
-	size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
-
-	if (dev_is_pci(dev))
-		ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size);
-	else
-		ret = nc_dma_get_range(dev, &size);
-
-	if (!ret) {
-		msb = fls64(dmaaddr + size - 1);
-		/*
-		 * Round-up to the power-of-two mask or set
-		 * the mask to the whole 64-bit address space
-		 * in case the DMA region covers the full
-		 * memory window.
-		 */
-		mask = msb == 64 ? U64_MAX : (1ULL << msb) - 1;
-		/*
-		 * Limit coherent and dma mask based on size
-		 * retrieved from firmware.
-		 */
-		dev->coherent_dma_mask = mask;
-		*dev->dma_mask = mask;
-	}
-
-	*dma_addr = dmaaddr;
-	*dma_size = size;
-
-	dev->dma_pfn_offset = PFN_DOWN(offset);
-	dev_dbg(dev, "dma_pfn_offset(%#08llx)\n", offset);
+	return fn(pdev, PCI_BDF2(pdev->bus, pdev->devfn), data);
 }
-
 /**
  * iort_iommu_configure - Set-up IOMMU configuration for a device.
  *
@@ -778,9 +286,8 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
  */
 const struct iommu_ops *iort_iommu_configure(struct device *dev)
 {
-	struct acpi_iort_node *node, *parent;
+	struct acpi_iort_node *node;
 	const struct iommu_ops *ops;
-	u32 streamid = 0;
 	int err = -ENODEV;
 
 	/*
@@ -792,472 +299,58 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
 		return ops;
 
 	if (dev_is_pci(dev)) {
-		struct pci_bus *bus = to_pci_dev(dev)->bus;
 		struct iort_pci_alias_info info = { .dev = dev };
-
 		node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
-				      iort_match_node_callback, &bus->dev);
+				      iort_match_node_callback, dev);
 		if (!node)
 			return NULL;
-
 		info.node = node;
 		err = pci_for_each_dma_alias(to_pci_dev(dev),
 					     iort_pci_iommu_init, &info);
-	} else {
-		int i = 0;
-
-		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
-				      iort_match_node_callback, dev);
-		if (!node)
-			return NULL;
-
-		do {
-			parent = iort_node_map_platform_id(node, &streamid,
-							   IORT_IOMMU_TYPE,
-							   i++);
-
-			if (parent)
-				err = iort_iommu_xlate(dev, parent, streamid);
-		} while (parent && !err);
-	}
-
-	/*
-	 * If we have reason to believe the IOMMU driver missed the initial
-	 * add_device callback for dev, replay it to get things in order.
-	 */
-	if (!err) {
-		ops = iort_fwspec_iommu_ops(dev->iommu_fwspec);
-		err = iort_add_device_replay(ops, dev);
 	}
-
-	/* Ignore all other errors apart from EPROBE_DEFER */
-	if (err == -EPROBE_DEFER) {
-		ops = ERR_PTR(err);
-	} else if (err) {
-		dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
-		ops = NULL;
-	}
-
 	return ops;
 }
 
-static void __init acpi_iort_register_irq(int hwirq, const char *name,
-					  int trigger,
-					  struct resource *res)
-{
-	int irq = acpi_register_gsi(NULL, hwirq, trigger,
-				    ACPI_ACTIVE_HIGH);
-
-	if (irq <= 0) {
-		pr_err("could not register gsi hwirq %d name [%s]\n", hwirq,
-								      name);
-		return;
-	}
-
-	res->start = irq;
-	res->end = irq;
-	res->flags = IORESOURCE_IRQ;
-	res->name = name;
-}
-
-static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node)
-{
-	struct acpi_iort_smmu_v3 *smmu;
-	/* Always present mem resource */
-	int num_res = 1;
-
-	/* Retrieve SMMUv3 specific data */
-	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
-
-	if (smmu->event_gsiv)
-		num_res++;
-
-	if (smmu->pri_gsiv)
-		num_res++;
-
-	if (smmu->gerr_gsiv)
-		num_res++;
-
-	if (smmu->sync_gsiv)
-		num_res++;
-
-	return num_res;
-}
-
-static bool arm_smmu_v3_is_combined_irq(struct acpi_iort_smmu_v3 *smmu)
-{
-	/*
-	 * Cavium ThunderX2 implementation doesn't not support unique
-	 * irq line. Use single irq line for all the SMMUv3 interrupts.
-	 */
-	if (smmu->model != ACPI_IORT_SMMU_V3_CAVIUM_CN99XX)
-		return false;
-
-	/*
-	 * ThunderX2 doesn't support MSIs from the SMMU, so we're checking
-	 * SPI numbers here.
-	 */
-	return smmu->event_gsiv == smmu->pri_gsiv &&
-	       smmu->event_gsiv == smmu->gerr_gsiv &&
-	       smmu->event_gsiv == smmu->sync_gsiv;
-}
-
-static unsigned long arm_smmu_v3_resource_size(struct acpi_iort_smmu_v3 *smmu)
-{
-	/*
-	 * Override the size, for Cavium ThunderX2 implementation
-	 * which doesn't support the page 1 SMMU register space.
-	 */
-	if (smmu->model == ACPI_IORT_SMMU_V3_CAVIUM_CN99XX)
-		return SZ_64K;
-
-	return SZ_128K;
-}
-
-static void __init arm_smmu_v3_init_resources(struct resource *res,
-					      struct acpi_iort_node *node)
-{
-	struct acpi_iort_smmu_v3 *smmu;
-	int num_res = 0;
-
-	/* Retrieve SMMUv3 specific data */
-	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
-
-	res[num_res].start = smmu->base_address;
-	res[num_res].end = smmu->base_address +
-				arm_smmu_v3_resource_size(smmu) - 1;
-	res[num_res].flags = IORESOURCE_MEM;
-
-	num_res++;
-	if (arm_smmu_v3_is_combined_irq(smmu)) {
-		if (smmu->event_gsiv)
-			acpi_iort_register_irq(smmu->event_gsiv, "combined",
-					       ACPI_EDGE_SENSITIVE,
-					       &res[num_res++]);
-	} else {
-
-		if (smmu->event_gsiv)
-			acpi_iort_register_irq(smmu->event_gsiv, "eventq",
-					       ACPI_EDGE_SENSITIVE,
-					       &res[num_res++]);
-
-		if (smmu->pri_gsiv)
-			acpi_iort_register_irq(smmu->pri_gsiv, "priq",
-					       ACPI_EDGE_SENSITIVE,
-					       &res[num_res++]);
-
-		if (smmu->gerr_gsiv)
-			acpi_iort_register_irq(smmu->gerr_gsiv, "gerror",
-					       ACPI_EDGE_SENSITIVE,
-					       &res[num_res++]);
-
-		if (smmu->sync_gsiv)
-			acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync",
-					       ACPI_EDGE_SENSITIVE,
-					       &res[num_res++]);
-	}
-}
-
-static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
-{
-	struct acpi_iort_smmu_v3 *smmu;
-
-	/* Retrieve SMMUv3 specific data */
-	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
-
-	return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
-}
-
-#if defined(CONFIG_ACPI_NUMA) && defined(ACPI_IORT_SMMU_V3_PXM_VALID)
-/*
- * set numa proximity domain for smmuv3 device
- */
-static void  __init arm_smmu_v3_set_proximity(struct device *dev,
-					      struct acpi_iort_node *node)
-{
-	struct acpi_iort_smmu_v3 *smmu;
-
-	smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
-	if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) {
-		set_dev_node(dev, acpi_map_pxm_to_node(smmu->pxm));
-		pr_info("SMMU-v3[%llx] Mapped to Proximity domain %d\n",
-			smmu->base_address,
-			smmu->pxm);
-	}
-}
-#else
-#define arm_smmu_v3_set_proximity NULL
-#endif
-
-static int __init arm_smmu_count_resources(struct acpi_iort_node *node)
-{
-	struct acpi_iort_smmu *smmu;
-
-	/* Retrieve SMMU specific data */
-	smmu = (struct acpi_iort_smmu *)node->node_data;
-
-	/*
-	 * Only consider the global fault interrupt and ignore the
-	 * configuration access interrupt.
-	 *
-	 * MMIO address and global fault interrupt resources are always
-	 * present so add them to the context interrupt count as a static
-	 * value.
-	 */
-	return smmu->context_interrupt_count + 2;
-}
-
-static void __init arm_smmu_init_resources(struct resource *res,
-					   struct acpi_iort_node *node)
-{
-	struct acpi_iort_smmu *smmu;
-	int i, hw_irq, trigger, num_res = 0;
-	u64 *ctx_irq, *glb_irq;
-
-	/* Retrieve SMMU specific data */
-	smmu = (struct acpi_iort_smmu *)node->node_data;
-
-	res[num_res].start = smmu->base_address;
-	res[num_res].end = smmu->base_address + smmu->span - 1;
-	res[num_res].flags = IORESOURCE_MEM;
-	num_res++;
-
-	glb_irq = ACPI_ADD_PTR(u64, node, smmu->global_interrupt_offset);
-	/* Global IRQs */
-	hw_irq = IORT_IRQ_MASK(glb_irq[0]);
-	trigger = IORT_IRQ_TRIGGER_MASK(glb_irq[0]);
-
-	acpi_iort_register_irq(hw_irq, "arm-smmu-global", trigger,
-				     &res[num_res++]);
-
-	/* Context IRQs */
-	ctx_irq = ACPI_ADD_PTR(u64, node, smmu->context_interrupt_offset);
-	for (i = 0; i < smmu->context_interrupt_count; i++) {
-		hw_irq = IORT_IRQ_MASK(ctx_irq[i]);
-		trigger = IORT_IRQ_TRIGGER_MASK(ctx_irq[i]);
-
-		acpi_iort_register_irq(hw_irq, "arm-smmu-context", trigger,
-				       &res[num_res++]);
-	}
-}
-
-static bool __init arm_smmu_is_coherent(struct acpi_iort_node *node)
-{
-	struct acpi_iort_smmu *smmu;
-
-	/* Retrieve SMMU specific data */
-	smmu = (struct acpi_iort_smmu *)node->node_data;
-
-	return smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK;
-}
-
-struct iort_iommu_config {
-	const char *name;
-	int (*iommu_init)(struct acpi_iort_node *node);
-	bool (*iommu_is_coherent)(struct acpi_iort_node *node);
-	int (*iommu_count_resources)(struct acpi_iort_node *node);
-	void (*iommu_init_resources)(struct resource *res,
-				     struct acpi_iort_node *node);
-	void (*iommu_set_proximity)(struct device *dev,
-				    struct acpi_iort_node *node);
-};
-
-static const struct iort_iommu_config iort_arm_smmu_v3_cfg __initconst = {
-	.name = "arm-smmu-v3",
-	.iommu_is_coherent = arm_smmu_v3_is_coherent,
-	.iommu_count_resources = arm_smmu_v3_count_resources,
-	.iommu_init_resources = arm_smmu_v3_init_resources,
-	.iommu_set_proximity = arm_smmu_v3_set_proximity,
-};
-
-static const struct iort_iommu_config iort_arm_smmu_cfg __initconst = {
-	.name = "arm-smmu",
-	.iommu_is_coherent = arm_smmu_is_coherent,
-	.iommu_count_resources = arm_smmu_count_resources,
-	.iommu_init_resources = arm_smmu_init_resources
-};
-
-static __init
-const struct iort_iommu_config *iort_get_iommu_cfg(struct acpi_iort_node *node)
-{
-	switch (node->type) {
-	case ACPI_IORT_NODE_SMMU_V3:
-		return &iort_arm_smmu_v3_cfg;
-	case ACPI_IORT_NODE_SMMU:
-		return &iort_arm_smmu_cfg;
-	default:
-		return NULL;
-	}
-}
-
-/**
- * iort_add_smmu_platform_device() - Allocate a platform device for SMMU
- * @node: Pointer to SMMU ACPI IORT node
- *
- * Returns: 0 on success, <0 failure
- */
 static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node)
 {
+	struct device *dev;
 	struct fwnode_handle *fwnode;
-	struct platform_device *pdev;
-	struct resource *r;
-	enum dev_dma_attr attr;
-	int ret, count;
-	const struct iort_iommu_config *ops = iort_get_iommu_cfg(node);
+	int ret;
 
-	if (!ops)
-		return -ENODEV;
-
-	pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO);
-	if (!pdev)
+	dev = kzalloc(sizeof (struct device), GFP_KERNEL);
+	if (!dev)
 		return -ENOMEM;
 
-	if (ops->iommu_set_proximity)
-		ops->iommu_set_proximity(&pdev->dev, node);
-
-	count = ops->iommu_count_resources(node);
-
-	r = kcalloc(count, sizeof(*r), GFP_KERNEL);
-	if (!r) {
-		ret = -ENOMEM;
-		goto dev_put;
-	}
-
-	ops->iommu_init_resources(r, node);
-
-	ret = platform_device_add_resources(pdev, r, count);
-	/*
-	 * Resources are duplicated in platform_device_add_resources,
-	 * free their allocated memory
-	 */
-	kfree(r);
-
-	if (ret)
-		goto dev_put;
-
-	/*
-	 * Add a copy of IORT node pointer to platform_data to
-	 * be used to retrieve IORT data information.
-	 */
-	ret = platform_device_add_data(pdev, &node, sizeof(node));
-	if (ret)
-		goto dev_put;
-
-	/*
-	 * We expect the dma masks to be equivalent for
-	 * all SMMUs set-ups
-	 */
-	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+	dev->type = DEV_ACPI;
+	dev->acpi_node = node;
 
 	fwnode = iort_get_fwnode(node);
 
 	if (!fwnode) {
 		ret = -ENODEV;
-		goto dev_put;
+		goto end;
 	}
 
-	pdev->dev.fwnode = fwnode;
-
-	attr = ops->iommu_is_coherent(node) ?
-			     DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
-
-	/* Configure DMA for the page table walker */
-	acpi_dma_configure(&pdev->dev, attr);
-
-	ret = platform_device_add(pdev);
-	if (ret)
-		goto dma_deconfigure;
-
-	return 0;
-
-dma_deconfigure:
-	acpi_dma_deconfigure(&pdev->dev);
-dev_put:
-	platform_device_put(pdev);
-
+	dev->fwnode = fwnode;
+	dev->iommu_fwspec = kzalloc(sizeof (struct iommu_fwspec), GFP_KERNEL);
+	/* Call the acpi init functions for IOMMU devices */
+	ret = acpi_device_init(DEVICE_IOMMU, (void *) dev, node->type);
+end:
 	return ret;
 }
 
-static bool __init iort_enable_acs(struct acpi_iort_node *iort_node)
-{
-	if (iort_node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
-		struct acpi_iort_node *parent;
-		struct acpi_iort_id_mapping *map;
-		int i;
-
-		map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, iort_node,
-				   iort_node->mapping_offset);
-
-		for (i = 0; i < iort_node->mapping_count; i++, map++) {
-			if (!map->output_reference)
-				continue;
-
-			parent = ACPI_ADD_PTR(struct acpi_iort_node,
-					iort_table,  map->output_reference);
-			/*
-			 * If we detect a RC->SMMU mapping, make sure
-			 * we enable ACS on the system.
-			 */
-			if ((parent->type == ACPI_IORT_NODE_SMMU) ||
-				(parent->type == ACPI_IORT_NODE_SMMU_V3)) {
-				pci_request_acs();
-				return true;
-			}
-		}
-	}
-
-	return false;
-}
 
-static void __init iort_init_platform_devices(void)
+static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)
 {
-	struct acpi_iort_node *iort_node, *iort_end;
-	struct acpi_table_iort *iort;
 	struct fwnode_handle *fwnode;
-	int i, ret;
-	bool acs_enabled = false;
 
-	/*
-	 * iort_table and iort both point to the start of IORT table, but
-	 * have different struct types
-	 */
-	iort = (struct acpi_table_iort *)iort_table;
-
-	/* Get the first IORT node */
-	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
-				 iort->node_offset);
-	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
-				iort_table->length);
-
-	for (i = 0; i < iort->node_count; i++) {
-		if (iort_node >= iort_end) {
-			pr_err("iort node pointer overflows, bad table\n");
-			return;
-		}
-
-		if (!acs_enabled)
-			acs_enabled = iort_enable_acs(iort_node);
-
-		if ((iort_node->type == ACPI_IORT_NODE_SMMU) ||
-			(iort_node->type == ACPI_IORT_NODE_SMMU_V3)) {
-
-			fwnode = acpi_alloc_fwnode_static();
-			if (!fwnode)
-				return;
-
-			iort_set_fwnode(iort_node, fwnode);
+	fwnode = kzalloc(sizeof(struct fwnode_handle), GFP_KERNEL);
+	if (!fwnode)
+		return NULL;
 
-			ret = iort_add_smmu_platform_device(iort_node);
-			if (ret) {
-				iort_delete_fwnode(iort_node);
-				acpi_free_fwnode_static(fwnode);
-				return;
-			}
-		}
+	fwnode->ops = &acpi_static_fwnode_ops;
 
-		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
-					 iort_node->length);
-	}
+	return fwnode;
 }
 
 void __init acpi_iort_init(void)
@@ -1265,15 +358,12 @@ void __init acpi_iort_init(void)
 	acpi_status status;
 
 	status = acpi_get_table(ACPI_SIG_IORT, 0, &iort_table);
+
 	if (ACPI_FAILURE(status)) {
 		if (status != AE_NOT_FOUND) {
 			const char *msg = acpi_format_exception(status);
-
 			pr_err("Failed to get table, %s\n", msg);
 		}
-
 		return;
 	}
-
-	iort_init_platform_devices();
 }
diff --git a/xen/include/acpi/acpi_iort.h b/xen/include/acpi/acpi_iort.h
index 8d3f0bf803..559226a312 100644
--- a/xen/include/acpi/acpi_iort.h
+++ b/xen/include/acpi/acpi_iort.h
@@ -19,9 +19,9 @@
 #ifndef __ACPI_IORT_H__
 #define __ACPI_IORT_H__
 
-#include <linux/acpi.h>
-#include <linux/fwnode.h>
-#include <linux/irqdomain.h>
+#include <asm/device.h>
+#include <xen/acpi.h>
+#include <xen/fwnode.h>
 
 #define IORT_IRQ_MASK(irq)		(irq & 0xffffffffULL)
 #define IORT_IRQ_TRIGGER_MASK(irq)	((irq >> 32) & 0xffffffffULL)
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 10/11] IORT parsing functions to prepare requesterId maps
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
                   ` (8 preceding siblings ...)
  2018-01-02  9:28 ` [RFC 09/11] Xen IORT Changes manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-02  9:28 ` [RFC 11/11] Add to_pci_dev macro manish.jaggi
  2018-01-16 17:53 ` [RFC 00/11] acpi: arm: IORT Support for Xen Julien Grall
  11 siblings, 0 replies; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

This patch adds functions to parse the IORT and use the requesterID public API
to update the maps.

Signed-off-by: Manish jaggi <manish.jaggi@linaro.org>
---
 xen/drivers/acpi/arm/iort.c | 200 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 200 insertions(+)

diff --git a/xen/drivers/acpi/arm/iort.c b/xen/drivers/acpi/arm/iort.c
index a47ee2df4c..00a9f18046 100644
--- a/xen/drivers/acpi/arm/iort.c
+++ b/xen/drivers/acpi/arm/iort.c
@@ -353,6 +353,205 @@ static inline struct fwnode_handle *acpi_alloc_fwnode_static(void)
 	return fwnode;
 }
 
+static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
+{
+	return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr);
+}
+
+static inline bool is_acpi_static_node(const struct fwnode_handle *fwnode)
+{
+	return !IS_ERR_OR_NULL(fwnode) &&
+		fwnode->ops == &acpi_static_fwnode_ops;
+}
+
+static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode)
+{
+	if (WARN_ON(!is_acpi_static_node(fwnode)))
+		return;
+
+	kfree(fwnode);
+}
+int fixup_rid_deviceid_map(struct acpi_iort_node *inode,
+                           struct acpi_iort_id_mapping *pci_idmap,
+                           struct acpi_iort_node *smmu_node)
+{
+
+	unsigned int p_input_base, p_output_base, p_id_count;
+	unsigned int s_input_base, s_output_base, s_id_count;
+	unsigned int delta, i;
+	int ret = 0;
+	struct acpi_iort_id_mapping *smmu_idmap = NULL;
+	struct acpi_iort_node *its_node;
+	struct acpi_table_iort *iort;
+
+	iort = (struct acpi_table_iort*) iort_table;
+
+	p_input_base = pci_idmap->input_base;
+	p_output_base = pci_idmap->output_base;
+	p_id_count = pci_idmap->id_count;
+
+	smmu_idmap = (struct acpi_iort_id_mapping*) ((u8*) smmu_node +
+		      smmu_node->mapping_offset);
+
+	for (i = 0; i < smmu_node->mapping_count; i++, smmu_idmap++) {
+		s_input_base = smmu_idmap->input_base;
+		s_output_base = smmu_idmap->output_base;
+		s_id_count = smmu_idmap->id_count;
+		its_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				        smmu_idmap->output_reference);
+
+		if (s_input_base <= p_output_base) {
+			int count;
+			if (s_input_base + s_id_count < p_output_base)
+				continue;
+
+			delta = p_output_base - s_input_base;
+			count = s_input_base + s_id_count <= p_output_base +
+				p_id_count ? s_id_count - delta : p_id_count;
+
+			ret = add_rid_deviceid_map (inode, its_node,
+						    p_input_base,
+						    s_output_base + delta,
+						    count);
+			if (ret)
+				return ret;
+		} else {
+			int count;
+			if (p_output_base + p_id_count < s_input_base)
+				continue;
+
+			delta = s_input_base - p_output_base;
+			count = s_input_base + s_id_count < p_output_base +
+				p_id_count ? s_id_count : p_id_count - delta;
+
+			ret = add_rid_deviceid_map (inode, its_node,
+						    p_input_base + delta,
+						    s_output_base, count);
+
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+void parse_pcirc_node(struct acpi_iort_node *iort_node)
+{
+	int j , ret;
+	struct acpi_iort_id_mapping *idmap;
+	struct acpi_iort_node *onode;
+	struct acpi_table_iort *iort;
+
+	iort = (struct acpi_table_iort*) iort_table;
+	idmap = ACPI_ADD_PTR(struct acpi_iort_id_mapping, iort_node,
+			     iort_node->mapping_offset);
+
+	/* iterate over idmap */
+	for ( j = 0; j < iort_node->mapping_count; j++ ) {
+
+		struct acpi_iort_node *its_node;
+		struct acpi_iort_node *smmu_node;
+		onode = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				     idmap->output_reference);
+
+		switch (onode->type) {
+			case ACPI_IORT_NODE_ITS_GROUP:
+
+				its_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+							idmap->output_reference);
+
+				ret = add_rid_deviceid_map(iort_node, its_node,
+							   idmap->input_base,
+							   idmap->output_base,
+							   idmap->id_count);
+				if (ret) {
+					pr_err("%s: add_rid_deviceid_map"
+					       "failed with ret=%d \r\n",
+					       __func__, ret);
+					break;
+				}
+			break;
+
+			case ACPI_IORT_NODE_SMMU:
+			case ACPI_IORT_NODE_SMMU_V3:
+
+				smmu_node = ACPI_ADD_PTR(
+						struct acpi_iort_node,
+						iort_table,
+						idmap->output_reference);
+
+				ret = add_rid_streamid_map(iort_node,
+							   smmu_node,
+							   idmap->input_base,
+							   idmap->output_base,
+							   idmap->id_count);
+				if (ret) {
+					pr_err("%s: add_rid_streamid_map"
+					       "failed with ret=%d \r\n",
+					       __func__, ret);
+					break;
+				}
+
+				ret = fixup_rid_deviceid_map(iort_node, idmap,
+							     onode);
+				if (ret) {
+					pr_err("%s: fixup_rid_deviceid_map"
+					       "failed with ret=%d \r\n",
+					       __func__, ret);
+					break;
+				}
+			break;
+		}
+		idmap++;
+	}
+}
+
+void parse_smmu_node(struct acpi_iort_node *iort_node)
+{
+	int ret;
+	struct fwnode_handle *fwnode;
+	fwnode = acpi_alloc_fwnode_static();
+	if (!fwnode)
+		return;
+
+	iort_set_fwnode(iort_node, fwnode);
+	ret = iort_add_smmu_platform_device(iort_node);
+	if (ret)
+		acpi_free_fwnode_static(fwnode);
+}
+
+void parse_iort(void)
+{
+	struct acpi_iort_node *iort_node, *iort_end;
+	struct acpi_table_iort *iort;
+	int i;
+
+	iort = (struct acpi_table_iort*) iort_table;
+	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+			iort->node_offset);
+	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+			iort->header.length);
+	init_ridmaps();
+
+	for (i = 0; i < iort->node_count; i++) {
+		if ( iort_node >= iort_end ) {
+			pr_err("iort node pointer overflows, bad table\n");
+			return;
+		}
+
+		if ( iort_node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX )
+			parse_pcirc_node(iort_node);
+		else if ( (iort_node->type == ACPI_IORT_NODE_SMMU ||
+			     iort_node->type == ACPI_IORT_NODE_SMMU_V3) )
+			parse_smmu_node(iort_node);
+
+		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+				iort_node->length);
+	}
+}
+
+
 void __init acpi_iort_init(void)
 {
 	acpi_status status;
@@ -366,4 +565,5 @@ void __init acpi_iort_init(void)
 		}
 		return;
 	}
+	parse_iort();
 }
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [RFC 11/11] Add to_pci_dev macro
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
                   ` (9 preceding siblings ...)
  2018-01-02  9:28 ` [RFC 10/11] IORT parsing functions to prepare requesterId maps manish.jaggi
@ 2018-01-02  9:28 ` manish.jaggi
  2018-01-18 19:15   ` Julien Grall
  2018-02-08 21:54   ` Sameer Goel
  2018-01-16 17:53 ` [RFC 00/11] acpi: arm: IORT Support for Xen Julien Grall
  11 siblings, 2 replies; 36+ messages in thread
From: manish.jaggi @ 2018-01-02  9:28 UTC (permalink / raw)
  To: xen-devel, julien.grall, sameer.goel, andre.przywara
  Cc: Manish Jaggi, manish.jaggi

From: Manish Jaggi <manish.jaggi@linaro.org>

This patch adds to_pci_dev macro

Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
---
 xen/include/xen/pci.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 43f21251a5..4c7ff4dd10 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -92,8 +92,11 @@ struct pci_dev {
 #define PT_FAULT_THRESHOLD 10
     } fault;
     u64 vf_rlen[6];
+    struct device dev;
 };
 
+#define to_pci_dev(p) container_of(p, struct pci_dev, dev)
+#define pci_domain_nr(dev) dev->seg
 #define for_each_pdev(domain, pdev) \
     list_for_each_entry(pdev, &(domain->arch.pdev_list), domain_list)
 
-- 
2.14.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid
  2018-01-02  9:27 ` [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid manish.jaggi
@ 2018-01-16 17:53   ` Julien Grall
  2018-01-16 18:31   ` Julien Grall
  1 sibling, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-01-16 17:53 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara; +Cc: manish.jaggi

Hi Manish,

On 02/01/18 09:27, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 
>   Public API to populate and query map between requester id and

The commit message should not be indented.

>   streamId/DeviceID. IORT is parsed one time (outside this patch)
>   and two lists are created one for mapping between reuesterId and streamid

s/reuesterId/requesterID/

Please stay consistent in the naming (including the lowercase/uppercase).

Cheers,

>   and another between requesterID and deviceID.
> 
>   These lists eliminate the need to reparse IORT for querying streamid
>   or deviceid using requesterid.
> 
>   Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>   xen/drivers/acpi/Makefile     |   1 +
>   xen/drivers/acpi/arm/Makefile |   1 +
>   xen/drivers/acpi/arm/ridmap.c | 124 ++++++++++++++++++++++++++++++++++++++++++
>   xen/include/acpi/ridmap.h     |  77 ++++++++++++++++++++++++++
>   4 files changed, 203 insertions(+)
> 
> diff --git a/xen/drivers/acpi/Makefile b/xen/drivers/acpi/Makefile
> index 444b11d583..80a074e007 100644
> --- a/xen/drivers/acpi/Makefile
> +++ b/xen/drivers/acpi/Makefile
> @@ -1,6 +1,7 @@
>   subdir-y += tables
>   subdir-y += utilities
>   subdir-$(CONFIG_X86) += apei
> +subdir-$(CONFIG_ARM) += arm
>   
>   obj-bin-y += tables.init.o
>   obj-$(CONFIG_NUMA) += numa.o
> diff --git a/xen/drivers/acpi/arm/Makefile b/xen/drivers/acpi/arm/Makefile
> new file mode 100644
> index 0000000000..046fad5e3d
> --- /dev/null
> +++ b/xen/drivers/acpi/arm/Makefile
> @@ -0,0 +1 @@
> +obj-y = ridmap.o
> diff --git a/xen/drivers/acpi/arm/ridmap.c b/xen/drivers/acpi/arm/ridmap.c
> new file mode 100644
> index 0000000000..2c3a8876ea
> --- /dev/null
> +++ b/xen/drivers/acpi/arm/ridmap.c
> @@ -0,0 +1,124 @@
> +/*
> + * xen/drivers/acpi/arm/ridmap.c
> + *
> + * Public API to populate and query map between requester id and
> + * streamId/DeviceID
> + *
> + * Manish Jaggi <manish.jaggi@linaro.org>
> + * Copyright (c) 2018 Linaro.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * 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.
> + */
> +
> +#include <acpi/ridmap.h>
> +#include <xen/iommu.h>
> +#include <xen/kernel.h>
> +#include <xen/list.h>
> +#include <xen/pci.h>
> +
> +struct list_head rid_streamid_map_list;
> +struct list_head rid_deviceid_map_list;
> +
> +void init_ridmaps(void)
> +{
> +    INIT_LIST_HEAD(&rid_deviceid_map_list);
> +    INIT_LIST_HEAD(&rid_streamid_map_list);
> +}
> +
> +int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
> +                         struct acpi_iort_node *smmu_node,
> +                         u32 input_base, u32 output_base, u32 id_count)
> +{
> +    struct rid_streamid_map *rid_map;
> +    rid_map = xzalloc(struct rid_streamid_map);
> +
> +    if (!rid_map)
> +        return -ENOMEM;
> +
> +    rid_map->idmap.input_base = input_base;
> +    rid_map->idmap.output_base = output_base;
> +    rid_map->idmap.id_count = id_count;
> +    rid_map->pcirc_node = pcirc_node;
> +    rid_map->smmu_node = smmu_node;
> +
> +    list_add_tail(&rid_map->entry, &rid_streamid_map_list);
> +    return 0;
> +}
> +
> +int add_rid_deviceid_map(struct acpi_iort_node *pcirc_node,
> +                         struct acpi_iort_node *its_node,
> +                         u32 input_base, u32 output_base, u32 id_count)
> +{
> +    struct rid_deviceid_map *rid_map;
> +    rid_map = xzalloc(struct rid_deviceid_map);
> +
> +    if (!rid_map)
> +        return -ENOMEM;
> +
> +    rid_map->idmap.input_base = input_base;
> +    rid_map->idmap.output_base = output_base;
> +    rid_map->idmap.id_count = id_count;
> +    rid_map->pcirc_node = pcirc_node;
> +    rid_map->its_node = its_node;
> +
> +    list_add_tail(&rid_map->entry, &rid_deviceid_map_list);
> +    return 0;
> +}
> +
> +void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, u32 *streamid,
> +                    struct acpi_iort_node **smmu_node)
> +{
> +    struct rid_streamid_map *rmap;
> +
> +    list_for_each_entry(rmap, &rid_streamid_map_list, entry)
> +    {
> +        if (rmap->pcirc_node == pcirc_node)
> +        {
> +            if ( (rid >= rmap->idmap.input_base) &&
> +                 (rid < rmap->idmap.input_base + rmap->idmap.id_count) )
> +            {
> +                *streamid = rid - rmap->idmap.input_base +
> +                            rmap->idmap.output_base;
> +                *smmu_node = rmap->smmu_node;
> +                break;
> +            }
> +        }
> +    }
> +
> +}
> +
> +void query_deviceid(struct acpi_iort_node *pcirc_node, u16 rid, u32 *deviceid)
> +{
> +    struct rid_deviceid_map *rmap;
> +
> +    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
> +    {
> +        if (rmap->pcirc_node == pcirc_node)
> +        {
> +            if ( (rid >= rmap->idmap.input_base) &&
> +                 (rid < rmap->idmap.input_base + rmap->idmap.id_count) )
> +            {
> +                *deviceid = rid - rmap->idmap.input_base +
> +                            rmap->idmap.output_base;
> +                break;
> +            }
> +        }
> +    }
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/include/acpi/ridmap.h b/xen/include/acpi/ridmap.h
> new file mode 100644
> index 0000000000..806f401d89
> --- /dev/null
> +++ b/xen/include/acpi/ridmap.h
> @@ -0,0 +1,77 @@
> +/*
> + * xen/include/acpi/ridmap.h
> + *
> + * Mapping structures to hold map between requester id and streamId/DeviceID
> + * after paring the IORT table.
> + *
> + * Manish Jaggi <manish.jaggi@linaro.org>
> + * Copyright (c) 2018 Linaro.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * 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.
> + */
> +
> +#ifndef RID_MAP_H
> +#define RID_MAP_H
> +
> +#include <xen/acpi.h>
> +
> +struct id_map_struct
> +{
> +    u16 input_base;
> +    u32 output_base;
> +    u16 id_count;
> +};
> +
> +struct rid_streamid_map
> +{
> +    struct acpi_iort_node *pcirc_node;
> +    struct id_map_struct idmap;
> +    struct list_head entry;
> +    struct acpi_iort_node *smmu_node;
> +};
> +
> +struct rid_deviceid_map
> +{
> +    struct acpi_iort_node *pcirc_node;
> +    struct acpi_iort_node *its_node;
> +    struct id_map_struct idmap;
> +    struct list_head entry;
> +};
> +
> +extern struct list_head rid_streamid_map_list;
> +extern struct list_head rid_deviceid_map_list;
> +
> +int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
> +                         struct acpi_iort_node *smmu_node,
> +                         u32 input_base, u32 output_base, u32 id_count);
> +
> +int add_rid_deviceid_map(struct acpi_iort_node *pcirc_node,
> +                         struct acpi_iort_node *its_node,
> +                         u32 input_base, u32 output_base, u32 id_count);
> +
> +void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, u32 *streamid,
> +                    struct acpi_iort_node **smmu_node);
> +
> +void query_deviceid(struct acpi_iort_node *pcirc_node,
> +                    u16 rid, u32 *deviceid);
> +
> +void init_ridmaps(void);
> +
> +#endif
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> 

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 00/11] acpi: arm: IORT Support for Xen
  2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
                   ` (10 preceding siblings ...)
  2018-01-02  9:28 ` [RFC 11/11] Add to_pci_dev macro manish.jaggi
@ 2018-01-16 17:53 ` Julien Grall
  11 siblings, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-01-16 17:53 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara; +Cc: manish.jaggi

Hi Manish,

On 02/01/18 09:27, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 
> This patch aims to add the support of IORT in Xen. Below is the list
> of major components which this patchset provides.
> a. Add support for parsing the IORT
> b. Provides API to populate/query requesterid - streamID mappings and
>     reuqesterid - deviceid mappings
> c. The requesterid - deviceid mappings is used to create the IORT for
>     hardware domain (which hides smmu nodes from IORT)
> d. iort.c fwnode.h fwspec code is imported from linux and modified.
> e. Few kernel helper routines are also imported from linux.

A link to the design document or a copy would have been helpful here.

Cheers,

> 
> This patchset compiles with [1]  [RFC v4 0/8] SMMUv3 driver.
> 
> [1] https://lists.xen.org/archives/html/xen-devel/2017-12/msg01294.html
> 
> Manish Jaggi (11):
>    acpi: arm: Public API for populating and query based on requesterid
>    acpi: arm: API to query estimated size of hardware domain's IORT
>    acpi: arm: Code to generate Hardware Domains IORT
>    acpi: arm: Import iort.c and acpi_iort.h
>    acpi: arm: Import fwnode.h from linux
>    acpi: arm: fwnode xen spacific changes
>    Add kernel helper functions
>    Add ACPI_IORT config
>    acpi: arm: Xen IORT Changes
>    acpi: arm: IORT parsing functions to prepare requesterId maps
>    Add to_pci_dev macro
> 
>   xen/arch/arm/Kconfig            |   5 +
>   xen/arch/arm/domain_build.c     |  40 ++-
>   xen/arch/arm/setup.c            |   2 +
>   xen/drivers/acpi/Kconfig        |   3 +
>   xen/drivers/acpi/Makefile       |   1 +
>   xen/drivers/acpi/arm/Makefile   |   3 +
>   xen/drivers/acpi/arm/gen-iort.c | 352 +++++++++++++++++++++++++
>   xen/drivers/acpi/arm/iort.c     | 569 ++++++++++++++++++++++++++++++++++++++++
>   xen/drivers/acpi/arm/ridmap.c   | 124 +++++++++
>   xen/drivers/passthrough/iommu.c |  75 ++++++
>   xen/include/acpi/acpi_iort.h    |  57 ++++
>   xen/include/acpi/gen-iort.h     |   7 +
>   xen/include/acpi/ridmap.h       |  77 ++++++
>   xen/include/asm-arm/acpi.h      |   1 +
>   xen/include/asm-arm/device.h    |  11 +-
>   xen/include/xen/fwnode.h        | 125 +++++++++
>   xen/include/xen/iommu.h         |  22 ++
>   xen/include/xen/kernel.h        |  10 +
>   xen/include/xen/pci.h           |   3 +
>   19 files changed, 1484 insertions(+), 3 deletions(-)
>   create mode 100644 xen/drivers/acpi/arm/Makefile
>   create mode 100644 xen/drivers/acpi/arm/gen-iort.c
>   create mode 100644 xen/drivers/acpi/arm/iort.c
>   create mode 100644 xen/drivers/acpi/arm/ridmap.c
>   create mode 100644 xen/include/acpi/acpi_iort.h
>   create mode 100644 xen/include/acpi/gen-iort.h
>   create mode 100644 xen/include/acpi/ridmap.h
>   create mode 100644 xen/include/xen/fwnode.h
> 

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid
  2018-01-02  9:27 ` [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid manish.jaggi
  2018-01-16 17:53   ` Julien Grall
@ 2018-01-16 18:31   ` Julien Grall
  2018-01-19  6:05     ` Manish Jaggi
  1 sibling, 1 reply; 36+ messages in thread
From: Julien Grall @ 2018-01-16 18:31 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara; +Cc: manish.jaggi

Hi Manish,

I sent the previous e-mail too soon.

On 02/01/18 09:27, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 
>   Public API to populate and query map between requester id and
>   streamId/DeviceID. IORT is parsed one time (outside this patch)
>   and two lists are created one for mapping between reuesterId and streamid
>   and another between requesterID and deviceID.
> 
>   These lists eliminate the need to reparse IORT for querying streamid
>   or deviceid using requesterid.
> 
>   Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>   xen/drivers/acpi/Makefile     |   1 +
>   xen/drivers/acpi/arm/Makefile |   1 +

We have a directory arch/arm/acpi/. So please move all your code there.

>   xen/drivers/acpi/arm/ridmap.c | 124 ++++++++++++++++++++++++++++++++++++++++++
>   xen/include/acpi/ridmap.h     |  77 ++++++++++++++++++++++++++

No need to make this header available in common. That should go under 
asm-arm/acpi/

>   4 files changed, 203 insertions(+)
> 
> diff --git a/xen/drivers/acpi/Makefile b/xen/drivers/acpi/Makefile
> index 444b11d583..80a074e007 100644
> --- a/xen/drivers/acpi/Makefile
> +++ b/xen/drivers/acpi/Makefile
> @@ -1,6 +1,7 @@
>   subdir-y += tables
>   subdir-y += utilities
>   subdir-$(CONFIG_X86) += apei
> +subdir-$(CONFIG_ARM) += arm
>   
>   obj-bin-y += tables.init.o
>   obj-$(CONFIG_NUMA) += numa.o
> diff --git a/xen/drivers/acpi/arm/Makefile b/xen/drivers/acpi/arm/Makefile
> new file mode 100644
> index 0000000000..046fad5e3d
> --- /dev/null
> +++ b/xen/drivers/acpi/arm/Makefile
> @@ -0,0 +1 @@
> +obj-y = ridmap.o
> diff --git a/xen/drivers/acpi/arm/ridmap.c b/xen/drivers/acpi/arm/ridmap.c
> new file mode 100644
> index 0000000000..2c3a8876ea
> --- /dev/null
> +++ b/xen/drivers/acpi/arm/ridmap.c
> @@ -0,0 +1,124 @@
> +/*
> + * xen/drivers/acpi/arm/ridmap.c
> + *
> + * Public API to populate and query map between requester id and
> + * streamId/DeviceID

I don't care whether you use deviceID or DeviceID but please stay 
consistent with the naming.

> + *
> + * Manish Jaggi <manish.jaggi@linaro.org>
> + * Copyright (c) 2018 Linaro.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.

Xen is GPLv2 only and hence the copyright wrong. You want to use:

This program is free software; you can redistribute it and/or modify it
under the terms and conditions 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.
> + */
> +
> +#include <acpi/ridmap.h>
> +#include <xen/iommu.h>
> +#include <xen/kernel.h>
> +#include <xen/list.h>
> +#include <xen/pci.h>
> +
> +struct list_head rid_streamid_map_list;
> +struct list_head rid_deviceid_map_list;

Please drop _list. This is pointless to know that when you can discover it.

Also, can you explain the rationale of using an unsorted list over 
another structure? Along that please give an idea how often and where 
the query API will be used.

> +
> +void init_ridmaps(void)

This likely need to be __init.

> +{
> +    INIT_LIST_HEAD(&rid_deviceid_map_list);
> +    INIT_LIST_HEAD(&rid_streamid_map_list);
> +}

This function is not necessary. Declaring 
LIST_HEAD(rid_streamid_map_list) will do the trick.

> +
> +int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,

Ditto.

> +                         struct acpi_iort_node *smmu_node,
> +                         u32 input_base, u32 output_base, u32 id_count)

u32 & co should not be used in new code (unless imported from Linux). 
Please use uint32_t & co.

> +{
> +    struct rid_streamid_map *rid_map;

Newline here as it should be between after declarations.


> +    rid_map = xzalloc(struct rid_streamid_map);
> +
> +    if (!rid_map)

This should be ( ... ).

> +        return -ENOMEM;

You either return -ENOMEM or 0 in this function. It sounds like to me 
that bool would be the best.

> +
> +    rid_map->idmap.input_base = input_base;
> +    rid_map->idmap.output_base = output_base;
> +    rid_map->idmap.id_count = id_count;
> +    rid_map->pcirc_node = pcirc_node;
> +    rid_map->smmu_node = smmu_node;
> +
> +    list_add_tail(&rid_map->entry, &rid_streamid_map_list);

Newline here.

> +    return 0;
> +}
> +
> +int add_rid_deviceid_map(struct acpi_iort_node *pcirc_node,
> +                         struct acpi_iort_node *its_node,
> +                         u32 input_base, u32 output_base, u32 id_count)

s/u*/uint_/

> +{
> +    struct rid_deviceid_map *rid_map;

Newline here.

> +    rid_map = xzalloc(struct rid_deviceid_map);
> +
> +    if (!rid_map)

Coding style.

> +        return -ENOMEM;
> +
> +    rid_map->idmap.input_base = input_base;
> +    rid_map->idmap.output_base = output_base;
> +    rid_map->idmap.id_count = id_count;
> +    rid_map->pcirc_node = pcirc_node;
> +    rid_map->its_node = its_node;
> +
> +    list_add_tail(&rid_map->entry, &rid_deviceid_map_list);

Newline here.

> +    return 0;
> +}
> +
> +void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, u32 *streamid,

s/u*/uint_/

But how come the rid is 16-bit here when Linux is using 32-bit?

Also, I am a bit puzzled how the caller is expected to use it. From the 
name I would expect the function to return whether a translation was 
found. But it returns void.

IHMO, this is a pretty bad idea and make more expectation on the value 
for the caller.

Lastly, I would appreciate documentation on at least the function exported.

> +                    struct acpi_iort_node **smmu_node)
> +{
> +    struct rid_streamid_map *rmap;
> +
> +    list_for_each_entry(rmap, &rid_streamid_map_list, entry)
> +    {
> +        if (rmap->pcirc_node == pcirc_node)

Coding style.

> +        {
> +            if ( (rid >= rmap->idmap.input_base) &&
> +                 (rid < rmap->idmap.input_base + rmap->idmap.id_count) )
> +            {
> +                *streamid = rid - rmap->idmap.input_base +
> +                            rmap->idmap.output_base;
> +                *smmu_node = rmap->smmu_node;
> +                break;
> +            }
> +        }
> +    }
> +
> +}
> +
> +void query_deviceid(struct acpi_iort_node *pcirc_node, u16 rid, u32 *deviceid)

Ditto for everything above within this function.

> +{
> +    struct rid_deviceid_map *rmap;
> +
> +    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
> +    {
> +        if (rmap->pcirc_node == pcirc_node)
> +        {
> +            if ( (rid >= rmap->idmap.input_base) &&
> +                 (rid < rmap->idmap.input_base + rmap->idmap.id_count) )
> +            {
> +                *deviceid = rid - rmap->idmap.input_base +
> +                            rmap->idmap.output_base;
> +                break;
> +            }
> +        }
> +    }
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/include/acpi/ridmap.h b/xen/include/acpi/ridmap.h
> new file mode 100644
> index 0000000000..806f401d89
> --- /dev/null
> +++ b/xen/include/acpi/ridmap.h
> @@ -0,0 +1,77 @@
> +/*
> + * xen/include/acpi/ridmap.h
> + *
> + * Mapping structures to hold map between requester id and streamId/DeviceID
> + * after paring the IORT table.

s/paring/parsing/

I think it would be clearer if you say:

Defitions for structure holding mapping between a requesterID and 
streamID/DeviceID.

> + *
> + * Manish Jaggi <manish.jaggi@linaro.org>
> + * Copyright (c) 2018 Linaro.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.

Wrong license.

> + *
> + * 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.
> + */
> +
> +#ifndef RID_MAP_H

We usually had the directory name in the guard to prevent potential

> +#define RID_MAP_H
> +
> +#include <xen/acpi.h>
> +
> +struct id_map_struct

Saying struct in the name is a bit pointless given you will always use 
it with "struct ..." before.

I would also appreciate some documentation within this header.


> +{
> +    u16 input_base;

uint_ same below.

> +    u32 output_base;
> +    u16 id_count;
> +};
> +
> +struct rid_streamid_map
> +{
> +    struct acpi_iort_node *pcirc_node;
> +    struct id_map_struct idmap;
> +    struct list_head entry;
> +    struct acpi_iort_node *smmu_node; > +};
> +
> +struct rid_deviceid_map
> +{
> +    struct acpi_iort_node *pcirc_node;
> +    struct acpi_iort_node *its_node;
> +    struct id_map_struct idmap;
> +    struct list_head entry;
> +};
> +
> +extern struct list_head rid_streamid_map_list;
> +extern struct list_head rid_deviceid_map_list;

I am not a big fan of exporting those 2 maps. But I will see how you use 
it before commenting.

For the rest of the code, see my comments in the patch.

> +
> +int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
> +                         struct acpi_iort_node *smmu_node,
> +                         u32 input_base, u32 output_base, u32 id_count);
> +
> +int add_rid_deviceid_map(struct acpi_iort_node *pcirc_node,
> +                         struct acpi_iort_node *its_node,
> +                         u32 input_base, u32 output_base, u32 id_count);
> +
> +void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, u32 *streamid,
> +                    struct acpi_iort_node **smmu_node);
> +
> +void query_deviceid(struct acpi_iort_node *pcirc_node,
> +                    u16 rid, u32 *deviceid);
> +
> +void init_ridmaps(void);
> +
> +#endif
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> 

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 02/11] acpi: arm: API to query estimated size of hardware domain's IORT
  2018-01-02  9:28 ` [RFC 02/11] acpi: arm: API to query estimated size of hardware domain's IORT manish.jaggi
@ 2018-01-16 18:52   ` Julien Grall
  2018-01-19  6:10     ` Manish Jaggi
  0 siblings, 1 reply; 36+ messages in thread
From: Julien Grall @ 2018-01-16 18:52 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara; +Cc: manish.jaggi

Hi Manish,

On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 
>   Code to query estimated IORT size for hardware domain.

Please avoid indenting the commit message.

>   IORT for hardware domain is generated using the requesterId and deviceId map.
> 
>   Signed-off-by: Manish Jaggi <manish.jaggi@linaro.com>
> ---
>   xen/arch/arm/domain_build.c     |  12 ++++-
>   xen/drivers/acpi/arm/Makefile   |   1 +
>   xen/drivers/acpi/arm/gen-iort.c | 101 ++++++++++++++++++++++++++++++++++++++++
>   xen/include/acpi/gen-iort.h     |   6 +++
>   4 files changed, 119 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index c74f4dd69d..f5d5e3d271 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -14,6 +14,7 @@
>   #include <xen/acpi.h>
>   #include <xen/warning.h>
>   #include <acpi/actables.h>
> +#include <acpi/gen-iort.h>
>   #include <asm/device.h>
>   #include <asm/setup.h>
>   #include <asm/platform.h>
> @@ -1799,7 +1800,7 @@ static int acpi_create_fadt(struct domain *d, struct membank tbl_add[])
>   
>   static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
>   {
> -    size_t efi_size, acpi_size, madt_size;
> +    size_t efi_size, acpi_size, madt_size, iort_size;

Rather than introduce a variable for 10 instructions, you can rename 
madt_size so it can be re-used. I would be ok for this to be in the same 
patch (providing a proper commit message).

>       u64 addr;
>       struct acpi_table_rsdp *rsdp_tbl;
>       struct acpi_table_header *table;
> @@ -1840,6 +1841,15 @@ static int estimate_acpi_efi_size(struct domain *d, struct kernel_info *kinfo)
>       acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
>   
>       acpi_size += ROUNDUP(sizeof(struct acpi_table_rsdp), 8);
> +
> +    if( estimate_iort_size(&iort_size) )

Coding style.

> +    {
> +        printk("Unable to get hwdom iort size\n");
> +        return -EINVAL;
> +    }
> +
> +    acpi_size += ROUNDUP(iort_size, 8);
> +
>       d->arch.efi_acpi_len = PAGE_ALIGN(ROUNDUP(efi_size, 8)
>                                         + ROUNDUP(acpi_size, 8));
>   
> diff --git a/xen/drivers/acpi/arm/Makefile b/xen/drivers/acpi/arm/Makefile
> index 046fad5e3d..13f1a9159f 100644
> --- a/xen/drivers/acpi/arm/Makefile
> +++ b/xen/drivers/acpi/arm/Makefile
> @@ -1 +1,2 @@
>   obj-y = ridmap.o
> +obj-y += gen-iort.o
> diff --git a/xen/drivers/acpi/arm/gen-iort.c b/xen/drivers/acpi/arm/gen-iort.c
> new file mode 100644
> index 0000000000..3fc32959c6
> --- /dev/null
> +++ b/xen/drivers/acpi/arm/gen-iort.c
> @@ -0,0 +1,101 @@
> +/*
> + * xen/drivers/acpi/arm/gen-iort.c
> + *
> + * Code to generate IORT for hardware domain using the requesterId
> + * and deviceId map.
> + *
> + * Manish Jaggi <manish.jaggi@linaro.com>
> + * Copyright (c) 2018 Linaro.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.

The license is wrong (see patch #1).

> + *
> + * 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.
> + */
> +
> +#include <acpi/ridmap.h>
> +#include <xen/acpi.h>
> +
> +/*
> + * Size of hardware domains iort is calulcated based on the number of

s/iort/IORT/
s/calulcated/calculated/

> + * mappings in the requesterId - deviceId mapping list.
> + */
> +int estimate_iort_size(size_t *iort_size)
> +{
> +    int count = 0;
> +    int pcirc_count = 0;
> +    int itsg_count = 0;
> +    uint64_t *pcirc_array;
> +    uint64_t *itsg_array;

What is the rationale to store the address directly rather than "void 
*"? This would avoid the cast in the code.

> +    struct rid_deviceid_map *rmap;
> +

A bit more documention of this function would be appreciated. For 
instance, the rationale between browsing the list twice for allocation.

I actually do think this might be avoidable by storing a bit more 
information from the IORT. From the table you can easily deduced the 
number of root complex and ITS group. They could be store with the rest 
of information.

For the rest of the function, please be careful on the coding style. I 
am not going to point them all, but I expect you to fix them.

> +    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
> +        count++;
> +
> +    pcirc_array = xzalloc_bytes(sizeof(uint64_t)*count);
> +    if ( !pcirc_array )
> +        return -ENOMEM;
> +
> +    itsg_array = xzalloc_bytes(sizeof(uint64_t)*count);
> +    if ( !itsg_array )
> +        return -ENOMEM;
> +
> +    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
> +    {
> +        int i = 0;
> +
> +        for (i=0; i <= pcirc_count; i++)
> +        {
> +            if ( pcirc_array[i] == (uint64_t)rmap->pcirc_node )
> +                break;
> +            if ( i == pcirc_count )
> +            {
> +                pcirc_array[i] = (uint64_t)rmap->pcirc_node;
> +                pcirc_count++;
> +                break;
> +            }
> +        }
> +
> +        for ( i=0; i <= itsg_count; i++ )
> +        {
> +            if ( itsg_array[i] == (uint64_t) rmap->its_node )
> +                break;
> +            if ( i == itsg_count )
> +            {
> +                itsg_array[i] = (uint64_t)rmap->its_node;
> +                itsg_count++;
> +                break;
> +            }
> +        }
> +    }
> +
> +    /* Size of IORT
> +     * = Size of IORT Table Header + Size of PCIRC Header Nodes +
> +     *   Size of PCIRC nodes + Size of ITS Header nodes + Size of ITS Nodes
> +     *   + Size of Idmap nodes
> +     */
> +    *iort_size = sizeof(struct acpi_table_iort) +
> +                 pcirc_count*( (sizeof(struct acpi_iort_node) -1) +
> +                               sizeof(struct acpi_iort_root_complex) ) +
> +                 itsg_count*( (sizeof(struct acpi_iort_node) -1) +
> +                               sizeof(struct acpi_iort_its_group) ) +
> +                 count*( sizeof(struct acpi_iort_id_mapping) );
> +
> +    xfree(itsg_array);
> +    xfree(pcirc_array);
> +
> +    return 0;
> +}
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/include/acpi/gen-iort.h b/xen/include/acpi/gen-iort.h
> new file mode 100644
> index 0000000000..68e666fdce
> --- /dev/null
> +++ b/xen/include/acpi/gen-iort.h
> @@ -0,0 +1,6 @@
> +#ifndef _GEN_IORT_H
> +#define _GEN_IORT_H
> +
> +int estimate_iort_size(size_t *iort_size);
> +
> +#endif

Missing emacs magic.

> 

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 03/11] acpi: arm: Code to generate Hardware Domains IORT
  2018-01-02  9:28 ` [RFC 03/11] acpi: arm: Code to generate Hardware Domains IORT manish.jaggi
@ 2018-01-18 18:32   ` Julien Grall
  0 siblings, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-01-18 18:32 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara; +Cc: manish.jaggi

Hi,

On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 

First of all, I would expect a commit message explaining roughly the 
logic. I am only going to skim through this patch and will wait a proper 
description to fully read it.

A general comment, please respect the coding style. Most of error can be 
avoided by using the coding style from the first line you write. And you 
are also saving bandwidth review.

> Singed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>   xen/arch/arm/domain_build.c     |  28 +++++
>   xen/drivers/acpi/arm/gen-iort.c | 253 +++++++++++++++++++++++++++++++++++++++-
>   xen/include/acpi/gen-iort.h     |   1 +
>   xen/include/asm-arm/acpi.h      |   1 +
>   4 files changed, 282 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index f5d5e3d271..9831943147 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1654,6 +1654,8 @@ static int acpi_create_xsdt(struct domain *d, struct membank tbl_add[])
>                              ACPI_SIG_FADT, tbl_add[TBL_FADT].start);
>       acpi_xsdt_modify_entry(xsdt->table_offset_entry, entry_count,
>                              ACPI_SIG_MADT, tbl_add[TBL_MADT].start);
> +    acpi_xsdt_modify_entry(xsdt->table_offset_entry, entry_count,
> +                           ACPI_SIG_IORT, tbl_add[TBL_IORT].start);
>       xsdt->table_offset_entry[entry_count] = tbl_add[TBL_STAO].start;
>   
>       xsdt->header.length = table_size;
> @@ -1704,6 +1706,28 @@ static int acpi_create_stao(struct domain *d, struct membank tbl_add[])
>       return 0;
>   }
>   
> +static int acpi_create_iort(struct domain *d, struct membank tbl_add[])
> +{
> +    struct acpi_table_iort *hwdom_table;
> +    unsigned int size = 0;
> +
> +    tbl_add[TBL_IORT].start = d->arch.efi_acpi_gpa
> +                              + acpi_get_table_offset(tbl_add, TBL_IORT);
> +    hwdom_table = d->arch.efi_acpi_table
> +                              + acpi_get_table_offset(tbl_add, TBL_IORT);

This code (and probably other bits of this series) seems to assume that 
IORT is always present. This may not be true, think of a platform with 
no MSI controller or Xen built with no ITS support.

So you have to figure out whether you need to generate the IORT table 
for the hardware domain.

> +
> +    if ( prepare_iort(hwdom_table, &size) )
> +    {
> +        printk("Failed to write IORT table\n");
> +        return -EINVAL;
> +    }
> +    printk("%s %d %d \r\n", __func__, __LINE__, size);

This sounds like a debug message.

> +
> +    tbl_add[TBL_IORT].size = size;
> +    printk("%s %d %d \r\n", __func__, __LINE__, size);

Ditto.

Newline here.

> +    return 0;
> +}
> +
>   static int acpi_create_madt(struct domain *d, struct membank tbl_add[])
>   {
>       struct acpi_table_header *table = NULL;
> @@ -1899,6 +1923,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
>       if ( rc != 0 )
>           return rc;
>   
> +    rc = acpi_create_iort(d, tbl_add);
> +    if ( rc != 0 )
> +        return rc;
> +
>       rc = acpi_create_xsdt(d, tbl_add);
>       if ( rc != 0 )
>           return rc;
> diff --git a/xen/drivers/acpi/arm/gen-iort.c b/xen/drivers/acpi/arm/gen-iort.c
> index 3fc32959c6..f368000753 100644
> --- a/xen/drivers/acpi/arm/gen-iort.c
> +++ b/xen/drivers/acpi/arm/gen-iort.c
> @@ -21,6 +21,257 @@
>   #include <acpi/ridmap.h>
>   #include <xen/acpi.h>
>   
> +/*
> + * Structure of Hardware domain's IORT
> + * -----------------------------------
> + *
> + * Below is the structure of the IORT which this code generates.
> + *
> + * [IORT Header]
> + * [ITS Group 1 ]
> + * [ITS Group N ]
> + * [PCIRC Node 1]
> + * [PCIRC IDMAP entry 1]
> + * [PCIRC IDMAP entry N]
> + * [PCIRC Node N]
> + *
> + * requesterId- deviceId mapping list poplated by parsing IORT is used

s/d-/d -/
s/poplated/populated/

> + * to create nodes and idmaps.
> + * We have one small problem, how to resolve the its grooup node offset from

s/grooup/group/

> + * the firmware iort to the ones in hardware domains IORT.

s/iort/IORT/

> + *
> + * Since the ITS group node pointer stored with the rid-devid map is used
> + * to populate the ITS Group nodes in the hardware domains' IORT.
> + * We create another map to save the offset of the ITS group node written
> + * in the hardware domain IORT with the ITS node pointer in the firmware IORT.
> + *
> + * This offset is later used when writing pcirc idmaps output_reference.
> + */
> +struct its_node_offset_map
> +{
> +    struct acpi_iort_node *its_node;
> +    unsigned int offset;
> +    struct list_head entry;
> +};

newline.

> +struct list_head its_map_list;
If you use LIST_HEAD(its_map_list) you don't need to do 
LIST_HEAD_INIT(...) below.

Also, static in front. Unless this should be exported and therefore have 
a corresponding line in the header.

> +
> +int set_its_node_offset(struct acpi_iort_node *its_node, unsigned int offset)

Ditto. I am not going to point all of them. So I expect you to fix them 
by next version.

> +{
> +    struct its_node_offset_map *its_map;

Newline.

> +    list_for_each_entry(its_map, &its_map_list, entry)
> +    {
> +        if ( its_map->its_node == its_node )
> +            return 0;
> +    }

If I get it correctly, this function will create a new ITS node if there 
are not already an ITS node with a given offset. Right? Anyhow, please 
document the function.

> +
> +    its_map = xzalloc(struct its_node_offset_map);
> +    if ( !its_map )
> +        return -ENOMEM;
> +
> +    its_map->its_node = its_node;
> +    its_map->offset = offset;
> +    list_add_tail(&its_map->entry, &its_map_list);
> +
> +    return 0;
> +}

newline.

> +/*
> + * This method would be used in write_pcirc_nodes when writing idmaps

It is not really interesting to know who use it. It is more interesting 
to know what this function does.

> + */
> +unsigned int get_its_node_offset(struct acpi_iort_node *its_node)
> +{
> +    struct its_node_offset_map *its_map;

newline.

> +    list_for_each_entry(its_map, &its_map_list, entry)
> +    {
> +        if ( its_map->its_node == its_node )
> +            return its_map->offset;
> +    }
> +
> +    return 0;
> +}
> +
> +void free_its_node_offset_list(void)
> +{
> +
> +    struct its_node_offset_map *its_map;

Newline here please.

> +    list_for_each_entry(its_map, &its_map_list, entry)
> +        xfree(its_map);

That does not sound really safe. list_for_each_entry will reuse the 
current entry to find the next. But you freed it. So I think you need to 
use list_for_each_safe here.

> +
> +    list_del(&its_map_list);

Shouldn't you remove entry one by one?

> +}
> +
> +void write_its_group(u8 *iort, unsigned int *offset, unsigned int *num_nodes)

Please use uint8_t. But I think this should be char here.

> +{
> +    struct rid_deviceid_map *rmap;
> +    unsigned int of = *offset;

Looking at the code, I don't think of is useful. You can just increment 
*offset directly.

> +    int n=0;

unsigned int n = 0;

Also, newline here please.

> +    INIT_LIST_HEAD(&its_map_list);

No need for this if you use LIST_HEAD(...) for declaring the variable as 
suggested above.

> +    /*
> +     * rid_deviceid_map_list is iterated to get unique its group nodes
> +     * Each unique ITS group node is written in hardware domains IORT
> +     * by using some values from the firmware ITS group node.
> +     */
> +    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
> +    {
> +        struct acpi_iort_node *node;
> +        struct acpi_iort_its_group *grp;
> +        struct acpi_iort_its_group *fw_grp;
> +
> +        /* save its_node_offset_map in a list uniquely */
> +        if ( !set_its_node_offset(rmap->its_node, of) )

I am a bit confused here. Shouldn't you return an error if you are 
unable to save the ITS node offset?

> +        {
> +            node = (struct acpi_iort_node *) &iort[of];
> +            grp = (struct acpi_iort_its_group *)(&node->node_data);
> +
> +            node->type = ACPI_IORT_NODE_ITS_GROUP;
> +            node->length = sizeof(struct acpi_iort_node) +
> +                           sizeof(struct acpi_iort_its_group) -
> +                           sizeof(node->node_data);
> +
> +            node->revision = rmap->its_node->revision;

I am not sure this is correct. You copy the revision from the IORT but 
generate it from scratch. What if the host IORT has been upgrade to a 
newer revision? But here you still generate rev 1 (I think). So you will 
confuse the hardware domain kernel.

> +            node->reserved = 0;
> +            node->mapping_count = 0;
> +            node->mapping_offset= 0;

I single line comment would be nice here to explain why mapping_count is 0.

> +
> +            fw_grp = (struct acpi_iort_its_group *)(&rmap->its_node->node_data);
> +
> +            grp->its_count = fw_grp->its_count;
> +            grp->identifiers[0] = fw_grp->identifiers[0];
> +
> +            of += node->length;
> +            n++;
> +        }
> +    }
> +    *offset = of;
> +    *num_nodes = n;
> +}
> +
> +/* It is assumed that rid_map_devid is sorted by pcirc_nodes */
> +void write_pcirc_nodes(u8 *iort, unsigned int *pos, unsigned int *num_nodes)
> +{
> +    struct acpi_iort_node *opcirc_node, *pcirc_node;
> +    struct acpi_iort_node *hwdom_pcirc_node = NULL;
> +    struct rid_deviceid_map *rmap;
> +    struct acpi_iort_id_mapping *idmap;
> +    int num_idmap = 0, n = 0;

Any integer should be unsigned if you don't plan to use signed value.

> +    unsigned int old_pos = *pos;

Same remark as 'of' above.

> +
> +    opcirc_node = NULL;
> +    /* Iterate rid_map_devid list */
> +    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
> +    {
> +        struct acpi_iort_root_complex *rc;
> +        struct acpi_iort_root_complex *rc_fw;
> +        int add_node = 0;

bool

> +        pcirc_node = rmap->pcirc_node;
> +
> +        if ( opcirc_node == NULL ) /* First entry */
> +        {
> +            add_node = 1;
> +        }
> +        else if ( opcirc_node != pcirc_node ) /* another pci_rc_node found*/
> +        {
> +            /* All the idmaps of a pcirc are written, now update node info*/
> +            hwdom_pcirc_node->length = num_idmap *
> +                                       sizeof(struct acpi_iort_id_mapping) +
> +                                       sizeof(struct acpi_iort_node) +
> +                                       sizeof(struct acpi_iort_root_complex) -
> +                                       sizeof(pcirc_node->node_data);

Can you abstract the sizeof(...) + ... there are very similar in this 
function and make quite difficult to read the code.

> +
> +            hwdom_pcirc_node->mapping_count = num_idmap;
> +            hwdom_pcirc_node->mapping_offset = sizeof(struct acpi_iort_node) +
> +                                               sizeof(struct acpi_iort_root_complex) -
> +                                               sizeof(pcirc_node->node_data);
> +            old_pos += hwdom_pcirc_node->length;
> +            add_node = 1;
> +        }
> +
> +        if ( add_node ) /* create the pcirc node */
> +        {
> +            opcirc_node = pcirc_node;
> +            hwdom_pcirc_node = (struct acpi_iort_node *)&iort[old_pos];
> +            hwdom_pcirc_node->type = ACPI_IORT_NODE_PCI_ROOT_COMPLEX;
> +            hwdom_pcirc_node->mapping_offset = sizeof(struct acpi_iort_node) +
> +                                               sizeof(struct acpi_iort_root_complex) -
> +                                               sizeof(hwdom_pcirc_node->node_data);
> +
> +            rc = (struct acpi_iort_root_complex *)
> +                  &hwdom_pcirc_node->node_data;

This is quite difficult to read. Is there any possibility to introduce a 
macro or just break down function?

> +
> +            rc_fw = (struct acpi_iort_root_complex *)
> +                     &pcirc_node->node_data;
> +
> +            rc->pci_segment_number = rc_fw->pci_segment_number;
> +            rc->ats_attribute = rc_fw->ats_attribute;
> +            rc->memory_properties = rc_fw->memory_properties;
> +
> +            idmap = ACPI_ADD_PTR(struct acpi_iort_id_mapping,
> +                                 hwdom_pcirc_node,
> +                                 hwdom_pcirc_node->mapping_offset);
> +            n++;
> +            num_idmap = 0;
> +        }
> +
> +        idmap->input_base = rmap->idmap.input_base;
> +        idmap->id_count = rmap->idmap.id_count;
> +        idmap->output_base = rmap->idmap.output_base;
> +        idmap->output_reference = get_its_node_offset(rmap->its_node);
> +        idmap->flags = 0;
> +
> +        idmap++;
> +        num_idmap++;
> +    }
> +
> +    if ( hwdom_pcirc_node ) /* if no further PCIRC nodes found */
> +    {
> +        /* All the idmaps of a pcirc are written, now update node info*/
> +        hwdom_pcirc_node->length = num_idmap *
> +                                   sizeof(struct acpi_iort_id_mapping) +
> +                                   sizeof(struct acpi_iort_node) +
> +                                   sizeof(struct acpi_iort_root_complex) -1;
> +
> +        hwdom_pcirc_node->mapping_count = num_idmap;
> +        old_pos += hwdom_pcirc_node->length;
> +    }
> +
> +    *pos = old_pos;
> +    *num_nodes = n;
> +}
> +
> +int prepare_iort(struct acpi_table_iort *hwdom_iort, unsigned int *iort_size)
> +{
> +    struct acpi_table_iort *fw_iort;
> +    unsigned int num_nodes = 0;
> +    unsigned int pos;
> +
> +    pos = sizeof(struct acpi_table_iort);
> +
> +    if ( acpi_get_table(ACPI_SIG_IORT, 0,
> +         (struct acpi_table_header **)&fw_iort) )
> +    {
> +        printk("Failed to get IORT table\n");
> +        return -ENODEV;
> +    }
> +
> +    /* Write IORT header */
> +    ACPI_MEMCPY(hwdom_iort, fw_iort, sizeof(struct acpi_table_iort));

Please use memcpy. But is it valid to copy the header from the host one?


> +    hwdom_iort->node_offset = pos;
> +    hwdom_iort->node_count = 0;
> +
> +    /* Write its group nodes */
> +    write_its_group((u8*)hwdom_iort, &pos, &num_nodes);
> +    hwdom_iort->node_count = num_nodes;
> +    /* Write pcirc_nodes*/
> +    write_pcirc_nodes((u8*)hwdom_iort, &pos, &num_nodes);

I am pretty sure we spoke about it before. You don't handle named 
components. What is the plan for that?


> +    /* Update IORT Size in IORT header */
> +    hwdom_iort->node_count += num_nodes;
> +    hwdom_iort->header.length = pos;
> +    hwdom_iort->header.checksum = 0; /* TODO */
> +
> +    *iort_size = hwdom_iort->header.length;
> +
> +    return 0;
> +}
> +
>   /*
>    * Size of hardware domains iort is calulcated based on the number of
>    * mappings in the requesterId - deviceId mapping list.
> @@ -49,7 +300,7 @@ int estimate_iort_size(size_t *iort_size)
>       {
>           int i = 0;
>   
> -        for (i=0; i <= pcirc_count; i++)
> +        for ( i=0; i <= pcirc_count; i++ )

This belong to the patch where you add this line.

>           {
>               if ( pcirc_array[i] == (uint64_t)rmap->pcirc_node )
>                   break;
> diff --git a/xen/include/acpi/gen-iort.h b/xen/include/acpi/gen-iort.h
> index 68e666fdce..4de31b7b9f 100644
> --- a/xen/include/acpi/gen-iort.h
> +++ b/xen/include/acpi/gen-iort.h
> @@ -2,5 +2,6 @@
>   #define _GEN_IORT_H
>   
>   int estimate_iort_size(size_t *iort_size);
> +int prepare_iort(struct acpi_table_iort *hwdom_iort, unsigned int *iort_size);
>   
>   #endif
> diff --git a/xen/include/asm-arm/acpi.h b/xen/include/asm-arm/acpi.h
> index c183b6bb6e..f8b5254621 100644
> --- a/xen/include/asm-arm/acpi.h
> +++ b/xen/include/asm-arm/acpi.h
> @@ -36,6 +36,7 @@ typedef enum {
>       TBL_FADT,
>       TBL_MADT,
>       TBL_STAO,
> +    TBL_IORT,
>       TBL_XSDT,
>       TBL_RSDP,
>       TBL_EFIT,
> 

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 06/11] fwnode xen spacific changes
  2018-01-02  9:28 ` [RFC 06/11] fwnode xen spacific changes manish.jaggi
@ 2018-01-18 18:51   ` Julien Grall
  2018-03-06 10:27     ` Manish Jaggi
  2018-03-06 13:43     ` Manish Jaggi
  0 siblings, 2 replies; 36+ messages in thread
From: Julien Grall @ 2018-01-18 18:51 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: Jan Beulich, manish.jaggi

Hi Manish,

Please use scripts/get_maintainers.pl to CC relevant maintainers. I have 
done it for you this time.


Title: s/spacific/specific/

On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 
> Merge few more changes from linux kernel code (v4.14) into iommu.c
> Modify code specifc to xen.

I appreciate you pick-up the series from Sameer. I would also have 
appreciated if you have addressed my remarks from there.

Sameer explain why he imported fwnode. This has been dropped here. Also,
I think you probably want a bit more context in the commit message about 
implement fwnode.h in common code.

Within this series, fwnode seems to only be used by Arm. So what would 
be the advantage to get that in xen/? Is it going to be used by x86 or 
taken advantage in common code?

> 
> Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>   xen/drivers/passthrough/iommu.c | 75 +++++++++++++++++++++++++++++++++++++++++
>   xen/include/asm-arm/device.h    | 11 ++++--
>   xen/include/xen/iommu.h         | 22 ++++++++++++
>   3 files changed, 106 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c
> index 1aecf7cf34..408f44106d 100644
> --- a/xen/drivers/passthrough/iommu.c
> +++ b/xen/drivers/passthrough/iommu.c
> @@ -13,6 +13,7 @@
>    */
>   
>   #include <xen/sched.h>
> +#include <xen/fwnode.h>
>   #include <xen/iommu.h>
>   #include <xen/paging.h>
>   #include <xen/guest_access.h>
> @@ -507,6 +508,80 @@ static void iommu_dump_p2m_table(unsigned char key)
>       }
>   }
>   
> +/**
> + * fwnode_handle_put - Drop reference to a device node
> + * @fwnode: Pointer to the device node to drop the reference to.
> + *
> + * This has to be used when terminating device_for_each_child_node() iteration
> + * with break or return to prevent stale device node references from being left
> + * behind.
> + */
> +void fwnode_handle_put(struct fwnode_handle *fwnode)
> +{
> +        fwnode_call_void_op(fwnode, put);

This file is following Xen coding style. And therefore you should use 
Xen coding.

> +}
> +
> +const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
> +{
> +       return iommu_get_ops();
> +}
> +
> +int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
> +                     const struct iommu_ops *ops)
> +{
> +       struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> +
> +       if (fwspec)
> +               return ops == fwspec->ops ? 0 : -EINVAL;
> +
> +       fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);

You define kzalloc in a later patch and hence break the build. *All* the 
patches should build one by one to help bisectability.

But given the side of the code and the fact you are going to fix the 
coding style. It might be easier to use Xen name here.

> +       if (!fwspec)
> +               return -ENOMEM;
> +#if 0
> +       of_node_get(to_of_node(iommu_fwnode));
> +#endif
> +       fwspec->iommu_fwnode = iommu_fwnode; > +       fwspec->ops = ops;
> +       dev->iommu_fwspec = fwspec;
> +       return 0;
> +}
> +
> +void iommu_fwspec_free(struct device *dev)
> +{
> +       struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> +
> +       if (fwspec) {
> +               fwnode_handle_put(fwspec->iommu_fwnode);
> +               kfree(fwspec);
> +               dev->iommu_fwspec = NULL;
> +       }
> +}
> +
> +int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
> +{
> +  struct iommu_fwspec *fwspec = dev->iommu_fwspec;
> +        size_t size;
> +        int i;
> +
> +        if (!fwspec)
> +                return -EINVAL;
> +
> +        size = offsetof(struct iommu_fwspec, ids[fwspec->num_ids + num_ids]);
> +        if (size > sizeof(*fwspec)) {
> +                //TBD: fwspec = krealloc(dev->iommu_fwspec, size, GFP_KERNEL);

Hmmm?

> +                if (!fwspec)
> +                        return -ENOMEM;
> +
> +                dev->iommu_fwspec = fwspec;
> +        }
> +
> +        for (i = 0; i < num_ids; i++)
> +                fwspec->ids[fwspec->num_ids + i] = ids[i];
> +
> +        fwspec->num_ids += num_ids;
> +        return 0;
> +
> +}
>   /*
>    * Local variables:
>    * mode: C
> diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
> index 6734ae8efd..f78482ca0c 100644
> --- a/xen/include/asm-arm/device.h
> +++ b/xen/include/asm-arm/device.h
> @@ -6,6 +6,8 @@
>   enum device_type
>   {
>       DEV_DT,
> +    DEV_ACPI,

You don't use DEV_ACPI in this patch. So why is there?

> +    DEV_PCI,
>   };
>   
>   struct dev_archdata {
> @@ -18,8 +20,13 @@ struct device
>       enum device_type type;
>   #ifdef CONFIG_HAS_DEVICE_TREE
>       struct dt_device_node *of_node; /* Used by drivers imported from Linux */

As said on Sameer's patches, I was expecting a todo in the code after 
the discussion about leave of_node here.

> +#endif
> +#ifdef CONFIG_ACPI
> +    void *acpi_node;

You don't use acpi_node in this patch. So why is it there?

>   #endif
>       struct dev_archdata archdata;
> +    struct fwnode_handle *fwnode; /* firmware device node */

Ditto.

> +    struct iommu_fwspec *iommu_fwspec;
>   };
>   
>   typedef struct device device_t;
> @@ -27,8 +34,8 @@ typedef struct device device_t;
>   #include <xen/device_tree.h>
>   
>   /* TODO: Correctly implement dev_is_pci when PCI is supported on ARM */
> -#define dev_is_pci(dev) ((void)(dev), 0)
> -#define dev_is_dt(dev)  ((dev->type == DEV_DT)
> +#define dev_is_pci(dev) (dev->type == DEV_PCI)
> +#define dev_is_dt(dev)  (dev->type == DEV_DT)

Those two changes does not belong to this patch. It is likely 2 separate 
patches:
     1# fixing dev_is_dt because of the missing parenthese
     2# implementing dev_is_dt

>   
>   enum device_class
>   {
> diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
> index 33c8b221dc..56b169bae9 100644
> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -208,4 +208,26 @@ DECLARE_PER_CPU(bool_t, iommu_dont_flush_iotlb);
>   extern struct spinlock iommu_pt_cleanup_lock;
>   extern struct page_list_head iommu_pt_cleanup_list;
>   
> +/**
> + * struct iommu_fwspec - per-device IOMMU instance data
> + * @ops: ops for this device's IOMMU
> + * @iommu_fwnode: firmware handle for this device's IOMMU
> + * @iommu_priv: IOMMU driver private data for this device
> + * @num_ids: number of associated device IDs
> + * @ids: IDs which this device may present to the IOMMU
> + */
> +struct iommu_fwspec {
> +        const struct iommu_ops  *ops;
> +        struct fwnode_handle    *iommu_fwnode;
> +        void                    *iommu_priv;
> +        unsigned int            num_ids;
> +        u32                     ids[1];
> +};
> +
> +int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
> +                      const struct iommu_ops *ops);
> +void iommu_fwspec_free(struct device *dev);
> +int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
> +const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
> +
>   #endif /* _IOMMU_H_ */
> 

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 07/11] Add kernel helper functions
  2018-01-02  9:28 ` [RFC 07/11] Add kernel helper functions manish.jaggi
@ 2018-01-18 18:55   ` Julien Grall
  2018-01-19  9:33     ` Jan Beulich
  2018-02-08 21:56   ` Sameer Goel
  1 sibling, 1 reply; 36+ messages in thread
From: Julien Grall @ 2018-01-18 18:55 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: Tim Deegan, Stefano Stabellini, Wei Liu, George Dunlap,
	Andrew Cooper, Ian Jackson, manish.jaggi, Jan Beulich

Hi Manish,

Please use scripts/get_maitainers.pl to CC relevant maintainers.

On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 
> Add kalloc kfree functions from linux kernel.

This does not description all the functions you added. But I am really 
not convinced this is the right place to do that.

This file is included in many places that should not use kmalloc & co 
but instead Xen version.

If you still want to add it in an header, I think it would make sense to 
create a header that will contain linuxism. So it get included only 
where it is needed.

> 
> Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>   xen/include/xen/kernel.h | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h
> index 548b64da9f..78517f6caa 100644
> --- a/xen/include/xen/kernel.h
> +++ b/xen/include/xen/kernel.h
> @@ -7,6 +7,16 @@
>   
>   #include <xen/types.h>
>   
> +/* Xen: Define compatibility functions */
> +#define FW_BUG         "[Firmware Bug]: "
> +#define pr_err(fmt, ...) printk(XENLOG_ERR fmt, ## __VA_ARGS__)
> +#define pr_warn(fmt, ...) printk(XENLOG_WARNING fmt, ## __VA_ARGS__)
> +
> +/* Alias to Xen allocation helpers */
> +#define kfree xfree
> +#define kmalloc(size, flags)            _xmalloc(size, sizeof(void *))
> +#define kzalloc(size, flags)            _xzalloc(size, sizeof(void *))
> +
>   /*
>    * min()/max() macros that also do
>    * strict type-checking.. See the
> 

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 08/11] Add ACPI_IORT config
  2018-01-02  9:28 ` [RFC 08/11] Add ACPI_IORT config manish.jaggi
@ 2018-01-18 19:01   ` Julien Grall
  0 siblings, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-01-18 19:01 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: Jan Beulich, manish.jaggi

Hi  Manish,

The usual scripts/get_maintainers.pl.

On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 
> Add ACPI_IORT config
> 
> Singed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>   xen/arch/arm/Kconfig     | 5 +++++
>   xen/drivers/acpi/Kconfig | 3 +++
>   2 files changed, 8 insertions(+)
> 
> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
> index f58019d6ed..d4767d6ea3 100644
> --- a/xen/arch/arm/Kconfig
> +++ b/xen/arch/arm/Kconfig
> @@ -42,6 +42,11 @@ config ACPI
>   	  Advanced Configuration and Power Interface (ACPI) support for Xen is
>   	  an alternative to device tree on ARM64.
>   
> +config ACPI_IORT
> +	bool
> +	prompt "ACPI IORT Support" if EXPERT = "y"

No need for EXPERT here. It will get picked up by ACPI.

Also, I don't think it is useful to let the user disabling IORT. You 
either need all ACPI or not. It will get into trouble if IORT is not 
handled in Xen.

Note that I am happy to see the config ACPI_IORT here. But not exposed 
to user's choice.

> +	depends on ACPI
> +
>   config HAS_GICV3
>   	bool
>   
> diff --git a/xen/drivers/acpi/Kconfig b/xen/drivers/acpi/Kconfig
> index b64d3731fb..15ae98140c 100644
> --- a/xen/drivers/acpi/Kconfig
> +++ b/xen/drivers/acpi/Kconfig
> @@ -5,5 +5,8 @@ config ACPI
>   config ACPI_LEGACY_TABLES_LOOKUP
>   	bool
>   
> +config ACPI_IORT
> +	bool

I am not sure to understand why you define ACPI_IORT again here. It is 
already done above?

However, I don't think it is necessary to have a separate patch just for 
adding the Kconfig. You can fold into the patch that is first using it. 
BTW, I would have expected this to be patch #1 and used to gate 
compilation for any of those file.

> +
>   config NUMA
>   	bool
> 

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 09/11] Xen IORT Changes
  2018-01-02  9:28 ` [RFC 09/11] Xen IORT Changes manish.jaggi
@ 2018-01-18 19:10   ` Julien Grall
  0 siblings, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-01-18 19:10 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara; +Cc: manish.jaggi

Hi Manish,

On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 
> This patch adds xen specific changes to iort.c

When I see the diff below, it is not changed but fully rewrite.

The original file contains 1279 lines, but you remove 978 lines and add 
71. In that context, I see no value to re-use Linux code.

> 
> Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>   xen/arch/arm/setup.c          |    2 +
>   xen/drivers/acpi/arm/Makefile |    1 +
>   xen/drivers/acpi/arm/iort.c   | 1040 +++--------------------------------------
>   xen/include/acpi/acpi_iort.h  |    6 +-
>   4 files changed, 71 insertions(+), 978 deletions(-)
> 
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index 16a3b1be8e..7ada48920f 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -37,6 +37,7 @@
>   #include <xen/vmap.h>
>   #include <xen/libfdt/libfdt.h>
>   #include <xen/acpi.h>
> +#include <acpi/acpi_iort.h>
>   #include <asm/alternative.h>
>   #include <asm/page.h>
>   #include <asm/current.h>
> @@ -800,6 +801,7 @@ void __init start_xen(unsigned long boot_phys_offset,
>   
>       tasklet_subsys_init();
>   
> +    acpi_iort_init();

Please no. I can't see any reason to call acpi_iort_init() in common 
code. Instead this should be an initcall().

If you think differently, please explain why.

>   
>       xsm_dt_init();
>   
> diff --git a/xen/drivers/acpi/arm/Makefile b/xen/drivers/acpi/arm/Makefile
> index 13f1a9159f..5d16161016 100644
> --- a/xen/drivers/acpi/arm/Makefile
> +++ b/xen/drivers/acpi/arm/Makefile
> @@ -1,2 +1,3 @@
>   obj-y = ridmap.o
>   obj-y += gen-iort.o
> +obj-y += iort.o
> diff --git a/xen/drivers/acpi/arm/iort.c b/xen/drivers/acpi/arm/iort.c
> index de56394dd1..a47ee2df4c 100644
> --- a/xen/drivers/acpi/arm/iort.c
> +++ b/xen/drivers/acpi/arm/iort.c
> @@ -14,17 +14,20 @@
>    * This file implements early detection/parsing of I/O mapping
>    * reported to OS through firmware via I/O Remapping Table (IORT)
>    * IORT document number: ARM DEN 0049A
> + *
> + * Imported from Linux 4.14.0
> + * Xen Modifications : Manish Jaggi <manish.jaggi@linaro.org>
>    */
>   
>   #define pr_fmt(fmt)	"ACPI: IORT: " fmt
>   
> -#include <linux/acpi_iort.h>
> -#include <linux/iommu.h>
> -#include <linux/kernel.h>
> -#include <linux/list.h>
> -#include <linux/pci.h>
> -#include <linux/platform_device.h>
> -#include <linux/slab.h>
> +#include <acpi/acpi_iort.h>
> +#include <acpi/ridmap.h>
> +#include <xen/iommu.h>
> +#include <xen/kernel.h>
> +#include <xen/list.h>
> +#include <xen/lib.h>
> +#include <xen/pci.h>
>   
>   #define IORT_TYPE_MASK(type)	(1 << (type))
>   #define IORT_MSI_TYPE		(1 << ACPI_IORT_NODE_ITS_GROUP)
> @@ -36,6 +39,22 @@
>   #define ACPI_IORT_SMMU_V3_CAVIUM_CN99XX		0x2
>   #endif
>   
> +/* Redefine WARN macros */
> +#undef WARN
> +#undef WARN_ON
> +#define WARN(condition, format...) ({					\
> +	int __ret_warn_on = !!(condition);				\
> +	if (unlikely(__ret_warn_on))					\
> +		printk(format);						\
> +	unlikely(__ret_warn_on);					\
> +})
> +#define WARN_TAINT(cond, taint, format...) WARN(cond, format)
> +#define WARN_ON(cond)                      (!!cond)

Again, I would have appreciated if you look at the comment I made on 
Sameer series.

> +
> +
> +#define MAX_ERRNO	4095
> +#define IS_ERR_VALUE(x) unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO)

IS_ERR_VALUE already exists in Xen (see include/xen/err.h).

For the rest of the code, I will wait your answer on my first comment in 
that e-mail.

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 11/11] Add to_pci_dev macro
  2018-01-02  9:28 ` [RFC 11/11] Add to_pci_dev macro manish.jaggi
@ 2018-01-18 19:15   ` Julien Grall
  2018-02-08 21:54   ` Sameer Goel
  1 sibling, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-01-18 19:15 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Tim Deegan, manish.jaggi, Jan Beulich, Ian Jackson

Hi Manish,

Again please use scripts/get_maintainers.pl.

On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
> 
> This patch adds to_pci_dev macro

Why? Who is going to use it? If it is a patch in your series, then 
likely this patch should be before you use it.

Any in case, a commit message a bit more develop will be help.

> 
> Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>   xen/include/xen/pci.h | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
> index 43f21251a5..4c7ff4dd10 100644
> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -92,8 +92,11 @@ struct pci_dev {
>   #define PT_FAULT_THRESHOLD 10
>       } fault;
>       u64 vf_rlen[6];
> +    struct device dev;

That's common code. Please look at adding this in arch_pci_dev. But I 
would need a bit more context why you need that.

>   };
>   
> +#define to_pci_dev(p) container_of(p, struct pci_dev, dev)
> +#define pci_domain_nr(dev) dev->seg
>   #define for_each_pdev(domain, pdev) \
>       list_for_each_entry(pdev, &(domain->arch.pdev_list), domain_list)
>   
> 

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid
  2018-01-16 18:31   ` Julien Grall
@ 2018-01-19  6:05     ` Manish Jaggi
  2018-01-19 12:03       ` Julien Grall
  0 siblings, 1 reply; 36+ messages in thread
From: Manish Jaggi @ 2018-01-19  6:05 UTC (permalink / raw)
  To: Julien Grall, manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: manish.jaggi


On 01/17/2018 12:01 AM, Julien Grall wrote:
> Hi Manish,
>
Hi Julien,
Thanks for reviewing the patch.

> I sent the previous e-mail too soon.
>
> On 02/01/18 09:27, manish.jaggi@linaro.org wrote:
>> From: Manish Jaggi <manish.jaggi@linaro.org>
>>
>>   Public API to populate and query map between requester id and
>>   streamId/DeviceID. IORT is parsed one time (outside this patch)
>>   and two lists are created one for mapping between reuesterId and 
>> streamid
>>   and another between requesterID and deviceID.
>>
>>   These lists eliminate the need to reparse IORT for querying streamid
>>   or deviceid using requesterid.
>>
>>   Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
>> ---
>>   xen/drivers/acpi/Makefile     |   1 +
>>   xen/drivers/acpi/arm/Makefile |   1 +
>
> We have a directory arch/arm/acpi/. So please move all your code there.
The current files in arch/arm/acpi hold only boot time/low level code.
IMHO creating drivers/acpi/arm makes more sense.
Linux also has iort code in drivers/acpi/arm.

>
>>   xen/drivers/acpi/arm/ridmap.c | 124 
>> ++++++++++++++++++++++++++++++++++++++++++
>>   xen/include/acpi/ridmap.h     |  77 ++++++++++++++++++++++++++
>
> No need to make this header available in common. That should go under 
> asm-arm/acpi/
ok
>
>>   4 files changed, 203 insertions(+)
>>
>> diff --git a/xen/drivers/acpi/Makefile b/xen/drivers/acpi/Makefile
>> index 444b11d583..80a074e007 100644
>> --- a/xen/drivers/acpi/Makefile
>> +++ b/xen/drivers/acpi/Makefile
>> @@ -1,6 +1,7 @@
>>   subdir-y += tables
>>   subdir-y += utilities
>>   subdir-$(CONFIG_X86) += apei
>> +subdir-$(CONFIG_ARM) += arm
>>     obj-bin-y += tables.init.o
>>   obj-$(CONFIG_NUMA) += numa.o
>> diff --git a/xen/drivers/acpi/arm/Makefile 
>> b/xen/drivers/acpi/arm/Makefile
>> new file mode 100644
>> index 0000000000..046fad5e3d
>> --- /dev/null
>> +++ b/xen/drivers/acpi/arm/Makefile
>> @@ -0,0 +1 @@
>> +obj-y = ridmap.o
>> diff --git a/xen/drivers/acpi/arm/ridmap.c 
>> b/xen/drivers/acpi/arm/ridmap.c
>> new file mode 100644
>> index 0000000000..2c3a8876ea
>> --- /dev/null
>> +++ b/xen/drivers/acpi/arm/ridmap.c
>> @@ -0,0 +1,124 @@
>> +/*
>> + * xen/drivers/acpi/arm/ridmap.c
>> + *
>> + * Public API to populate and query map between requester id and
>> + * streamId/DeviceID
>
> I don't care whether you use deviceID or DeviceID but please stay 
> consistent with the naming.
ok
>
>> + *
>> + * Manish Jaggi <manish.jaggi@linaro.org>
>> + * Copyright (c) 2018 Linaro.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>
> Xen is GPLv2 only and hence the copyright wrong. You want to use:
>
> This program is free software; you can redistribute it and/or modify it
> under the terms and conditions of the GNU General Public License,
> version 2, as published by the Free Software Foundation.

I picked this copyright from xen/arch/arm/traps.c.

  * xen/arch/arm/traps.c
  *
  * ARM Trap handlers
  *
  * Copyright (c) 2011 Citrix Systems.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the Licese, or
  * (at your option) any later version.

So IIUYC, traps.c copyright is also wrong.
How do we plan to fix all other files in xen code which use the same 
copyright.
>> + *
>> + * 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.
>> + */
>> +
>> +#include <acpi/ridmap.h>
>> +#include <xen/iommu.h>
>> +#include <xen/kernel.h>
>> +#include <xen/list.h>
>> +#include <xen/pci.h>
>> +
>> +struct list_head rid_streamid_map_list;
>> +struct list_head rid_deviceid_map_list;
>
> Please drop _list. This is pointless to know that when you can 
> discover it.

I think it is not pointless.
There is a point here. :)
  _list is added to show that it is a list to make it more verbose.
Without _list the name could mean a single mapping as well.

If you care to see
xen/common/rangeset.c:27:    struct list_head range_list;

I hope you can appreciate the point.
>
> Also, can you explain the rationale of using an unsorted list over 
> another structure? 
Since rid - streamId mapping also requires pcirc_node so it would 
require two level of sorting.
First sort based on pcirc_node and next on basis of rid.
Does it makes sense to have all that complex code here ?
  as this API will be used only once per pci device
> Along that please give an idea how often and where the query API will 
> be used.
ok
BTW, this is called from pci_for_each_dma_alias code flow.
>
>> +
>> +void init_ridmaps(void)
>
> This likely need to be __init.
ok.
>
>> +{
>> +    INIT_LIST_HEAD(&rid_deviceid_map_list);
>> +    INIT_LIST_HEAD(&rid_streamid_map_list);
>> +}
>
> This function is not necessary. Declaring 
> LIST_HEAD(rid_streamid_map_list) will do the trick.
ok.
>> +
>> +int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
>
> Ditto.
Ditto for? Sorry didnt catch your point here.
>
>> +                         struct acpi_iort_node *smmu_node,
>> +                         u32 input_base, u32 output_base, u32 id_count)
>
> u32 & co should not be used in new code (unless imported from Linux). 
> Please use uint32_t & co.
I couldn't find this in xen coding style document.
Could you please point to the section which says u32 should not be used.

>
>> +{
>> +    struct rid_streamid_map *rid_map;
>
> Newline here as it should be between after declarations.
>
ok
>
>> +    rid_map = xzalloc(struct rid_streamid_map);
>> +
>> +    if (!rid_map)
>
> This should be ( ... ).
>
>> +        return -ENOMEM;
>
> You either return -ENOMEM or 0 in this function. It sounds like to me 
> that bool would be the best.
I think ENOMEM should be used here. The error code is designed 
specifically for this purpose.
>
>> +
>> +    rid_map->idmap.input_base = input_base;
>> +    rid_map->idmap.output_base = output_base;
>> +    rid_map->idmap.id_count = id_count;
>> +    rid_map->pcirc_node = pcirc_node;
>> +    rid_map->smmu_node = smmu_node;
>> +
>> +    list_add_tail(&rid_map->entry, &rid_streamid_map_list);
>
> Newline here.
>
>> +    return 0;
>> +}
>> +
>> +int add_rid_deviceid_map(struct acpi_iort_node *pcirc_node,
>> +                         struct acpi_iort_node *its_node,
>> +                         u32 input_base, u32 output_base, u32 id_count)
>
> s/u*/uint_/
See above
>
>> +{
>> +    struct rid_deviceid_map *rid_map;
>
> Newline here.
>
>> +    rid_map = xzalloc(struct rid_deviceid_map);
>> +
>> +    if (!rid_map)
>
> Coding style.
>
>> +        return -ENOMEM;
>> +
>> +    rid_map->idmap.input_base = input_base;
>> +    rid_map->idmap.output_base = output_base;
>> +    rid_map->idmap.id_count = id_count;
>> +    rid_map->pcirc_node = pcirc_node;
>> +    rid_map->its_node = its_node;
>> +
>> +    list_add_tail(&rid_map->entry, &rid_deviceid_map_list);
>
> Newline here.
>
>> +    return 0;
>> +}
>> +
>> +void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, u32 
>> *streamid,
>
> s/u*/uint_/
>
> But how come the rid is 16-bit here when Linux is using 32-bit?
IIUC rid is 16bit only. Dont know why linux is using 32bit.

rid = bus - 8bits , devfn 8bits.

 From PCI Express specification
The Requester ID is a 16-bit value that is unique for every PCI Express 
Function within a Hierarchy..

If you think it is a 32bit value please let me know how to use upper 16 
bits.

>
> Also, I am a bit puzzled how the caller is expected to use it. 
I thought it would be self explanatory query streamid based on rid.
But if it is not verbose enough for you, I will add this explicitly.

> From the name I would expect the function to return whether a 
> translation was found. But it returns void.
>
> IHMO, this is a pretty bad idea and make more expectation on the value 
> for the caller.
>
> Lastly, I would appreciate documentation on at least the function 
> exported.
ok.
>
>> +                    struct acpi_iort_node **smmu_node)
>> +{
>> +    struct rid_streamid_map *rmap;
>> +
>> +    list_for_each_entry(rmap, &rid_streamid_map_list, entry)
>> +    {
>> +        if (rmap->pcirc_node == pcirc_node)
>
> Coding style.
Can we have a checkpatch.pl for xen.
This would help in cases when code has a mix of files with linux coding 
style and xen coding style.
>
>> +        {
>> +            if ( (rid >= rmap->idmap.input_base) &&
>> +                 (rid < rmap->idmap.input_base + 
>> rmap->idmap.id_count) )
>> +            {
>> +                *streamid = rid - rmap->idmap.input_base +
>> +                            rmap->idmap.output_base;
>> +                *smmu_node = rmap->smmu_node;
>> +                break;
>> +            }
>> +        }
>> +    }
>> +
>> +}
>> +
>> +void query_deviceid(struct acpi_iort_node *pcirc_node, u16 rid, u32 
>> *deviceid)
>
> Ditto for everything above within this function.
>
>> +{
>> +    struct rid_deviceid_map *rmap;
>> +
>> +    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
>> +    {
>> +        if (rmap->pcirc_node == pcirc_node)
>> +        {
>> +            if ( (rid >= rmap->idmap.input_base) &&
>> +                 (rid < rmap->idmap.input_base + 
>> rmap->idmap.id_count) )
>> +            {
>> +                *deviceid = rid - rmap->idmap.input_base +
>> +                            rmap->idmap.output_base;
>> +                break;
>> +            }
>> +        }
>> +    }
>> +}
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/xen/include/acpi/ridmap.h b/xen/include/acpi/ridmap.h
>> new file mode 100644
>> index 0000000000..806f401d89
>> --- /dev/null
>> +++ b/xen/include/acpi/ridmap.h
>> @@ -0,0 +1,77 @@
>> +/*
>> + * xen/include/acpi/ridmap.h
>> + *
>> + * Mapping structures to hold map between requester id and 
>> streamId/DeviceID
>> + * after paring the IORT table.
>
> s/paring/parsing/
>
> I think it would be clearer if you say:
>
> Defitions for structure holding mapping between a requesterID and 
> streamID/DeviceID.
If that makes you happy, I will change it :)
>
>> + *
>> + * Manish Jaggi <manish.jaggi@linaro.org>
>> + * Copyright (c) 2018 Linaro.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>
> Wrong license.
See above.
>
>> + *
>> + * 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.
>> + */
>> +
>> +#ifndef RID_MAP_H
>
> We usually had the directory name in the guard to prevent potential
ok will change it
>
>> +#define RID_MAP_H
>> +
>> +#include <xen/acpi.h>
>> +
>> +struct id_map_struct
>
> Saying struct in the name is a bit pointless given you will always use 
> it with "struct ..." before.
>
> I would also appreciate some documentation within this header.
ok
>
>
>> +{
>> +    u16 input_base;
>
> uint_ same below.
>
>> +    u32 output_base;
>> +    u16 id_count;
>> +};
>> +
>> +struct rid_streamid_map
>> +{
>> +    struct acpi_iort_node *pcirc_node;
>> +    struct id_map_struct idmap;
>> +    struct list_head entry;
>> +    struct acpi_iort_node *smmu_node; > +};
>> +
>> +struct rid_deviceid_map
>> +{
>> +    struct acpi_iort_node *pcirc_node;
>> +    struct acpi_iort_node *its_node;
>> +    struct id_map_struct idmap;
>> +    struct list_head entry;
>> +};
>> +
>> +extern struct list_head rid_streamid_map_list;
>> +extern struct list_head rid_deviceid_map_list;
>
> I am not a big fan of exporting those 2 maps. But I will see how you 
> use it before commenting.
Lot of xen code using the same way. Is that all wrong?
>
> For the rest of the code, see my comments in the patch.
>
>> +
>> +int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
>> +                         struct acpi_iort_node *smmu_node,
>> +                         u32 input_base, u32 output_base, u32 
>> id_count);
>> +
>> +int add_rid_deviceid_map(struct acpi_iort_node *pcirc_node,
>> +                         struct acpi_iort_node *its_node,
>> +                         u32 input_base, u32 output_base, u32 
>> id_count);
>> +
>> +void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, u32 
>> *streamid,
>> +                    struct acpi_iort_node **smmu_node);
>> +
>> +void query_deviceid(struct acpi_iort_node *pcirc_node,
>> +                    u16 rid, u32 *deviceid);
>> +
>> +void init_ridmaps(void);
>> +
>> +#endif
>> +
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>>
>
> Cheers,
>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 02/11] acpi: arm: API to query estimated size of hardware domain's IORT
  2018-01-16 18:52   ` Julien Grall
@ 2018-01-19  6:10     ` Manish Jaggi
  2018-01-22 13:45       ` Julien Grall
  0 siblings, 1 reply; 36+ messages in thread
From: Manish Jaggi @ 2018-01-19  6:10 UTC (permalink / raw)
  To: Julien Grall, manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: manish.jaggi



On 01/17/2018 12:22 AM, Julien Grall wrote:
> Hi Manish,
>
Hi Julien,
Thanks for reviewing this patch.
> On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
>> From: Manish Jaggi <manish.jaggi@linaro.org>
>>
>>   Code to query estimated IORT size for hardware domain.
>
> Please avoid indenting the commit message.
ok.
>
>>   IORT for hardware domain is generated using the requesterId and 
>> deviceId map.
>>
>>   Signed-off-by: Manish Jaggi <manish.jaggi@linaro.com>
>> ---
>>   xen/arch/arm/domain_build.c     |  12 ++++-
>>   xen/drivers/acpi/arm/Makefile   |   1 +
>>   xen/drivers/acpi/arm/gen-iort.c | 101 
>> ++++++++++++++++++++++++++++++++++++++++
>>   xen/include/acpi/gen-iort.h     |   6 +++
>>   4 files changed, 119 insertions(+), 1 deletion(-)
>>
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index c74f4dd69d..f5d5e3d271 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -14,6 +14,7 @@
>>   #include <xen/acpi.h>
>>   #include <xen/warning.h>
>>   #include <acpi/actables.h>
>> +#include <acpi/gen-iort.h>
>>   #include <asm/device.h>
>>   #include <asm/setup.h>
>>   #include <asm/platform.h>
>> @@ -1799,7 +1800,7 @@ static int acpi_create_fadt(struct domain *d, 
>> struct membank tbl_add[])
>>     static int estimate_acpi_efi_size(struct domain *d, struct 
>> kernel_info *kinfo)
>>   {
>> -    size_t efi_size, acpi_size, madt_size;
>> +    size_t efi_size, acpi_size, madt_size, iort_size;
>
> Rather than introduce a variable for 10 instructions, you can rename 
> madt_size so it can be re-used. I would be ok for this to be in the 
> same patch (providing a proper commit message).
Why would you want to replace iort_size with madt_size ?
What is the harm if adding a variable makes the code more verbose.
I am not able to appreciate your point here.
>
>>       u64 addr;
>>       struct acpi_table_rsdp *rsdp_tbl;
>>       struct acpi_table_header *table;
>> @@ -1840,6 +1841,15 @@ static int estimate_acpi_efi_size(struct 
>> domain *d, struct kernel_info *kinfo)
>>       acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
>>         acpi_size += ROUNDUP(sizeof(struct acpi_table_rsdp), 8);
>> +
>> +    if( estimate_iort_size(&iort_size) )
>
> Coding style.
>
>> +    {
>> +        printk("Unable to get hwdom iort size\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    acpi_size += ROUNDUP(iort_size, 8);
>> +
>>       d->arch.efi_acpi_len = PAGE_ALIGN(ROUNDUP(efi_size, 8)
>>                                         + ROUNDUP(acpi_size, 8));
>>   diff --git a/xen/drivers/acpi/arm/Makefile 
>> b/xen/drivers/acpi/arm/Makefile
>> index 046fad5e3d..13f1a9159f 100644
>> --- a/xen/drivers/acpi/arm/Makefile
>> +++ b/xen/drivers/acpi/arm/Makefile
>> @@ -1 +1,2 @@
>>   obj-y = ridmap.o
>> +obj-y += gen-iort.o
>> diff --git a/xen/drivers/acpi/arm/gen-iort.c 
>> b/xen/drivers/acpi/arm/gen-iort.c
>> new file mode 100644
>> index 0000000000..3fc32959c6
>> --- /dev/null
>> +++ b/xen/drivers/acpi/arm/gen-iort.c
>> @@ -0,0 +1,101 @@
>> +/*
>> + * xen/drivers/acpi/arm/gen-iort.c
>> + *
>> + * Code to generate IORT for hardware domain using the requesterId
>> + * and deviceId map.
>> + *
>> + * Manish Jaggi <manish.jaggi@linaro.com>
>> + * Copyright (c) 2018 Linaro.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>
> The license is wrong (see patch #1).
Please see my comment in patch #1.
This license is used from an existing file in xen.
So there are a lot of wrong licenses in xen code.
>
>> + *
>> + * 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.
>> + */
>> +
>> +#include <acpi/ridmap.h>
>> +#include <xen/acpi.h>
>> +
>> +/*
>> + * Size of hardware domains iort is calulcated based on the number of
>
> s/iort/IORT/
> s/calulcated/calculated/
Thanks.
>
>> + * mappings in the requesterId - deviceId mapping list.
>> + */
>> +int estimate_iort_size(size_t *iort_size)
>> +{
>> +    int count = 0;
>> +    int pcirc_count = 0;
>> +    int itsg_count = 0;
>> +    uint64_t *pcirc_array;
>> +    uint64_t *itsg_array;
>
> What is the rationale to store the address directly rather than "void 
> *"? This would avoid the cast in the code.
>
>> +    struct rid_deviceid_map *rmap;
>> +
>
> A bit more documention of this function would be appreciated. For 
> instance, the rationale between browsing the list twice for allocation.
>
> I actually do think this might be avoidable by storing a bit more 
> information from the IORT. From the table you can easily deduced the 
> number of root complex and ITS group. They could be store with the 
> rest of information.
>
I will add more documentation that will explain why it is used this way.
> For the rest of the function, please be careful on the coding style. I 
> am not going to point them all, but I expect you to fix them.
>
>> +    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
>> +        count++;
>> +
>> +    pcirc_array = xzalloc_bytes(sizeof(uint64_t)*count);
>> +    if ( !pcirc_array )
>> +        return -ENOMEM;
>> +
>> +    itsg_array = xzalloc_bytes(sizeof(uint64_t)*count);
>> +    if ( !itsg_array )
>> +        return -ENOMEM;
>> +
>> +    list_for_each_entry(rmap, &rid_deviceid_map_list, entry)
>> +    {
>> +        int i = 0;
>> +
>> +        for (i=0; i <= pcirc_count; i++)
>> +        {
>> +            if ( pcirc_array[i] == (uint64_t)rmap->pcirc_node )
>> +                break;
>> +            if ( i == pcirc_count )
>> +            {
>> +                pcirc_array[i] = (uint64_t)rmap->pcirc_node;
>> +                pcirc_count++;
>> +                break;
>> +            }
>> +        }
>> +
>> +        for ( i=0; i <= itsg_count; i++ )
>> +        {
>> +            if ( itsg_array[i] == (uint64_t) rmap->its_node )
>> +                break;
>> +            if ( i == itsg_count )
>> +            {
>> +                itsg_array[i] = (uint64_t)rmap->its_node;
>> +                itsg_count++;
>> +                break;
>> +            }
>> +        }
>> +    }
>> +
>> +    /* Size of IORT
>> +     * = Size of IORT Table Header + Size of PCIRC Header Nodes +
>> +     *   Size of PCIRC nodes + Size of ITS Header nodes + Size of 
>> ITS Nodes
>> +     *   + Size of Idmap nodes
>> +     */
>> +    *iort_size = sizeof(struct acpi_table_iort) +
>> +                 pcirc_count*( (sizeof(struct acpi_iort_node) -1) +
>> +                               sizeof(struct acpi_iort_root_complex) 
>> ) +
>> +                 itsg_count*( (sizeof(struct acpi_iort_node) -1) +
>> +                               sizeof(struct acpi_iort_its_group) ) +
>> +                 count*( sizeof(struct acpi_iort_id_mapping) );
>> +
>> +    xfree(itsg_array);
>> +    xfree(pcirc_array);
>> +
>> +    return 0;
>> +}
>> +/*
>> + * Local variables:
>> + * mode: C
>> + * c-file-style: "BSD"
>> + * c-basic-offset: 4
>> + * indent-tabs-mode: nil
>> + * End:
>> + */
>> diff --git a/xen/include/acpi/gen-iort.h b/xen/include/acpi/gen-iort.h
>> new file mode 100644
>> index 0000000000..68e666fdce
>> --- /dev/null
>> +++ b/xen/include/acpi/gen-iort.h
>> @@ -0,0 +1,6 @@
>> +#ifndef _GEN_IORT_H
>> +#define _GEN_IORT_H
>> +
>> +int estimate_iort_size(size_t *iort_size);
>> +
>> +#endif
>
> Missing emacs magic.
>
>>
>
> Cheers,
>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 07/11] Add kernel helper functions
  2018-01-18 18:55   ` Julien Grall
@ 2018-01-19  9:33     ` Jan Beulich
  0 siblings, 0 replies; 36+ messages in thread
From: Jan Beulich @ 2018-01-19  9:33 UTC (permalink / raw)
  To: Julien Grall, manish.jaggi
  Cc: Tim Deegan, Stefano Stabellini, Wei Liu, George Dunlap,
	Andrew Cooper, Ian Jackson, andre.przywara, manish.jaggi,
	sameer.goel, xen-devel

>>> On 18.01.18 at 19:55, <julien.grall@linaro.org> wrote:
> On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
>> From: Manish Jaggi <manish.jaggi@linaro.org>
>> 
>> Add kalloc kfree functions from linux kernel.
> 
> This does not description all the functions you added. But I am really 
> not convinced this is the right place to do that.
> 
> This file is included in many places that should not use kmalloc & co 
> but instead Xen version.
> 
> If you still want to add it in an header, I think it would make sense to 
> create a header that will contain linuxism. So it get included only 
> where it is needed.

Indeed - if we want such helpers at all, they should be made as
invisible to any unrelated code as possible. Since Linux sources
can't normally be imported verbatim anyway, it may be best to
have such helpers near the to of affected .c files, restricted to
just the helpers that are actually needed in each individual file.
Only if this results in meaningful duplication I would consider it
reasonable to introduce a helper header.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid
  2018-01-19  6:05     ` Manish Jaggi
@ 2018-01-19 12:03       ` Julien Grall
  2018-01-22  5:07         ` Manish Jaggi
  0 siblings, 1 reply; 36+ messages in thread
From: Julien Grall @ 2018-01-19 12:03 UTC (permalink / raw)
  To: Manish Jaggi, manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: manish.jaggi



On 19/01/18 06:05, Manish Jaggi wrote:
> 
> On 01/17/2018 12:01 AM, Julien Grall wrote:
>> Hi Manish,
>>
> Hi Julien,
> Thanks for reviewing the patch.
> 
>> I sent the previous e-mail too soon.
>>
>> On 02/01/18 09:27, manish.jaggi@linaro.org wrote:
>>> From: Manish Jaggi <manish.jaggi@linaro.org>
>>>
>>>   Public API to populate and query map between requester id and
>>>   streamId/DeviceID. IORT is parsed one time (outside this patch)
>>>   and two lists are created one for mapping between reuesterId and 
>>> streamid
>>>   and another between requesterID and deviceID.
>>>
>>>   These lists eliminate the need to reparse IORT for querying streamid
>>>   or deviceid using requesterid.
>>>
>>>   Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
>>> ---
>>>   xen/drivers/acpi/Makefile     |   1 +
>>>   xen/drivers/acpi/arm/Makefile |   1 +
>>
>> We have a directory arch/arm/acpi/. So please move all your code there.
> The current files in arch/arm/acpi hold only boot time/low level code.
> IMHO creating drivers/acpi/arm makes more sense.
> Linux also has iort code in drivers/acpi/arm.

drivers/acpi mostly contain generic ACPI code. ridmap.c and iort.c is 
AFAICT Arm specific. So arch/arm/acpi is a better place.

[...]

>>
>>> + *
>>> + * Manish Jaggi <manish.jaggi@linaro.org>
>>> + * Copyright (c) 2018 Linaro.
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>
>> Xen is GPLv2 only and hence the copyright wrong. You want to use:
>>
>> This program is free software; you can redistribute it and/or modify it
>> under the terms and conditions of the GNU General Public License,
>> version 2, as published by the Free Software Foundation.
> 
> I picked this copyright from xen/arch/arm/traps.c.
> 
>   * xen/arch/arm/traps.c
>   *
>   * ARM Trap handlers
>   *
>   * Copyright (c) 2011 Citrix Systems.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License as published by
>   * the Free Software Foundation; either version 2 of the Licese, or
>   * (at your option) any later version.
> 
> So IIUYC, traps.c copyright is also wrong.
> How do we plan to fix all other files in xen code which use the same 
> copyright.

https://lists.xenproject.org/archives/html/xen-devel/2016-09/msg02899.html

>>> + *
>>> + * 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.
>>> + */
>>> +
>>> +#include <acpi/ridmap.h>
>>> +#include <xen/iommu.h>
>>> +#include <xen/kernel.h>
>>> +#include <xen/list.h>
>>> +#include <xen/pci.h>
>>> +
>>> +struct list_head rid_streamid_map_list;
>>> +struct list_head rid_deviceid_map_list;
>>
>> Please drop _list. This is pointless to know that when you can 
>> discover it.
> 
> I think it is not pointless.
> There is a point here. :)
>   _list is added to show that it is a list to make it more verbose.
> Without _list the name could mean a single mapping as well.

When I read, rid_streamid_map. I understand it is a map of rid/streamid. 
Not a single mapping. But ...

> 
> If you care to see
> xen/common/rangeset.c:27:    struct list_head range_list;
> 
> I hope you can appreciate the point.

... look at the name length here, 10 characters. Yours is 22 characters. 
This is 1/4 of a line. That's just stupid.

>>
>> Also, can you explain the rationale of using an unsorted list over 
>> another structure? 
> Since rid - streamId mapping also requires pcirc_node so it would 
> require two level of sorting.
> First sort based on pcirc_node and next on basis of rid.
> Does it makes sense to have all that complex code here ?
>   as this API will be used only once per pci device
>> Along that please give an idea how often and where the query API will 
>> be used.
> ok
> BTW, this is called from pci_for_each_dma_alias code flow.

The document the rationale.

>>
>>> +
>>> +void init_ridmaps(void)
>>
>> This likely need to be __init.
> ok.
>>
>>> +{
>>> +    INIT_LIST_HEAD(&rid_deviceid_map_list);
>>> +    INIT_LIST_HEAD(&rid_streamid_map_list);
>>> +}
>>
>> This function is not necessary. Declaring 
>> LIST_HEAD(rid_streamid_map_list) will do the trick.
> ok.
>>> +
>>> +int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
>>
>> Ditto.
> Ditto for? Sorry didnt catch your point here.

__init.

>>
>>> +                         struct acpi_iort_node *smmu_node,
>>> +                         u32 input_base, u32 output_base, u32 id_count)
>>
>> u32 & co should not be used in new code (unless imported from Linux). 
>> Please use uint32_t & co.
> I couldn't find this in xen coding style document.
> Could you please point to the section which says u32 should not be used.

It is not in the coding style but Xen is phasing out from u*. What's the 
problem?

> 
>>
>>> +{
>>> +    struct rid_streamid_map *rid_map;
>>
>> Newline here as it should be between after declarations.
>>
> ok
>>
>>> +    rid_map = xzalloc(struct rid_streamid_map);
>>> +
>>> +    if (!rid_map)
>>
>> This should be ( ... ).
>>
>>> +        return -ENOMEM;
>>
>> You either return -ENOMEM or 0 in this function. It sounds like to me 
>> that bool would be the best.
> I think ENOMEM should be used here. The error code is designed 
> specifically for this purpose.

Fair enough.

>>> +    return 0;
>>> +}
>>> +
>>> +void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, u32 
>>> *streamid,
>>
>> s/u*/uint_/
>>
>> But how come the rid is 16-bit here when Linux is using 32-bit?
> IIUC rid is 16bit only. Dont know why linux is using 32bit.
> 
> rid = bus - 8bits , devfn 8bits.
> 
>  From PCI Express specification
> The Requester ID is a 16-bit value that is unique for every PCI Express 
> Function within a Hierarchy..
> 
> If you think it is a 32bit value please let me know how to use upper 16 
> bits.

Well AFAICT, the IORT stores 32-bit. So it is probably best to stick 
with it.

> 
>>
>> Also, I am a bit puzzled how the caller is expected to use it. 
> I thought it would be self explanatory query streamid based on rid.
> But if it is not verbose enough for you, I will add this explicitly.

Not at all. More than this function is returning void. A query function 
is usually return a bool/int.

> 
>> From the name I would expect the function to return whether a 
>> translation was found. But it returns void.
>>
>> IHMO, this is a pretty bad idea and make more expectation on the value 
>> for the caller.
>>
>> Lastly, I would appreciate documentation on at least the function 
>> exported.
> ok.
>>
>>> +                    struct acpi_iort_node **smmu_node)
>>> +{
>>> +    struct rid_streamid_map *rmap;
>>> +
>>> +    list_for_each_entry(rmap, &rid_streamid_map_list, entry)
>>> +    {
>>> +        if (rmap->pcirc_node == pcirc_node)
>>
>> Coding style.
> Can we have a checkpatch.pl for xen.
> This would help in cases when code has a mix of files with linux coding 
> style and xen coding style.

This is been worked on.

[...]

>> I am not a big fan of exporting those 2 maps. But I will see how you 
>> use it before commenting.
> Lot of xen code using the same way. Is that all wrong?

Second sentence: "I will see how you use it before commenting".

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid
  2018-01-19 12:03       ` Julien Grall
@ 2018-01-22  5:07         ` Manish Jaggi
  2018-01-22 13:40           ` Julien Grall
  0 siblings, 1 reply; 36+ messages in thread
From: Manish Jaggi @ 2018-01-22  5:07 UTC (permalink / raw)
  To: Julien Grall, manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: manish.jaggi



On 01/19/2018 05:33 PM, Julien Grall wrote:
>
>
> On 19/01/18 06:05, Manish Jaggi wrote:
>>
>> On 01/17/2018 12:01 AM, Julien Grall wrote:
>>> Hi Manish,
>>>
>> Hi Julien,
>> Thanks for reviewing the patch.
>>
>>> I sent the previous e-mail too soon.
>>>
>>> On 02/01/18 09:27, manish.jaggi@linaro.org wrote:
>>>> From: Manish Jaggi <manish.jaggi@linaro.org>
>>>>
>>>>   Public API to populate and query map between requester id and
>>>>   streamId/DeviceID. IORT is parsed one time (outside this patch)
>>>>   and two lists are created one for mapping between reuesterId and 
>>>> streamid
>>>>   and another between requesterID and deviceID.
>>>>
>>>>   These lists eliminate the need to reparse IORT for querying streamid
>>>>   or deviceid using requesterid.
>>>>
>>>>   Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
>>>> ---
>>>>   xen/drivers/acpi/Makefile     |   1 +
>>>>   xen/drivers/acpi/arm/Makefile |   1 +
>>>
>>> We have a directory arch/arm/acpi/. So please move all your code there.
>> The current files in arch/arm/acpi hold only boot time/low level code.
>> IMHO creating drivers/acpi/arm makes more sense.
>> Linux also has iort code in drivers/acpi/arm.
>
> drivers/acpi mostly contain generic ACPI code. ridmap.c and iort.c is 
> AFAICT Arm specific. So arch/arm/acpi is a better place.
ok, I will move the code.
What about iort.c ?
Should it be in drivers/acpi/arm
>
> [...]
>
>>>
>>>> + *
>>>> + * Manish Jaggi <manish.jaggi@linaro.org>
>>>> + * Copyright (c) 2018 Linaro.
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or 
>>>> modify
>>>> + * it under the terms of the GNU General Public License as 
>>>> published by
>>>> + * the Free Software Foundation; either version 2 of the License, or
>>>> + * (at your option) any later version.
>>>
>>> Xen is GPLv2 only and hence the copyright wrong. You want to use:
>>>
>>> This program is free software; you can redistribute it and/or modify it
>>> under the terms and conditions of the GNU General Public License,
>>> version 2, as published by the Free Software Foundation.
>>
>> I picked this copyright from xen/arch/arm/traps.c.
>>
>>   * xen/arch/arm/traps.c
>>   *
>>   * ARM Trap handlers
>>   *
>>   * Copyright (c) 2011 Citrix Systems.
>>   *
>>   * This program is free software; you can redistribute it and/or modify
>>   * it under the terms of the GNU General Public License as published by
>>   * the Free Software Foundation; either version 2 of the Licese, or
>>   * (at your option) any later version.
>>
>> So IIUYC, traps.c copyright is also wrong.
>> How do we plan to fix all other files in xen code which use the same 
>> copyright.
>
> https://lists.xenproject.org/archives/html/xen-devel/2016-09/msg02899.html 
>
I was not aware of this patch, will change the copyright.
Please add what copyright to be used in Xen coding guidelines document.
Moreover the patch to fix copyright is still not merged, any specific 
reason?
>>>> + *
>>>> + * 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.
>>>> + */
>>>> +
>>>> +#include <acpi/ridmap.h>
>>>> +#include <xen/iommu.h>
>>>> +#include <xen/kernel.h>
>>>> +#include <xen/list.h>
>>>> +#include <xen/pci.h>
>>>> +
>>>> +struct list_head rid_streamid_map_list;
>>>> +struct list_head rid_deviceid_map_list;
>>>
>>> Please drop _list. This is pointless to know that when you can 
>>> discover it.
>>
>> I think it is not pointless.
>> There is a point here. :)
>>   _list is added to show that it is a list to make it more verbose.
>> Without _list the name could mean a single mapping as well.
>
> When I read, rid_streamid_map. I understand it is a map of 
> rid/streamid. Not a single mapping. But ...
But In code the rid_streamid_map is used for a single mapping, so there 
has to be a proper naming.
Thats why I used a _list.

range_t and range_list. Same logic here.
>
>>
>> If you care to see
>> xen/common/rangeset.c:27:    struct list_head range_list;
>>
>> I hope you can appreciate the point.
>
> ... look at the name length here, 10 characters. Yours is 22 
> characters. This is 1/4 of a line. That's just stupid.
So your reservation is not against _list but 22 characters ?
I dont consider this stupid at all. The list is accessed in few 
functions only and it makes code more readable.
Anyway, how about rid_sid_map_list? or rid_sid_list ? Which one you prefer.
>>>
>>> Also, can you explain the rationale of using an unsorted list over 
>>> another structure? 
>> Since rid - streamId mapping also requires pcirc_node so it would 
>> require two level of sorting.
>> First sort based on pcirc_node and next on basis of rid.
>> Does it makes sense to have all that complex code here ?
>>   as this API will be used only once per pci device
>>> Along that please give an idea how often and where the query API 
>>> will be used.
>> ok
>> BTW, this is called from pci_for_each_dma_alias code flow.
>
> The document the rationale.
The/Then?
Yes I will do in v2.
>
>>>
>>>> +
>>>> +void init_ridmaps(void)
>>>
>>> This likely need to be __init.
>> ok.
>>>
>>>> +{
>>>> +    INIT_LIST_HEAD(&rid_deviceid_map_list);
>>>> +    INIT_LIST_HEAD(&rid_streamid_map_list);
>>>> +}
>>>
>>> This function is not necessary. Declaring 
>>> LIST_HEAD(rid_streamid_map_list) will do the trick.
>> ok.
>>>> +
>>>> +int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
>>>
>>> Ditto.
>> Ditto for? Sorry didnt catch your point here.
>
> __init.
_init might not be valid, I will add more documentation and you can see 
the rationale.
>
>>>
>>>> +                         struct acpi_iort_node *smmu_node,
>>>> +                         u32 input_base, u32 output_base, u32 
>>>> id_count)
>>>
>>> u32 & co should not be used in new code (unless imported from 
>>> Linux). Please use uint32_t & co. /.
>> I couldn't find this in xen coding style document.
>> Could you please point to the section which says u32 should not be used.
>
> It is not in the coding style but Xen is phasing out from u*. What's 
> the problem?
There is no problem, but It is not written anywhere so I was not sure of 
your comment.
I suggest it should be _mentioned_ in xen coding guidelines.
This will avoid all unwritten standards not being followed issues.
>
>>
>>>
>>>> +{
>>>> +    struct rid_streamid_map *rid_map;
>>>
>>> Newline here as it should be between after declarations.
>>>
>> ok
>>>
>>>> +    rid_map = xzalloc(struct rid_streamid_map);
>>>> +
>>>> +    if (!rid_map)
>>>
>>> This should be ( ... ).
>>>
>>>> +        return -ENOMEM;
>>>
>>> You either return -ENOMEM or 0 in this function. It sounds like to 
>>> me that bool would be the best.
>> I think ENOMEM should be used here. The error code is designed 
>> specifically for this purpose.
>
> Fair enough.
Thanks it is one of rare instances where you agree to my point.
>
>>>> +    return 0;
>>>> +}
>>>> +
>>>> +void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, 
>>>> u32 *streamid,
>>>
>>> s/u*/uint_/
>>>
>>> But how come the rid is 16-bit here when Linux is using 32-bit?
>> IIUC rid is 16bit only. Dont know why linux is using 32bit.
>>
>> rid = bus - 8bits , devfn 8bits.
>>
>>  From PCI Express specification
>> The Requester ID is a 16-bit value that is unique for every PCI 
>> Express Function within a Hierarchy..
>>
>> If you think it is a 32bit value please let me know how to use upper 
>> 16 bits.
>
> Well AFAICT, the IORT stores 32-bit. So it is probably best to stick 
> with it.
IORT uses 32bit and refers as input_base.
That is generic in acpi_iort_id_mapping.
Does IORT spec uses term requesterID and defines its width as 32bit?

I can keep 32bit anyways.
>
>>
>>>
>>> Also, I am a bit puzzled how the caller is expected to use it. 
>> I thought it would be self explanatory query streamid based on rid.
>> But if it is not verbose enough for you, I will add this explicitly.
>
> Not at all. More than this function is returning void. A query 
> function is usually return a bool/int.
ok will change.
>
>>
>>> From the name I would expect the function to return whether a 
>>> translation was found. But it returns void.
>>>
>>> IHMO, this is a pretty bad idea and make more expectation on the 
>>> value for the caller.
>>>
>>> Lastly, I would appreciate documentation on at least the function 
>>> exported.
>> ok.
>>>
>>>> +                    struct acpi_iort_node **smmu_node)
>>>> +{
>>>> +    struct rid_streamid_map *rmap;
>>>> +
>>>> +    list_for_each_entry(rmap, &rid_streamid_map_list, entry)
>>>> +    {
>>>> +        if (rmap->pcirc_node == pcirc_node)
>>>
>>> Coding style.
>> Can we have a checkpatch.pl for xen.
>> This would help in cases when code has a mix of files with linux 
>> coding style and xen coding style.
>
> This is been worked on.
Great!
>
> [...]
>
>>> I am not a big fan of exporting those 2 maps. But I will see how you 
>>> use it before commenting.
>> Lot of xen code using the same way. Is that all wrong?
>
> Second sentence: "I will see how you use it before commenting".
>
In that case, the comment was unwanted..
> Cheers,
>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid
  2018-01-22  5:07         ` Manish Jaggi
@ 2018-01-22 13:40           ` Julien Grall
  0 siblings, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-01-22 13:40 UTC (permalink / raw)
  To: Manish Jaggi, manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: manish.jaggi

Hi,

On 22/01/18 05:07, Manish Jaggi wrote:
> On 01/19/2018 05:33 PM, Julien Grall wrote:
>>
>>
>> On 19/01/18 06:05, Manish Jaggi wrote:
>>>
>>> On 01/17/2018 12:01 AM, Julien Grall wrote:
>>>> Hi Manish,
>>>>
>>> Hi Julien,
>>> Thanks for reviewing the patch.
>>>
>>>> I sent the previous e-mail too soon.
>>>>
>>>> On 02/01/18 09:27, manish.jaggi@linaro.org wrote:
>>>>> From: Manish Jaggi <manish.jaggi@linaro.org>
>>>>>
>>>>>   Public API to populate and query map between requester id and
>>>>>   streamId/DeviceID. IORT is parsed one time (outside this patch)
>>>>>   and two lists are created one for mapping between reuesterId and 
>>>>> streamid
>>>>>   and another between requesterID and deviceID.
>>>>>
>>>>>   These lists eliminate the need to reparse IORT for querying streamid
>>>>>   or deviceid using requesterid.
>>>>>
>>>>>   Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
>>>>> ---
>>>>>   xen/drivers/acpi/Makefile     |   1 +
>>>>>   xen/drivers/acpi/arm/Makefile |   1 +
>>>>
>>>> We have a directory arch/arm/acpi/. So please move all your code there.
>>> The current files in arch/arm/acpi hold only boot time/low level code.
>>> IMHO creating drivers/acpi/arm makes more sense.
>>> Linux also has iort code in drivers/acpi/arm.
>>
>> drivers/acpi mostly contain generic ACPI code. ridmap.c and iort.c is 
>> AFAICT Arm specific. So arch/arm/acpi is a better place.
> ok, I will move the code.
> What about iort.c ?
> Should it be in drivers/acpi/arm

I think they should be both in arch/arm/acpi. Stefano do you have any 
opinion?

>>
>> [...]
>>
>>>>
>>>>> + *
>>>>> + * Manish Jaggi <manish.jaggi@linaro.org>
>>>>> + * Copyright (c) 2018 Linaro.
>>>>> + *
>>>>> + * This program is free software; you can redistribute it and/or 
>>>>> modify
>>>>> + * it under the terms of the GNU General Public License as 
>>>>> published by
>>>>> + * the Free Software Foundation; either version 2 of the License, or
>>>>> + * (at your option) any later version.
>>>>
>>>> Xen is GPLv2 only and hence the copyright wrong. You want to use:
>>>>
>>>> This program is free software; you can redistribute it and/or modify it
>>>> under the terms and conditions of the GNU General Public License,
>>>> version 2, as published by the Free Software Foundation.
>>>
>>> I picked this copyright from xen/arch/arm/traps.c.
>>>
>>>   * xen/arch/arm/traps.c
>>>   *
>>>   * ARM Trap handlers
>>>   *
>>>   * Copyright (c) 2011 Citrix Systems.
>>>   *
>>>   * This program is free software; you can redistribute it and/or modify
>>>   * it under the terms of the GNU General Public License as published by
>>>   * the Free Software Foundation; either version 2 of the Licese, or
>>>   * (at your option) any later version.
>>>
>>> So IIUYC, traps.c copyright is also wrong.
>>> How do we plan to fix all other files in xen code which use the same 
>>> copyright.
>>
>> https://lists.xenproject.org/archives/html/xen-devel/2016-09/msg02899.html 
>>
> I was not aware of this patch, will change the copyright.
> Please add what copyright to be used in Xen coding guidelines document.

Patch are welcomed for coding style improvement.

> Moreover the patch to fix copyright is still not merged, any specific 
> reason?

Because it is unclear how you can modify the header in current code. 
Whether you need an ack from everyone who has touched the code. See the 
thread.

New code should use the GPLv2 copyright to avoid such dilemma.

>>>>> + *
>>>>> + * 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.
>>>>> + */
>>>>> +
>>>>> +#include <acpi/ridmap.h>
>>>>> +#include <xen/iommu.h>
>>>>> +#include <xen/kernel.h>
>>>>> +#include <xen/list.h>
>>>>> +#include <xen/pci.h>
>>>>> +
>>>>> +struct list_head rid_streamid_map_list;
>>>>> +struct list_head rid_deviceid_map_list;
>>>>
>>>> Please drop _list. This is pointless to know that when you can 
>>>> discover it.
>>>
>>> I think it is not pointless.
>>> There is a point here. :)
>>>   _list is added to show that it is a list to make it more verbose.
>>> Without _list the name could mean a single mapping as well.
>>
>> When I read, rid_streamid_map. I understand it is a map of 
>> rid/streamid. Not a single mapping. But ...
> But In code the rid_streamid_map is used for a single mapping, so there 
> has to be a proper naming.
> Thats why I used a _list.
> 
> range_t and range_list. Same logic here.
>>
>>>
>>> If you care to see
>>> xen/common/rangeset.c:27:    struct list_head range_list;
>>>
>>> I hope you can appreciate the point.
>>
>> ... look at the name length here, 10 characters. Yours is 22 
>> characters. This is 1/4 of a line. That's just stupid.
> So your reservation is not against _list but 22 characters ?
> I dont consider this stupid at all. The list is accessed in few 
> functions only and it makes code more readable.
> Anyway, how about rid_sid_map_list? or rid_sid_list ? Which one you prefer.

I prefer rid_sid_list.

>>>>
>>>> Also, can you explain the rationale of using an unsorted list over 
>>>> another structure? 
>>> Since rid - streamId mapping also requires pcirc_node so it would 
>>> require two level of sorting.
>>> First sort based on pcirc_node and next on basis of rid.
>>> Does it makes sense to have all that complex code here ?
>>>   as this API will be used only once per pci device
>>>> Along that please give an idea how often and where the query API 
>>>> will be used.
>>> ok
>>> BTW, this is called from pci_for_each_dma_alias code flow.
>>
>> The document the rationale.
> The/Then?

Yes then...

> Yes I will do in v2.
>>
>>>>
>>>>> +
>>>>> +void init_ridmaps(void)
>>>>
>>>> This likely need to be __init.
>>> ok.
>>>>
>>>>> +{
>>>>> +    INIT_LIST_HEAD(&rid_deviceid_map_list);
>>>>> +    INIT_LIST_HEAD(&rid_streamid_map_list);
>>>>> +}
>>>>
>>>> This function is not necessary. Declaring 
>>>> LIST_HEAD(rid_streamid_map_list) will do the trick.
>>> ok.
>>>>> +
>>>>> +int add_rid_streamid_map(struct acpi_iort_node *pcirc_node,
>>>>
>>>> Ditto.
>>> Ditto for? Sorry didnt catch your point here.
>>
>> __init.
> _init might not be valid, I will add more documentation and you can see 
> the rationale.

Do you mind giving the rationale now? Why would you call this function 
after boot?

>>
>>>>
>>>>> +                         struct acpi_iort_node *smmu_node,
>>>>> +                         u32 input_base, u32 output_base, u32 
>>>>> id_count)
>>>>
>>>> u32 & co should not be used in new code (unless imported from 
>>>> Linux). Please use uint32_t & co. /.
>>> I couldn't find this in xen coding style document.
>>> Could you please point to the section which says u32 should not be used.
>>
>> It is not in the coding style but Xen is phasing out from u*. What's 
>> the problem?
> There is no problem, but It is not written anywhere so I was not sure of 
> your comment.
> I suggest it should be _mentioned_ in xen coding guidelines.
> This will avoid all unwritten standards not being followed issues.

Patch for coding style improvement are welcomed.

>>
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>> +void query_streamid(struct acpi_iort_node *pcirc_node, u16 rid, 
>>>>> u32 *streamid,
>>>>
>>>> s/u*/uint_/
>>>>
>>>> But how come the rid is 16-bit here when Linux is using 32-bit?
>>> IIUC rid is 16bit only. Dont know why linux is using 32bit.
>>>
>>> rid = bus - 8bits , devfn 8bits.
>>>
>>>  From PCI Express specification
>>> The Requester ID is a 16-bit value that is unique for every PCI 
>>> Express Function within a Hierarchy..
>>>
>>> If you think it is a 32bit value please let me know how to use upper 
>>> 16 bits.
>>
>> Well AFAICT, the IORT stores 32-bit. So it is probably best to stick 
>> with it.
> IORT uses 32bit and refers as input_base.
> That is generic in acpi_iort_id_mapping.
> Does IORT spec uses term requesterID and defines its width as 32bit?

The IORT spec does not seem to say anything about the width of 
requesterID. So I prefer to stay on the safe side on use 32-bit.

[...]

>>>> I am not a big fan of exporting those 2 maps. But I will see how you 
>>>> use it before commenting.
>>> Lot of xen code using the same way. Is that all wrong?
>>
>> Second sentence: "I will see how you use it before commenting".
>>
> In that case, the comment was unwanted..
Probably less than "Thanks it is one of rare instances where you agree 
to my point." ;).

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 02/11] acpi: arm: API to query estimated size of hardware domain's IORT
  2018-01-19  6:10     ` Manish Jaggi
@ 2018-01-22 13:45       ` Julien Grall
  0 siblings, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-01-22 13:45 UTC (permalink / raw)
  To: Manish Jaggi, manish.jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: manish.jaggi

Hi,

On 19/01/18 06:10, Manish Jaggi wrote:
> 
> 
> On 01/17/2018 12:22 AM, Julien Grall wrote:
>>>   IORT for hardware domain is generated using the requesterId and 
>>> deviceId map.
>>>
>>>   Signed-off-by: Manish Jaggi <manish.jaggi@linaro.com>
>>> ---
>>>   xen/arch/arm/domain_build.c     |  12 ++++-
>>>   xen/drivers/acpi/arm/Makefile   |   1 +
>>>   xen/drivers/acpi/arm/gen-iort.c | 101 
>>> ++++++++++++++++++++++++++++++++++++++++
>>>   xen/include/acpi/gen-iort.h     |   6 +++
>>>   4 files changed, 119 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>>> index c74f4dd69d..f5d5e3d271 100644
>>> --- a/xen/arch/arm/domain_build.c
>>> +++ b/xen/arch/arm/domain_build.c
>>> @@ -14,6 +14,7 @@
>>>   #include <xen/acpi.h>
>>>   #include <xen/warning.h>
>>>   #include <acpi/actables.h>
>>> +#include <acpi/gen-iort.h>
>>>   #include <asm/device.h>
>>>   #include <asm/setup.h>
>>>   #include <asm/platform.h>
>>> @@ -1799,7 +1800,7 @@ static int acpi_create_fadt(struct domain *d, 
>>> struct membank tbl_add[])
>>>     static int estimate_acpi_efi_size(struct domain *d, struct 
>>> kernel_info *kinfo)
>>>   {
>>> -    size_t efi_size, acpi_size, madt_size;
>>> +    size_t efi_size, acpi_size, madt_size, iort_size;
>>
>> Rather than introduce a variable for 10 instructions, you can rename 
>> madt_size so it can be re-used. I would be ok for this to be in the 
>> same patch (providing a proper commit message).
> Why would you want to replace iort_size with madt_size ?
> What is the harm if adding a variable makes the code more verbose.
> I am not able to appreciate your point here.

I didn't ask to replace iort_size with madt_size. But rename madt_size 
to table_size or some other name that could be reused for both.

This is very similar to when you store the error return of a function. 
You are not going to name ret_foo, ret_bar, ret_fish... You are just 
going to use one variable and re-use it.

Anyway, I am not going to fight with that and just send a patch to clean 
that up once it has been merged.

[...]

>>>   diff --git a/xen/drivers/acpi/arm/Makefile 
>>> b/xen/drivers/acpi/arm/Makefile
>>> index 046fad5e3d..13f1a9159f 100644
>>> --- a/xen/drivers/acpi/arm/Makefile
>>> +++ b/xen/drivers/acpi/arm/Makefile
>>> @@ -1 +1,2 @@
>>>   obj-y = ridmap.o
>>> +obj-y += gen-iort.o
>>> diff --git a/xen/drivers/acpi/arm/gen-iort.c 
>>> b/xen/drivers/acpi/arm/gen-iort.c
>>> new file mode 100644
>>> index 0000000000..3fc32959c6
>>> --- /dev/null
>>> +++ b/xen/drivers/acpi/arm/gen-iort.c
>>> @@ -0,0 +1,101 @@
>>> +/*
>>> + * xen/drivers/acpi/arm/gen-iort.c
>>> + *
>>> + * Code to generate IORT for hardware domain using the requesterId
>>> + * and deviceId map.
>>> + *
>>> + * Manish Jaggi <manish.jaggi@linaro.com>
>>> + * Copyright (c) 2018 Linaro.
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>
>> The license is wrong (see patch #1).
> Please see my comment in patch #1.
> This license is used from an existing file in xen.
> So there are a lot of wrong licenses in xen code.

Well yes. But does it mean you have to add more wrong code? ;)

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 11/11] Add to_pci_dev macro
  2018-01-02  9:28 ` [RFC 11/11] Add to_pci_dev macro manish.jaggi
  2018-01-18 19:15   ` Julien Grall
@ 2018-02-08 21:54   ` Sameer Goel
  1 sibling, 0 replies; 36+ messages in thread
From: Sameer Goel @ 2018-02-08 21:54 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, julien.grall, andre.przywara; +Cc: manish.jaggi



On 1/2/2018 2:28 AM, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
>
> This patch adds to_pci_dev macro
>
> Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>  xen/include/xen/pci.h | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
> index 43f21251a5..4c7ff4dd10 100644
> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -92,8 +92,11 @@ struct pci_dev {
>  #define PT_FAULT_THRESHOLD 10
>      } fault;
>      u64 vf_rlen[6];
> +    struct device dev;
>  };
>  
> +#define to_pci_dev(p) container_of(p, struct pci_dev, dev)
Remove the above function from smmu.c if it needs to be defined here.
> +#define pci_domain_nr(dev) dev->seg
>  #define for_each_pdev(domain, pdev) \
>      list_for_each_entry(pdev, &(domain->arch.pdev_list), domain_list)
>  


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 07/11] Add kernel helper functions
  2018-01-02  9:28 ` [RFC 07/11] Add kernel helper functions manish.jaggi
  2018-01-18 18:55   ` Julien Grall
@ 2018-02-08 21:56   ` Sameer Goel
  1 sibling, 0 replies; 36+ messages in thread
From: Sameer Goel @ 2018-02-08 21:56 UTC (permalink / raw)
  To: manish.jaggi, xen-devel, julien.grall, andre.przywara; +Cc: manish.jaggi


On 1/2/2018 2:28 AM, manish.jaggi@linaro.org wrote:
> From: Manish Jaggi <manish.jaggi@linaro.org>
>
> Add kalloc kfree functions from linux kernel.
>
> Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
> ---
>  xen/include/xen/kernel.h | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h
> index 548b64da9f..78517f6caa 100644
> --- a/xen/include/xen/kernel.h
> +++ b/xen/include/xen/kernel.h
> @@ -7,6 +7,16 @@
>  
>  #include <xen/types.h>
>  
You might want to swap 06 and 07. Once you do that I can remove the following defines from kernel.h
> +/* Xen: Define compatibility functions */
> +#define FW_BUG         "[Firmware Bug]: "
> +#define pr_err(fmt, ...) printk(XENLOG_ERR fmt, ## __VA_ARGS__)
> +#define pr_warn(fmt, ...) printk(XENLOG_WARNING fmt, ## __VA_ARGS__)
> +
> +/* Alias to Xen allocation helpers */
> +#define kfree xfree
> +#define kmalloc(size, flags)            _xmalloc(size, sizeof(void *))
> +#define kzalloc(size, flags)            _xzalloc(size, sizeof(void *))
> +
>  /*
>   * min()/max() macros that also do
>   * strict type-checking.. See the


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 06/11] fwnode xen spacific changes
  2018-01-18 18:51   ` Julien Grall
@ 2018-03-06 10:27     ` Manish Jaggi
  2018-03-06 14:29       ` Julien Grall
  2018-03-06 13:43     ` Manish Jaggi
  1 sibling, 1 reply; 36+ messages in thread
From: Manish Jaggi @ 2018-03-06 10:27 UTC (permalink / raw)
  To: Julien Grall, xen-devel, sameer.goel, andre.przywara
  Cc: Jan Beulich, manish.jaggi



On 01/19/2018 12:21 AM, Julien Grall wrote:
> Hi Manish,
>
> Please use scripts/get_maintainers.pl to CC relevant maintainers. I 
> have done it for you this time.
>
>
> Title: s/spacific/specific/
>
> On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
>> From: Manish Jaggi <manish.jaggi@linaro.org>
>>
>> Merge few more changes from linux kernel code (v4.14) into iommu.c
>> Modify code specifc to xen.
>
> I appreciate you pick-up the series from Sameer. I would also have 
> appreciated if you have addressed my remarks from there.
>
> Sameer explain why he imported fwnode. This has been dropped here. Also,
> I think you probably want a bit more context in the commit message 
> about implement fwnode.h in common code.
>
> Within this series, fwnode seems to only be used by Arm. So what would 
> be the advantage to get that in xen/? Is it going to be used by x86 or 
> taken advantage in common code?
Do you want patch code (iommu.h iommu.c) to be moved to xen/arch/arm
In patch 4, i have created a new file xen/include/xen/fwnode.h
Should I move it to asm-arm ?
>
>>
>> Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
>> ---
>>   xen/drivers/passthrough/iommu.c | 75 
>> +++++++++++++++++++++++++++++++++++++++++
>>   xen/include/asm-arm/device.h    | 11 ++++--
>>   xen/include/xen/iommu.h         | 22 ++++++++++++
>>   3 files changed, 106 insertions(+), 2 deletions(-)
>>
>> diff --git a/xen/drivers/passthrough/iommu.c 
>> b/xen/drivers/passthrough/iommu.c
>> index 1aecf7cf34..408f44106d 100644
>> --- a/xen/drivers/passthrough/iommu.c
>> +++ b/xen/drivers/passthrough/iommu.c
>> @@ -13,6 +13,7 @@
>>    */
>>     #include <xen/sched.h>
>> +#include <xen/fwnode.h>
>>   #include <xen/iommu.h>
>>   #include <xen/paging.h>
>>   #include <xen/guest_access.h>
>> @@ -507,6 +508,80 @@ static void iommu_dump_p2m_table(unsigned char key)
>>       }
>>   }
>>   +/**
>> + * fwnode_handle_put - Drop reference to a device node
>> + * @fwnode: Pointer to the device node to drop the reference to.
>> + *
>> + * This has to be used when terminating device_for_each_child_node() 
>> iteration
>> + * with break or return to prevent stale device node references from 
>> being left
>> + * behind.
>> + */
>> +void fwnode_handle_put(struct fwnode_handle *fwnode)
>> +{
>> +        fwnode_call_void_op(fwnode, put);
>
> This file is following Xen coding style. And therefore you should use 
> Xen coding.
>
>> +}
>> +
>> +const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle 
>> *fwnode)
>> +{
>> +       return iommu_get_ops();
>> +}
>> +
>> +int iommu_fwspec_init(struct device *dev, struct fwnode_handle 
>> *iommu_fwnode,
>> +                     const struct iommu_ops *ops)
>> +{
>> +       struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>> +
>> +       if (fwspec)
>> +               return ops == fwspec->ops ? 0 : -EINVAL;
>> +
>> +       fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
>
> You define kzalloc in a later patch and hence break the build. *All* 
> the patches should build one by one to help bisectability.
>
> But given the side of the code and the fact you are going to fix the 
> coding style. It might be easier to use Xen name here.
>
>> +       if (!fwspec)
>> +               return -ENOMEM;
>> +#if 0
>> +       of_node_get(to_of_node(iommu_fwnode));
>> +#endif
>> +       fwspec->iommu_fwnode = iommu_fwnode; > + fwspec->ops = ops;
>> +       dev->iommu_fwspec = fwspec;
>> +       return 0;
>> +}
>> +
>> +void iommu_fwspec_free(struct device *dev)
>> +{
>> +       struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>> +
>> +       if (fwspec) {
>> +               fwnode_handle_put(fwspec->iommu_fwnode);
>> +               kfree(fwspec);
>> +               dev->iommu_fwspec = NULL;
>> +       }
>> +}
>> +
>> +int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
>> +{
>> +  struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>> +        size_t size;
>> +        int i;
>> +
>> +        if (!fwspec)
>> +                return -EINVAL;
>> +
>> +        size = offsetof(struct iommu_fwspec, ids[fwspec->num_ids + 
>> num_ids]);
>> +        if (size > sizeof(*fwspec)) {
>> +                //TBD: fwspec = krealloc(dev->iommu_fwspec, size, 
>> GFP_KERNEL);
>
> Hmmm?
>
>> +                if (!fwspec)
>> +                        return -ENOMEM;
>> +
>> +                dev->iommu_fwspec = fwspec;
>> +        }
>> +
>> +        for (i = 0; i < num_ids; i++)
>> +                fwspec->ids[fwspec->num_ids + i] = ids[i];
>> +
>> +        fwspec->num_ids += num_ids;
>> +        return 0;
>> +
>> +}
>>   /*
>>    * Local variables:
>>    * mode: C
>> diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
>> index 6734ae8efd..f78482ca0c 100644
>> --- a/xen/include/asm-arm/device.h
>> +++ b/xen/include/asm-arm/device.h
>> @@ -6,6 +6,8 @@
>>   enum device_type
>>   {
>>       DEV_DT,
>> +    DEV_ACPI,
>
> You don't use DEV_ACPI in this patch. So why is there?
>
>> +    DEV_PCI,
>>   };
>>     struct dev_archdata {
>> @@ -18,8 +20,13 @@ struct device
>>       enum device_type type;
>>   #ifdef CONFIG_HAS_DEVICE_TREE
>>       struct dt_device_node *of_node; /* Used by drivers imported 
>> from Linux */
>
> As said on Sameer's patches, I was expecting a todo in the code after 
> the discussion about leave of_node here.
I might have missed your comment on sameers patch, could you please restate
>
>> +#endif
>> +#ifdef CONFIG_ACPI
>> +    void *acpi_node;
>
> You don't use acpi_node in this patch. So why is it there?
>
>>   #endif
>>       struct dev_archdata archdata;
>> +    struct fwnode_handle *fwnode; /* firmware device node */
>
> Ditto.
>
>> +    struct iommu_fwspec *iommu_fwspec;
>>   };
>>     typedef struct device device_t;
>> @@ -27,8 +34,8 @@ typedef struct device device_t;
>>   #include <xen/device_tree.h>
>>     /* TODO: Correctly implement dev_is_pci when PCI is supported on 
>> ARM */
>> -#define dev_is_pci(dev) ((void)(dev), 0)
>> -#define dev_is_dt(dev)  ((dev->type == DEV_DT)
>> +#define dev_is_pci(dev) (dev->type == DEV_PCI)
>> +#define dev_is_dt(dev)  (dev->type == DEV_DT)
>
> Those two changes does not belong to this patch. It is likely 2 
> separate patches:
>     1# fixing dev_is_dt because of the missing parenthese
>     2# implementing dev_is_dt
>
>>     enum device_class
>>   {
>> diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
>> index 33c8b221dc..56b169bae9 100644
>> --- a/xen/include/xen/iommu.h
>> +++ b/xen/include/xen/iommu.h
>> @@ -208,4 +208,26 @@ DECLARE_PER_CPU(bool_t, iommu_dont_flush_iotlb);
>>   extern struct spinlock iommu_pt_cleanup_lock;
>>   extern struct page_list_head iommu_pt_cleanup_list;
>>   +/**
>> + * struct iommu_fwspec - per-device IOMMU instance data
>> + * @ops: ops for this device's IOMMU
>> + * @iommu_fwnode: firmware handle for this device's IOMMU
>> + * @iommu_priv: IOMMU driver private data for this device
>> + * @num_ids: number of associated device IDs
>> + * @ids: IDs which this device may present to the IOMMU
>> + */
>> +struct iommu_fwspec {
>> +        const struct iommu_ops  *ops;
>> +        struct fwnode_handle    *iommu_fwnode;
>> +        void                    *iommu_priv;
>> +        unsigned int            num_ids;
>> +        u32                     ids[1];
>> +};
>> +
>> +int iommu_fwspec_init(struct device *dev, struct fwnode_handle 
>> *iommu_fwnode,
>> +                      const struct iommu_ops *ops);
>> +void iommu_fwspec_free(struct device *dev);
>> +int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
>> +const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle 
>> *fwnode);
>> +
>>   #endif /* _IOMMU_H_ */
>>
>
> Cheers,
>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 06/11] fwnode xen spacific changes
  2018-01-18 18:51   ` Julien Grall
  2018-03-06 10:27     ` Manish Jaggi
@ 2018-03-06 13:43     ` Manish Jaggi
  2018-03-06 13:44       ` Manish Jaggi
  1 sibling, 1 reply; 36+ messages in thread
From: Manish Jaggi @ 2018-03-06 13:43 UTC (permalink / raw)
  To: Julien Grall, xen-devel, sameer.goel, andre.przywara
  Cc: Jan Beulich, manish.jaggi


[-- Attachment #1.1: Type: text/plain, Size: 986 bytes --]

Hi Julien,


On 01/19/2018 12:21 AM, Julien Grall wrote:
>> diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
>> index 6734ae8efd..f78482ca0c 100644
>> --- a/xen/include/asm-arm/device.h
>> +++ b/xen/include/asm-arm/device.h
>> @@ -6,6 +6,8 @@
>>   enum device_type
>>   {
>>       DEV_DT,
>> +    DEV_ACPI,
>
> You don't use DEV_ACPI in this patch. So why is there?
>
>> +    DEV_PCI,
>>   };
>>     struct dev_archdata {
>> @@ -18,8 +20,13 @@ struct device
>>       enum device_type type;
>>   #ifdef CONFIG_HAS_DEVICE_TREE
>>       struct dt_device_node *of_node; /* Used by drivers imported 
>> from Linux */
>
> As said on Sameer's patches, I was expecting a todo in the code after 
> the discussion about leave of_node here. 
I think you are referring to https://patchwork.kernel.org/patch/9963109/
Could you please add what TODO you wish to add ?

I could not find  any discussion on of_node in the mail chain


-Regards
Manish

[-- Attachment #1.2: Type: text/html, Size: 1973 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 06/11] fwnode xen spacific changes
  2018-03-06 13:43     ` Manish Jaggi
@ 2018-03-06 13:44       ` Manish Jaggi
  2018-03-06 14:22         ` Julien Grall
  0 siblings, 1 reply; 36+ messages in thread
From: Manish Jaggi @ 2018-03-06 13:44 UTC (permalink / raw)
  To: Manish Jaggi, Julien Grall, xen-devel, sameer.goel, andre.przywara
  Cc: Jan Beulich, manish.jaggi

Hi Julien,


On 01/19/2018 12:21 AM, Julien Grall wrote:
>> diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
>> index 6734ae8efd..f78482ca0c 100644
>> --- a/xen/include/asm-arm/device.h
>> +++ b/xen/include/asm-arm/device.h
>> @@ -6,6 +6,8 @@
>>   enum device_type
>>   {
>>       DEV_DT,
>> +    DEV_ACPI,
>
> You don't use DEV_ACPI in this patch. So why is there?
>
>> +    DEV_PCI,
>>   };
>>     struct dev_archdata {
>> @@ -18,8 +20,13 @@ struct device
>>       enum device_type type;
>>   #ifdef CONFIG_HAS_DEVICE_TREE
>>       struct dt_device_node *of_node; /* Used by drivers imported 
>> from Linux */
>
> As said on Sameer's patches, I was expecting a todo in the code after 
> the discussion about leave of_node here. 
I think you are referring to https://patchwork.kernel.org/patch/9963109/
Could you please add what TODO you wish to add ?

I could not find  any discussion on of_node in the mail chain


-Regards
Manish

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 06/11] fwnode xen spacific changes
  2018-03-06 13:44       ` Manish Jaggi
@ 2018-03-06 14:22         ` Julien Grall
  0 siblings, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-03-06 14:22 UTC (permalink / raw)
  To: Manish Jaggi, Manish Jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: Jan Beulich, manish.jaggi



On 06/03/18 13:44, Manish Jaggi wrote:
> Hi Julien,
> 
> 
> On 01/19/2018 12:21 AM, Julien Grall wrote:
>>> diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
>>> index 6734ae8efd..f78482ca0c 100644
>>> --- a/xen/include/asm-arm/device.h
>>> +++ b/xen/include/asm-arm/device.h
>>> @@ -6,6 +6,8 @@
>>>   enum device_type
>>>   {
>>>       DEV_DT,
>>> +    DEV_ACPI,
>>
>> You don't use DEV_ACPI in this patch. So why is there?
>>
>>> +    DEV_PCI,
>>>   };
>>>     struct dev_archdata {
>>> @@ -18,8 +20,13 @@ struct device
>>>       enum device_type type;
>>>   #ifdef CONFIG_HAS_DEVICE_TREE
>>>       struct dt_device_node *of_node; /* Used by drivers imported 
>>> from Linux */
>>
>> As said on Sameer's patches, I was expecting a todo in the code after 
>> the discussion about leave of_node here. 
> I think you are referring to https://patchwork.kernel.org/patch/9963109/
> Could you please add what TODO you wish to add ?
> 
> I could not find  any discussion on of_node in the mail chain
Usually when I say: "I was expecting ..." it means that was discussed on 
a previous version. In that case it is "[RFC 2/6] arm64: Add definitions 
for fwnode_handle".

Below the conversation:

Me: I am a bit surprised you don't rework struct dev. As of_node is now 
redundant with fwnode.

Sameer: I agree that this will eventually be removed. I have kept this 
in now just to maintain compatibility
(compilation and otherwise) with smmuv2 driver. I will add a comment to 
indicate this. So that it can
be easily identified and remove when we do a final cleanup. Can I prefix 
the comment with with XEN:TODO:?

Me: A TODO would be nice, but who is going to do the rework?

Cheers,

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [RFC 06/11] fwnode xen spacific changes
  2018-03-06 10:27     ` Manish Jaggi
@ 2018-03-06 14:29       ` Julien Grall
  0 siblings, 0 replies; 36+ messages in thread
From: Julien Grall @ 2018-03-06 14:29 UTC (permalink / raw)
  To: Manish Jaggi, xen-devel, sameer.goel, andre.przywara
  Cc: Jan Beulich, manish.jaggi



On 06/03/18 10:27, Manish Jaggi wrote:
> 
> 
> On 01/19/2018 12:21 AM, Julien Grall wrote:
>> Hi Manish,
>>
>> Please use scripts/get_maintainers.pl to CC relevant maintainers. I 
>> have done it for you this time.
>>
>>
>> Title: s/spacific/specific/
>>
>> On 02/01/18 09:28, manish.jaggi@linaro.org wrote:
>>> From: Manish Jaggi <manish.jaggi@linaro.org>
>>>
>>> Merge few more changes from linux kernel code (v4.14) into iommu.c
>>> Modify code specifc to xen.
>>
>> I appreciate you pick-up the series from Sameer. I would also have 
>> appreciated if you have addressed my remarks from there.
>>
>> Sameer explain why he imported fwnode. This has been dropped here. Also,
>> I think you probably want a bit more context in the commit message 
>> about implement fwnode.h in common code.
>>
>> Within this series, fwnode seems to only be used by Arm. So what would 
>> be the advantage to get that in xen/? Is it going to be used by x86 or 
>> taken advantage in common code?
> Do you want patch code (iommu.h iommu.c) to be moved to xen/arch/arm
> In patch 4, i have created a new file xen/include/xen/fwnode.h
> Should I move it to asm-arm ?

Please read my e-mail and answer the question. If you answer by no, then 
move it to asm-arm. If you answer by yes, then write the rationale in 
the commit message.

It looks like to me we might only need that in Arm, but I wanted your 
input as the author of the patch. You likely have a reason to put this 
code here, am I right?

Cheers,

>>
>>>
>>> Signed-off-by: Manish Jaggi <manish.jaggi@linaro.org>
>>> ---
>>>   xen/drivers/passthrough/iommu.c | 75 
>>> +++++++++++++++++++++++++++++++++++++++++
>>>   xen/include/asm-arm/device.h    | 11 ++++--
>>>   xen/include/xen/iommu.h         | 22 ++++++++++++
>>>   3 files changed, 106 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/xen/drivers/passthrough/iommu.c 
>>> b/xen/drivers/passthrough/iommu.c
>>> index 1aecf7cf34..408f44106d 100644
>>> --- a/xen/drivers/passthrough/iommu.c
>>> +++ b/xen/drivers/passthrough/iommu.c
>>> @@ -13,6 +13,7 @@
>>>    */
>>>     #include <xen/sched.h>
>>> +#include <xen/fwnode.h>
>>>   #include <xen/iommu.h>
>>>   #include <xen/paging.h>
>>>   #include <xen/guest_access.h>
>>> @@ -507,6 +508,80 @@ static void iommu_dump_p2m_table(unsigned char key)
>>>       }
>>>   }
>>>   +/**
>>> + * fwnode_handle_put - Drop reference to a device node
>>> + * @fwnode: Pointer to the device node to drop the reference to.
>>> + *
>>> + * This has to be used when terminating device_for_each_child_node() 
>>> iteration
>>> + * with break or return to prevent stale device node references from 
>>> being left
>>> + * behind.
>>> + */
>>> +void fwnode_handle_put(struct fwnode_handle *fwnode)
>>> +{
>>> +        fwnode_call_void_op(fwnode, put);
>>
>> This file is following Xen coding style. And therefore you should use 
>> Xen coding.
>>
>>> +}
>>> +
>>> +const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle 
>>> *fwnode)
>>> +{
>>> +       return iommu_get_ops();
>>> +}
>>> +
>>> +int iommu_fwspec_init(struct device *dev, struct fwnode_handle 
>>> *iommu_fwnode,
>>> +                     const struct iommu_ops *ops)
>>> +{
>>> +       struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>> +
>>> +       if (fwspec)
>>> +               return ops == fwspec->ops ? 0 : -EINVAL;
>>> +
>>> +       fwspec = kzalloc(sizeof(*fwspec), GFP_KERNEL);
>>
>> You define kzalloc in a later patch and hence break the build. *All* 
>> the patches should build one by one to help bisectability.
>>
>> But given the side of the code and the fact you are going to fix the 
>> coding style. It might be easier to use Xen name here.
>>
>>> +       if (!fwspec)
>>> +               return -ENOMEM;
>>> +#if 0
>>> +       of_node_get(to_of_node(iommu_fwnode));
>>> +#endif
>>> +       fwspec->iommu_fwnode = iommu_fwnode; > + fwspec->ops = ops;
>>> +       dev->iommu_fwspec = fwspec;
>>> +       return 0;
>>> +}
>>> +
>>> +void iommu_fwspec_free(struct device *dev)
>>> +{
>>> +       struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>> +
>>> +       if (fwspec) {
>>> +               fwnode_handle_put(fwspec->iommu_fwnode);
>>> +               kfree(fwspec);
>>> +               dev->iommu_fwspec = NULL;
>>> +       }
>>> +}
>>> +
>>> +int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids)
>>> +{
>>> +  struct iommu_fwspec *fwspec = dev->iommu_fwspec;
>>> +        size_t size;
>>> +        int i;
>>> +
>>> +        if (!fwspec)
>>> +                return -EINVAL;
>>> +
>>> +        size = offsetof(struct iommu_fwspec, ids[fwspec->num_ids + 
>>> num_ids]);
>>> +        if (size > sizeof(*fwspec)) {
>>> +                //TBD: fwspec = krealloc(dev->iommu_fwspec, size, 
>>> GFP_KERNEL);
>>
>> Hmmm?
>>
>>> +                if (!fwspec)
>>> +                        return -ENOMEM;
>>> +
>>> +                dev->iommu_fwspec = fwspec;
>>> +        }
>>> +
>>> +        for (i = 0; i < num_ids; i++)
>>> +                fwspec->ids[fwspec->num_ids + i] = ids[i];
>>> +
>>> +        fwspec->num_ids += num_ids;
>>> +        return 0;
>>> +
>>> +}
>>>   /*
>>>    * Local variables:
>>>    * mode: C
>>> diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h
>>> index 6734ae8efd..f78482ca0c 100644
>>> --- a/xen/include/asm-arm/device.h
>>> +++ b/xen/include/asm-arm/device.h
>>> @@ -6,6 +6,8 @@
>>>   enum device_type
>>>   {
>>>       DEV_DT,
>>> +    DEV_ACPI,
>>
>> You don't use DEV_ACPI in this patch. So why is there?
>>
>>> +    DEV_PCI,
>>>   };
>>>     struct dev_archdata {
>>> @@ -18,8 +20,13 @@ struct device
>>>       enum device_type type;
>>>   #ifdef CONFIG_HAS_DEVICE_TREE
>>>       struct dt_device_node *of_node; /* Used by drivers imported 
>>> from Linux */
>>
>> As said on Sameer's patches, I was expecting a todo in the code after 
>> the discussion about leave of_node here.
> I might have missed your comment on sameers patch, could you please restate
>>
>>> +#endif
>>> +#ifdef CONFIG_ACPI
>>> +    void *acpi_node;
>>
>> You don't use acpi_node in this patch. So why is it there?
>>
>>>   #endif
>>>       struct dev_archdata archdata;
>>> +    struct fwnode_handle *fwnode; /* firmware device node */
>>
>> Ditto.
>>
>>> +    struct iommu_fwspec *iommu_fwspec;
>>>   };
>>>     typedef struct device device_t;
>>> @@ -27,8 +34,8 @@ typedef struct device device_t;
>>>   #include <xen/device_tree.h>
>>>     /* TODO: Correctly implement dev_is_pci when PCI is supported on 
>>> ARM */
>>> -#define dev_is_pci(dev) ((void)(dev), 0)
>>> -#define dev_is_dt(dev)  ((dev->type == DEV_DT)
>>> +#define dev_is_pci(dev) (dev->type == DEV_PCI)
>>> +#define dev_is_dt(dev)  (dev->type == DEV_DT)
>>
>> Those two changes does not belong to this patch. It is likely 2 
>> separate patches:
>>     1# fixing dev_is_dt because of the missing parenthese
>>     2# implementing dev_is_dt
>>
>>>     enum device_class
>>>   {
>>> diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
>>> index 33c8b221dc..56b169bae9 100644
>>> --- a/xen/include/xen/iommu.h
>>> +++ b/xen/include/xen/iommu.h
>>> @@ -208,4 +208,26 @@ DECLARE_PER_CPU(bool_t, iommu_dont_flush_iotlb);
>>>   extern struct spinlock iommu_pt_cleanup_lock;
>>>   extern struct page_list_head iommu_pt_cleanup_list;
>>>   +/**
>>> + * struct iommu_fwspec - per-device IOMMU instance data
>>> + * @ops: ops for this device's IOMMU
>>> + * @iommu_fwnode: firmware handle for this device's IOMMU
>>> + * @iommu_priv: IOMMU driver private data for this device
>>> + * @num_ids: number of associated device IDs
>>> + * @ids: IDs which this device may present to the IOMMU
>>> + */
>>> +struct iommu_fwspec {
>>> +        const struct iommu_ops  *ops;
>>> +        struct fwnode_handle    *iommu_fwnode;
>>> +        void                    *iommu_priv;
>>> +        unsigned int            num_ids;
>>> +        u32                     ids[1];
>>> +};
>>> +
>>> +int iommu_fwspec_init(struct device *dev, struct fwnode_handle 
>>> *iommu_fwnode,
>>> +                      const struct iommu_ops *ops);
>>> +void iommu_fwspec_free(struct device *dev);
>>> +int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
>>> +const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle 
>>> *fwnode);
>>> +
>>>   #endif /* _IOMMU_H_ */
>>>
>>
>> Cheers,
>>
> 

-- 
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2018-03-06 14:29 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-02  9:27 [RFC 00/11] acpi: arm: IORT Support for Xen manish.jaggi
2018-01-02  9:27 ` [RFC 01/11] acpi: arm: Public API for populating and query based on requesterid manish.jaggi
2018-01-16 17:53   ` Julien Grall
2018-01-16 18:31   ` Julien Grall
2018-01-19  6:05     ` Manish Jaggi
2018-01-19 12:03       ` Julien Grall
2018-01-22  5:07         ` Manish Jaggi
2018-01-22 13:40           ` Julien Grall
2018-01-02  9:28 ` [RFC 02/11] acpi: arm: API to query estimated size of hardware domain's IORT manish.jaggi
2018-01-16 18:52   ` Julien Grall
2018-01-19  6:10     ` Manish Jaggi
2018-01-22 13:45       ` Julien Grall
2018-01-02  9:28 ` [RFC 03/11] acpi: arm: Code to generate Hardware Domains IORT manish.jaggi
2018-01-18 18:32   ` Julien Grall
2018-01-02  9:28 ` [RFC 04/11] Import iort.c and acpi_iort.h manish.jaggi
2018-01-02  9:28 ` [RFC 05/11] Import fwnode.h from linux manish.jaggi
2018-01-02  9:28 ` [RFC 06/11] fwnode xen spacific changes manish.jaggi
2018-01-18 18:51   ` Julien Grall
2018-03-06 10:27     ` Manish Jaggi
2018-03-06 14:29       ` Julien Grall
2018-03-06 13:43     ` Manish Jaggi
2018-03-06 13:44       ` Manish Jaggi
2018-03-06 14:22         ` Julien Grall
2018-01-02  9:28 ` [RFC 07/11] Add kernel helper functions manish.jaggi
2018-01-18 18:55   ` Julien Grall
2018-01-19  9:33     ` Jan Beulich
2018-02-08 21:56   ` Sameer Goel
2018-01-02  9:28 ` [RFC 08/11] Add ACPI_IORT config manish.jaggi
2018-01-18 19:01   ` Julien Grall
2018-01-02  9:28 ` [RFC 09/11] Xen IORT Changes manish.jaggi
2018-01-18 19:10   ` Julien Grall
2018-01-02  9:28 ` [RFC 10/11] IORT parsing functions to prepare requesterId maps manish.jaggi
2018-01-02  9:28 ` [RFC 11/11] Add to_pci_dev macro manish.jaggi
2018-01-18 19:15   ` Julien Grall
2018-02-08 21:54   ` Sameer Goel
2018-01-16 17:53 ` [RFC 00/11] acpi: arm: IORT Support for Xen Julien Grall

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.