|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 08/13] xen/passthrough: iommu: Basic support of device tree assignment
>>> On 11.03.14 at 16:49, Julien Grall <julien.grall@xxxxxxxxxx> wrote:
> Add IOMMU helpers to support device tree assignment/deassignment. This patch
> introduces 2 new fields in the dt_device_node:
> - is_protected: Does the device is protected by an IOMMU
> - next_assigned: Pointer to the next device assigned to the same
> domain
>
> Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
> Cc: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
For the modifications to existing files:
Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
>
> ---
> Changes in v3:
> - Remove iommu_dt_domain_{init,destroy} call in common code. Let
> architecture code to call them
> - Fix indentation in xen/include/xen/hvm/iommu.h
> Changes in v2:
> - Patch added
> ---
> xen/common/device_tree.c | 4 ++
> xen/drivers/passthrough/Makefile | 1 +
> xen/drivers/passthrough/device_tree.c | 106
> +++++++++++++++++++++++++++++++++
> xen/include/xen/device_tree.h | 14 +++++
> xen/include/xen/hvm/iommu.h | 6 ++
> xen/include/xen/iommu.h | 16 +++++
> 6 files changed, 147 insertions(+)
> create mode 100644 xen/drivers/passthrough/device_tree.c
>
> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
> index 564f2bb..7c6b683 100644
> --- a/xen/common/device_tree.c
> +++ b/xen/common/device_tree.c
> @@ -1695,6 +1695,10 @@ static unsigned long __init unflatten_dt_node(const
> void *fdt,
> np->full_name = ((char *)np) + sizeof(struct dt_device_node);
> /* By default dom0 owns the device */
> np->used_by = 0;
> + /* By default the device is not protected */
> + np->is_protected = false;
> + INIT_LIST_HEAD(&np->next_assigned);
> +
> if ( new_format )
> {
> char *fn = np->full_name;
> diff --git a/xen/drivers/passthrough/Makefile
> b/xen/drivers/passthrough/Makefile
> index 6e08f89..5a0a35e 100644
> --- a/xen/drivers/passthrough/Makefile
> +++ b/xen/drivers/passthrough/Makefile
> @@ -5,3 +5,4 @@ subdir-$(x86_64) += x86
> obj-y += iommu.o
> obj-$(x86) += io.o
> obj-$(HAS_PCI) += pci.o
> +obj-$(HAS_DEVICE_TREE) += device_tree.o
> diff --git a/xen/drivers/passthrough/device_tree.c
> b/xen/drivers/passthrough/device_tree.c
> new file mode 100644
> index 0000000..7384e73
> --- /dev/null
> +++ b/xen/drivers/passthrough/device_tree.c
> @@ -0,0 +1,106 @@
> +/*
> + * xen/drivers/passthrough/arm/device_tree.c
> + *
> + * Code to passthrough device tree node to a guest
> + *
> + * Julien Grall <julien.grall@xxxxxxxxxx>
> + * Copyright (c) 2014 Linaro Limited.
> + *
> + * 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 <xen/lib.h>
> +#include <xen/sched.h>
> +#include <xen/iommu.h>
> +#include <xen/device_tree.h>
> +
> +static spinlock_t dtdevs_lock = SPIN_LOCK_UNLOCKED;
> +
> +int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev)
> +{
> + int rc = -EBUSY;
> + struct hvm_iommu *hd = domain_hvm_iommu(d);
> +
> + if ( !iommu_enabled || !hd->platform_ops )
> + return -EINVAL;
> +
> + if ( !dt_device_is_protected(dev) )
> + return -EINVAL;
> +
> + spin_lock(&dtdevs_lock);
> +
> + if ( !list_empty(&dev->next_assigned) )
> + goto fail;
> +
> + rc = hd->platform_ops->assign_dt_device(d, dev);
> +
> + if ( rc )
> + goto fail;
> +
> + list_add(&dev->next_assigned, &hd->dt_devices);
> + dt_device_set_used_by(dev, d->domain_id);
> +
> +fail:
> + spin_unlock(&dtdevs_lock);
> +
> + return rc;
> +}
> +
> +int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev)
> +{
> + struct hvm_iommu *hd = domain_hvm_iommu(d);
> + int rc;
> +
> + if ( !iommu_enabled || !hd->platform_ops )
> + return -EINVAL;
> +
> + if ( !dt_device_is_protected(dev) )
> + return -EINVAL;
> +
> + spin_lock(&dtdevs_lock);
> +
> + rc = hd->platform_ops->reassign_dt_device(d, dom0, dev);
> + if ( rc )
> + goto fail;
> +
> + dt_device_set_used_by(dev, dom0->domain_id);
> +
> + list_del(&dev->next_assigned);
> +
> +fail:
> + spin_unlock(&dtdevs_lock);
> +
> + return rc;
> +}
> +
> +int iommu_dt_domain_init(struct domain *d)
> +{
> + struct hvm_iommu *hd = domain_hvm_iommu(d);
> +
> + INIT_LIST_HEAD(&hd->dt_devices);
> +
> + return 0;
> +}
> +
> +void iommu_dt_domain_destroy(struct domain *d)
> +{
> + struct hvm_iommu *hd = domain_hvm_iommu(d);
> + struct dt_device_node *dev, *_dev;
> + int rc;
> +
> + list_for_each_entry_safe(dev, _dev, &hd->dt_devices, next_assigned)
> + {
> + rc = iommu_deassign_dt_device(d, dev);
> + if ( rc )
> + dprintk(XENLOG_ERR, "Failed to deassign %s in domain %u\n",
> + dt_node_full_name(dev), d->domain_id);
> + }
> +}
> diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
> index d429e60..2aae047 100644
> --- a/xen/include/xen/device_tree.h
> +++ b/xen/include/xen/device_tree.h
> @@ -16,6 +16,7 @@
> #include <xen/string.h>
> #include <xen/types.h>
> #include <xen/stdbool.h>
> +#include <xen/list.h>
>
> #define DEVICE_TREE_MAX_DEPTH 16
>
> @@ -110,6 +111,9 @@ struct dt_device_node {
> struct dt_device_node *next; /* TODO: Remove it. Only use to know the
> last children */
> struct dt_device_node *allnext;
>
> + /* IOMMU specific fields */
> + bool is_protected; /* Tell if the device is protected by an IOMMU */
> + struct list_head next_assigned;
> };
>
> #define MAX_PHANDLE_ARGS 16
> @@ -325,6 +329,16 @@ static inline domid_t dt_device_used_by(const struct
> dt_device_node *device)
> return device->used_by;
> }
>
> +static inline void dt_device_set_protected(struct dt_device_node *device)
> +{
> + device->is_protected = true;
> +}
> +
> +static inline bool dt_device_is_protected(const struct dt_device_node
> *device)
> +{
> + return device->is_protected;
> +}
> +
> static inline bool_t dt_property_name_is_equal(const struct dt_property
> *pp,
> const char *name)
> {
> diff --git a/xen/include/xen/hvm/iommu.h b/xen/include/xen/hvm/iommu.h
> index f8f8a93..1259e16 100644
> --- a/xen/include/xen/hvm/iommu.h
> +++ b/xen/include/xen/hvm/iommu.h
> @@ -21,6 +21,7 @@
> #define __XEN_HVM_IOMMU_H__
>
> #include <xen/iommu.h>
> +#include <xen/list.h>
> #include <asm/hvm/iommu.h>
>
> struct hvm_iommu {
> @@ -28,6 +29,11 @@ struct hvm_iommu {
>
> /* iommu_ops */
> const struct iommu_ops *platform_ops;
> +
> +#ifdef HAS_DEVICE_TREE
> + /* List of DT devices assigned to this domain */
> + struct list_head dt_devices;
> +#endif
> };
>
> #endif /* __XEN_HVM_IOMMU_H__ */
> diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
> index f556a7e..56f6c5c 100644
> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -82,6 +82,16 @@ bool_t pt_irq_need_timer(uint32_t flags);
> #define PT_IRQ_TIME_OUT MILLISECS(8)
> #endif /* HAS_PCI */
>
> +#ifdef HAS_DEVICE_TREE
> +#include <xen/device_tree.h>
> +
> +int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev);
> +int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev);
> +int iommu_dt_domain_init(struct domain *d);
> +void iommu_dt_domain_destroy(struct domain *d);
> +
> +#endif /* HAS_DEVICE_TREE */
> +
> #ifdef HAS_PCI
> struct msi_desc;
> struct msi_msg;
> @@ -103,6 +113,12 @@ struct iommu_ops {
> int (*update_ire_from_msi)(struct msi_desc *msi_desc, struct msi_msg
> *msg);
> void (*read_msi_from_ire)(struct msi_desc *msi_desc, struct msi_msg
> *msg);
> #endif /* HAS_PCI */
> +#ifdef HAS_DEVICE_TREE
> + int (*assign_dt_device)(struct domain *d, const struct dt_device_node
> *dev);
> + int (*reassign_dt_device)(struct domain *s, struct domain *t,
> + const struct dt_device_node *dev);
> +#endif
> +
> void (*teardown)(struct domain *d);
> int (*map_page)(struct domain *d, unsigned long gfn, unsigned long mfn,
> unsigned int flags);
> --
> 1.7.10.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |