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

Re: [Xen-devel] [PATCH v5 5/8] xen/arm: assign devices to boot domains



On Fri, 27 Sep 2019, Julien Grall wrote:
> Hi,
> 
> On 27/09/2019 15:40, Oleksandr wrote:
> > 
> > On 26.09.19 00:12, Julien Grall wrote:
> >> On 25/09/2019 19:49, Stefano Stabellini wrote:
> >>> Scan the user provided dtb fragment at boot. For each device node, map
> >>> memory to guests, and route interrupts and setup the iommu.
> >>>
> >>> The memory region to remap is specified by the "xen,reg" property.
> >>>
> >>> The iommu is setup by passing the node of the device to assign on the
> >>> host device tree. The path is specified in the device tree fragment as
> >>> the "xen,path" string property.
> >>>
> >>> The interrupts are remapped based on the information from the
> >>> corresponding node on the host device tree. Call
> >>> handle_device_interrupts to remap interrupts. Interrupts related device
> >>> tree properties are copied from the device tree fragment, same as all
> >>> the other properties.
> >>>
> >>> Also add the new flag XEN_DOMCTL_CDF_iommu to that dom0less domU can use
> >>> the IOMMU.
> >>>
> >>> Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx>
> >>> ---
> >>> Changes in v5:
> >>> - use local variable for name
> >>> - use map_regions_p2mt
> >>> - add warning for not page aligned addresses/sizes
> >>> - introduce handle_passthrough_prop
> >>>
> >>> Changes in v4:
> >>> - use unsigned
> >>> - improve commit message
> >>> - code style
> >>> - use dt_prop_cmp
> >>> - use device_tree_get_reg
> >>> - don't copy over xen,reg and xen,path
> >>> - don't create special interrupt properties for domU: copy them from the
> >>>     fragment
> >>> - in-code comment
> >>>
> >>> Changes in v3:
> >>> - improve commit message
> >>> - remove superfluous cast
> >>> - merge code with the copy code
> >>> - add interrup-parent
> >>> - demove depth > 2 check
> >>> - reuse code from handle_device_interrupts
> >>> - copy interrupts from host dt
> >>>
> >>> Changes in v2:
> >>> - rename "path" to "xen,path"
> >>> - grammar fix
> >>> - use gaddr_to_gfn and maddr_to_mfn
> >>> - remove depth <= 2 limitation in scanning the dtb fragment
> >>> - introduce and parse xen,reg
> >>> - code style
> >>> - support more than one interrupt per device
> >>> - specify only the GIC is supported
> >>> ---
> >>>    xen/arch/arm/domain_build.c | 101 
> >>> ++++++++++++++++++++++++++++++++++--
> >>>    1 file changed, 97 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> >>> index 9d985d3bbe..414893bc24 100644
> >>> --- a/xen/arch/arm/domain_build.c
> >>> +++ b/xen/arch/arm/domain_build.c
> >>> @@ -1701,6 +1701,85 @@ static int __init make_vpl011_uart_node(struct 
> >>> kernel_info *kinfo)
> >>>    }
> >>>    #endif
> >>> +/*
> >>> + * Scan device tree properties for passthrough specific information.
> >>> + * Returns -ENOENT when no passthrough properties are found
> >>> + *         < 0 on error
> >>> + *         0 on success
> >>> + */
> >>> +static int __init handle_passthrough_prop(struct kernel_info *kinfo,
> >>> +                                          const struct fdt_property 
> >>> *prop,
> >>> +                                          const char *name,
> >>> +                                          uint32_t address_cells, 
> >>> uint32_t size_cells)
> >>> +{
> >>> +    const __be32 *cell;
> >>> +    unsigned int i, len;
> >>> +    struct dt_device_node *node;
> >>> +    int res;
> >>> +
> >>> +    /* xen,reg specifies where to map the MMIO region */
> >>> +    if ( dt_prop_cmp("xen,reg", name) == 0 )
> >>> +    {
> >>> +        paddr_t mstart, size, gstart;
> >>> +        cell = (const __be32 *)prop->data;
> >>> +        len = fdt32_to_cpu(prop->len) /
> >>> +            ((address_cells * 2 + size_cells) * sizeof(uint32_t));
> >>> +
> >>> +        for ( i = 0; i < len; i++ )
> >>> +        {
> >>> +            device_tree_get_reg(&cell, address_cells, size_cells,
> >>> +                    &mstart, &size);
> >>> +            gstart = dt_next_cell(address_cells, &cell);
> >>> +
> >>> +            if ( gstart & ~PAGE_MASK || mstart & ~PAGE_MASK || size 
> >>> & ~PAGE_MASK )
> >>> +                dprintk(XENLOG_WARNING,
> >>> +                        "DomU passthrough config has not page 
> >>> aligned addresses/sizes\n");
> >> I don't think this is wise to continue, the more this is a printk that
> >> can only happen in debug build. So someone using a release build may not
> >> notice the error.
> >>
> >> So I think this wants to be a printk(XENLOG_ERR,...) and also return an
> >> error.
> >>
> >>> +
> >>> +            res = map_regions_p2mt(kinfo->d,
> >>> +                    gaddr_to_gfn(gstart),
> >>> +                    PFN_DOWN(size),
> >>> +                    maddr_to_mfn(mstart),
> >>> +                    p2m_mmio_direct_dev);
> >> Coding style.
> >>
> >>> +            if ( res < 0 )
> >>> +            {
> >>> +                dprintk(XENLOG_ERR,
> >>> +                        "Failed to map %"PRIpaddr" to the guest 
> >>> at%"PRIpaddr"\n",
> >>> +                        mstart, gstart);
> >> Similarly, this wants to be a printk.
> >>
> >>> +                return -EFAULT;
> >>> +            }
> >>> +        }
> >>> +
> >>> +        return 0;
> >>> +    }
> >>> +    /*
> >>> +     * xen,path specifies the corresponding node in the host DT.
> >>> +     * Both interrupt mappings and IOMMU settings are based on it,
> >>> +     * as they are done based on the corresponding host DT node.
> >>> +     */
> >>> +    else if ( dt_prop_cmp("xen,path", name) == 0 )
> >>> +    {
> >>> +        node = dt_find_node_by_path(prop->data);
> >>> +        if ( node == NULL )
> >>> +        {
> >>> +            dprintk(XENLOG_ERR, "Couldn't find node %s in host_dt!\n",
> >>> +                    (char *)prop->data);
> >> Same here.
> >>
> >>> +            return -EINVAL;
> >>> +        }
> > 
> > I have to admit that I don't know about dom0less feature enough ...
> > 
> > 
> > But, shouldn't we check if the device is behind the IOMMU and try to add 
> > it (iommu_add_dt_device) before assigning it (this is needed for drivers 
> > which support generic IOMMU DT bindings in the first place).
> > 
> > [please take a look at 
> > https://lists.xenproject.org/archives/html/xen-devel/2019-09/msg02714.html 
> > if so]
> > 
> > Julien, what do you think?
> 
> Yes you are right.
> 
> @Stefano, this is a recently merged feature. Without it, you will not be 
> able to use passthrough with dom0less guest when the IOMMU (such as 
> IPMMU) is using the generic DT bindings.

Just double-checking but it should be only a matter of the following,
right?

+        res = iommu_add_dt_device(node);
+        if ( res < 0 )
+            return res;
+
+        if ( dt_device_is_protected(node) )
+        {
+            res = iommu_assign_dt_device(kinfo->d, node);
+            if ( res < 0 )
+                return res;
+        }
+

(I am asking because I couldn't quite test it due to the error with
mmu-masters I mentioned in the other email.)
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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