[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] libxl/arm: Create specific IOMMU node to be referred by virtio-mmio device



commit ca45d3cb4586372909f350e54482246f994e1bc7
Author:     Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>
AuthorDate: Fri Jul 15 22:20:26 2022 +0300
Commit:     Julien Grall <jgrall@xxxxxxxxxx>
CommitDate: Thu Jul 28 19:26:37 2022 +0100

    libxl/arm: Create specific IOMMU node to be referred by virtio-mmio device
    
    Reuse generic IOMMU device tree bindings to communicate Xen specific
    information for the virtio devices for which the restricted memory
    access using Xen grant mappings need to be enabled.
    
    Insert "iommus" property pointed to the IOMMU node with "xen,grant-dma"
    compatible to all virtio devices which backends are going to run in
    non-hardware domains (which are non-trusted by default).
    
    Based on device-tree binding from Linux:
    Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml
    
    The example of generated nodes:
    
    xen_iommu {
        compatible = "xen,grant-dma";
        #iommu-cells = <0x01>;
        phandle = <0xfde9>;
    };
    
    virtio@2000000 {
        compatible = "virtio,mmio";
        reg = <0x00 0x2000000 0x00 0x200>;
        interrupts = <0x00 0x01 0xf01>;
        interrupt-parent = <0xfde8>;
        dma-coherent;
        iommus = <0xfde9 0x01>;
    };
    
    virtio@2000200 {
        compatible = "virtio,mmio";
        reg = <0x00 0x2000200 0x00 0x200>;
        interrupts = <0x00 0x02 0xf01>;
        interrupt-parent = <0xfde8>;
        dma-coherent;
        iommus = <0xfde9 0x01>;
    };
    
    Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
    Reviewed-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
 tools/libs/light/libxl_arm.c          | 49 ++++++++++++++++++++++++++++++++---
 xen/include/public/device_tree_defs.h |  3 ++-
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c
index 866e58c66b..1a3ac1646e 100644
--- a/tools/libs/light/libxl_arm.c
+++ b/tools/libs/light/libxl_arm.c
@@ -865,9 +865,32 @@ static int make_vpci_node(libxl__gc *gc, void *fdt,
     return 0;
 }
 
+static int make_xen_iommu_node(libxl__gc *gc, void *fdt)
+{
+    int res;
+
+    /* See Linux Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml */
+    res = fdt_begin_node(fdt, "xen_iommu");
+    if (res) return res;
+
+    res = fdt_property_compat(gc, fdt, 1, "xen,grant-dma");
+    if (res) return res;
+
+    res = fdt_property_cell(fdt, "#iommu-cells", 1);
+    if (res) return res;
+
+    res = fdt_property_cell(fdt, "phandle", GUEST_PHANDLE_IOMMU);
+    if (res) return res;
+
+    res = fdt_end_node(fdt);
+    if (res) return res;
+
+    return 0;
+}
 
 static int make_virtio_mmio_node(libxl__gc *gc, void *fdt,
-                                 uint64_t base, uint32_t irq)
+                                 uint64_t base, uint32_t irq,
+                                 uint32_t backend_domid)
 {
     int res;
     gic_interrupt intr;
@@ -890,6 +913,16 @@ static int make_virtio_mmio_node(libxl__gc *gc, void *fdt,
     res = fdt_property(fdt, "dma-coherent", NULL, 0);
     if (res) return res;
 
+    if (backend_domid != LIBXL_TOOLSTACK_DOMID) {
+        uint32_t iommus_prop[2];
+
+        iommus_prop[0] = cpu_to_fdt32(GUEST_PHANDLE_IOMMU);
+        iommus_prop[1] = cpu_to_fdt32(backend_domid);
+
+        res = fdt_property(fdt, "iommus", iommus_prop, sizeof(iommus_prop));
+        if (res) return res;
+    }
+
     res = fdt_end_node(fdt);
     if (res) return res;
 
@@ -1097,6 +1130,7 @@ static int libxl__prepare_dtb(libxl__gc *gc, 
libxl_domain_config *d_config,
     size_t fdt_size = 0;
     int pfdt_size = 0;
     libxl_domain_build_info *const info = &d_config->b_info;
+    bool iommu_created;
     unsigned int i;
 
     const libxl_version_info *vers;
@@ -1204,11 +1238,20 @@ next_resize:
         if (d_config->num_pcidevs)
             FDT( make_vpci_node(gc, fdt, ainfo, dom) );
 
+        iommu_created = false;
         for (i = 0; i < d_config->num_disks; i++) {
             libxl_device_disk *disk = &d_config->disks[i];
 
-            if (disk->specification == LIBXL_DISK_SPECIFICATION_VIRTIO)
-                FDT( make_virtio_mmio_node(gc, fdt, disk->base, disk->irq) );
+            if (disk->specification == LIBXL_DISK_SPECIFICATION_VIRTIO) {
+                if (disk->backend_domid != LIBXL_TOOLSTACK_DOMID &&
+                    !iommu_created) {
+                    FDT( make_xen_iommu_node(gc, fdt) );
+                    iommu_created = true;
+                }
+
+                FDT( make_virtio_mmio_node(gc, fdt, disk->base, disk->irq,
+                                           disk->backend_domid) );
+            }
         }
 
         if (pfdt)
diff --git a/xen/include/public/device_tree_defs.h 
b/xen/include/public/device_tree_defs.h
index 209d43de3f..228daafe81 100644
--- a/xen/include/public/device_tree_defs.h
+++ b/xen/include/public/device_tree_defs.h
@@ -4,9 +4,10 @@
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
 /*
  * The device tree compiler (DTC) is allocating the phandle from 1 to
- * onwards. Reserve a high value for the GIC phandle.
+ * onwards. Reserve high values for the specific phandles.
  */
 #define GUEST_PHANDLE_GIC (65000)
+#define GUEST_PHANDLE_IOMMU (GUEST_PHANDLE_GIC + 1)
 
 #define GUEST_ROOT_ADDRESS_CELLS 2
 #define GUEST_ROOT_SIZE_CELLS 2
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.