Hi Julien,
On Tue, Aug 22, 2023 at 08:43:27PM +0100, Julien Grall wrote:
> Hi Vikram,
>
> On 19/08/2023 01:28, Vikram Garhwal wrote:
> > Rename iommu_dt_device_is_assigned() to
> > iommu_dt_device_is_assigned_locked().
> > Remove static type so this can also be used by SMMU drivers to check if the
> > device is being used before removing.
>
> I have commented on v8. But I will comment here to make easier to keep track
> of comment.
>
> I don't think iommu_dt_device_is_assigned_locked() should be called from the
> SMMU. If you want to check a device is assigned then it would be best to use
> the internal state of the SMMU.
>
> This has two benefits:
> * This avoids what I view as a layer of violation
> * This confirmed that the internal state match with what we expect
>
> >
> > Moving spin_lock to caller was done to prevent the concurrent access to
> > iommu_dt_device_is_assigned while doing add/remove/assign/deassign.
> > Follow-up
> > patches in this series introduces node add/remove feature.
> >
> > Also, caller is required hold the correct lock so moved the function
> > prototype
> > to a private header.
>
> I don't understand how requiring the caller to hold the correct lock means
> you need to move the protype in a private header. Can you clarify?
>
With removal of check in smmu.c, this header is no longer required.
will remove private header too.
> >
> > Signed-off-by: Vikram Garhwal <vikram.garh...@amd.com>
> >
> > ---
> > Changes from v7:
> > Update commit message.
> > Add ASSERT().
> > ---
> > ---
> > xen/drivers/passthrough/device_tree.c | 26 +++++++++++++++++++++----
> > xen/include/xen/iommu-private.h | 28 +++++++++++++++++++++++++++
> > 2 files changed, 50 insertions(+), 4 deletions(-)
> > create mode 100644 xen/include/xen/iommu-private.h
> >
> > diff --git a/xen/drivers/passthrough/device_tree.c
> > b/xen/drivers/passthrough/device_tree.c
> > index 1c32d7b50c..5796ee1f93 100644
> > --- a/xen/drivers/passthrough/device_tree.c
> > +++ b/xen/drivers/passthrough/device_tree.c
> > @@ -18,6 +18,7 @@
> > #include <xen/device_tree.h>
> > #include <xen/guest_access.h>
> > #include <xen/iommu.h>
> > +#include <xen/iommu-private.h>
> > #include <xen/lib.h>
> > #include <xen/sched.h>
> > #include <xsm/xsm.h>
> > @@ -83,16 +84,16 @@ fail:
> > return rc;
> > }
> > -static bool_t iommu_dt_device_is_assigned(const struct dt_device_node *dev)
> > +bool_t iommu_dt_device_is_assigned_locked(const struct dt_device_node *dev)
> > {
> > bool_t assigned = 0;
> > + ASSERT(spin_is_locked(&dtdevs_lock));
> > +
> > if ( !dt_device_is_protected(dev) )
> > return 0;
> > - spin_lock(&dtdevs_lock);
> > assigned = !list_empty(&dev->domain_list);
> > - spin_unlock(&dtdevs_lock);
> > return assigned;
> > }
> > @@ -213,27 +214,44 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl,
> > struct domain *d,
> > if ( (d && d->is_dying) || domctl->u.assign_device.flags )
> > break;
> > + /*
> > + * To ensure that the dev doesn't disappear between the time we
> > look it
> > + * up with dt_find_node_by_gpath() and we check the assignment
> > later.
> > + */
> > + spin_lock(&dtdevs_lock);
>
> This change doesn't look to be explained in the commit message. But looking
> at the code after this series is applied, you justified the addition of
> read_lock(&dt_host_lock) to protect access to the device-tree. This will be
> held longer than dtdevs_lock. So is it actually necessary to move the
> locking earlier?
I re-looked at the implementation and actually, dt_host_lock will protect the
dt related changes. I will move it down before
iommu_dt_device_is_assigned_lock()
call.
>
> > +
> > ret = dt_find_node_by_gpath(domctl->u.assign_device.u.dt.path,
> > domctl->u.assign_device.u.dt.size,
> > &dev);
> > if ( ret )
> > + {
> > + spin_unlock(&dtdevs_lock);
> > break;
> > + }
> > ret = xsm_assign_dtdevice(XSM_HOOK, d, dt_node_full_name(dev));
> > if ( ret )
> > + {
> > + spin_unlock(&dtdevs_lock);
> > break;
> > + }
> > if ( domctl->cmd == XEN_DOMCTL_test_assign_device )
> > {
> > - if ( iommu_dt_device_is_assigned(dev) )
> > +
> > + if ( iommu_dt_device_is_assigned_locked(dev) )
> > {
> > printk(XENLOG_G_ERR "%s already assigned.\n",
> > dt_node_full_name(dev));
> > ret = -EINVAL;
> > }
> > +
> > + spin_unlock(&dtdevs_lock);
> > break;
> > }
> > + spin_unlock(&dtdevs_lock);
> > +
> > if ( d == dom_io )
> > return -EINVAL;
> > diff --git a/xen/include/xen/iommu-private.h
> > b/xen/include/xen/iommu-private.h
> > new file mode 100644
> > index 0000000000..bb5c94e7a6
> > --- /dev/null
> > +++ b/xen/include/xen/iommu-private.h
> > @@ -0,0 +1,28 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * xen/iommu-private.h
> > + */
> > +#ifndef __XEN_IOMMU_PRIVATE_H__
> > +#define __XEN_IOMMU_PRIVATE_H__
> > +
> > +#ifdef CONFIG_HAS_DEVICE_TREE
> > +#include <xen/device_tree.h>
> > +
> > +/*
> > + * Checks if dt_device_node is assigned to a domain or not. This function
> > + * expects to be called with dtdevs_lock acquired by caller.
> > + */
> > +bool_t iommu_dt_device_is_assigned_locked(const struct dt_device_node
> > *dev);
> > +#endif
> > +
> > +#endif /* __XEN_IOMMU_PRIVATE_H__ */
> > +
> > +/*
> > + * Local variables:
> > + * mode: C
> > + * c-file-style: "BSD"
> > + * c-basic-offset: 4
> > + * tab-width: 4
> > + * indent-tabs-mode: nil
> > + * End:
> > + */
>
> Cheers,
>
> --
> Julien Grall