Re: [PATCH 5/6] iommu/amd: Lock dev_data in attach/detach code paths
On Wed Sep 25 19, Joerg Roedel wrote: From: Joerg Roedel Make sure that attaching a detaching a device can't race against each other and protect the iommu_dev_data with a spin_lock in these code paths. Fixes: 92d420ec028d ("iommu/amd: Relax locking in dma_ops path") Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 9 + drivers/iommu/amd_iommu_types.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 459247c32dc0..bac4e20a5919 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -201,6 +201,7 @@ static struct iommu_dev_data *alloc_dev_data(u16 devid) if (!dev_data) return NULL; + spin_lock_init(&dev_data->lock); dev_data->devid = devid; ratelimit_default_init(&dev_data->rs); @@ -2157,6 +2158,8 @@ static int attach_device(struct device *dev, dev_data = get_dev_data(dev); + spin_lock(&dev_data->lock); + ret = -EBUSY; if (dev_data->domain != NULL) goto out; @@ -2199,6 +2202,8 @@ static int attach_device(struct device *dev, domain_flush_complete(domain); out: + spin_unlock(&dev_data->lock); + spin_unlock_irqrestore(&domain->lock, flags); return ret; @@ -2218,6 +2223,8 @@ static void detach_device(struct device *dev) spin_lock_irqsave(&domain->lock, flags); + spin_lock(&dev_data->lock); + /* * First check if the device is still attached. It might already * be detached from its domain because the generic @@ -2240,6 +2247,8 @@ static void detach_device(struct device *dev) dev_data->ats.enabled = false; out: + spin_unlock(&dev_data->lock); + spin_unlock_irqrestore(&domain->lock, flags); } diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 0186501ab971..c9c1612d52e0 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -633,6 +633,9 @@ struct devid_map { * This struct contains device specific data for the IOMMU */ struct iommu_dev_data { + /*Protect against attach/detach races */ + spinlock_t lock; + struct list_head list;/* For domain->dev_list */ struct llist_node dev_data_list; /* For global dev_data_list */ struct protection_domain *domain; /* Domain the device is bound to */ -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu Reviewed-by: Jerry Snitselaar ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 5/6] iommu/amd: Lock dev_data in attach/detach code paths
> On 25. Sep 2019, at 06:22, Joerg Roedel wrote: > > From: Joerg Roedel > > Make sure that attaching a detaching a device can't race against each > other and protect the iommu_dev_data with a spin_lock in these code > paths. > > Fixes: 92d420ec028d ("iommu/amd: Relax locking in dma_ops path") > Signed-off-by: Joerg Roedel > --- > drivers/iommu/amd_iommu.c | 9 + > drivers/iommu/amd_iommu_types.h | 3 +++ > 2 files changed, 12 insertions(+) > > diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c > index 459247c32dc0..bac4e20a5919 100644 > --- a/drivers/iommu/amd_iommu.c > +++ b/drivers/iommu/amd_iommu.c > @@ -201,6 +201,7 @@ static struct iommu_dev_data *alloc_dev_data(u16 devid) > if (!dev_data) > return NULL; > > + spin_lock_init(&dev_data->lock); > dev_data->devid = devid; > ratelimit_default_init(&dev_data->rs); > > @@ -2157,6 +2158,8 @@ static int attach_device(struct device *dev, > > dev_data = get_dev_data(dev); > > + spin_lock(&dev_data->lock); > + > ret = -EBUSY; > if (dev_data->domain != NULL) > goto out; > @@ -2199,6 +2202,8 @@ static int attach_device(struct device *dev, > domain_flush_complete(domain); > > out: > + spin_unlock(&dev_data->lock); > + > spin_unlock_irqrestore(&domain->lock, flags); > > return ret; > @@ -2218,6 +2223,8 @@ static void detach_device(struct device *dev) > > spin_lock_irqsave(&domain->lock, flags); > > + spin_lock(&dev_data->lock); > + > /* >* First check if the device is still attached. It might already >* be detached from its domain because the generic > @@ -2240,6 +2247,8 @@ static void detach_device(struct device *dev) > dev_data->ats.enabled = false; > > out: > + spin_unlock(&dev_data->lock); > + > spin_unlock_irqrestore(&domain->lock, flags); > } > > diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h > index 0186501ab971..c9c1612d52e0 100644 > --- a/drivers/iommu/amd_iommu_types.h > +++ b/drivers/iommu/amd_iommu_types.h > @@ -633,6 +633,9 @@ struct devid_map { > * This struct contains device specific data for the IOMMU > */ > struct iommu_dev_data { > + /*Protect against attach/detach races */ > + spinlock_t lock; > + > struct list_head list;/* For domain->dev_list */ > struct llist_node dev_data_list; /* For global dev_data_list */ > struct protection_domain *domain; /* Domain the device is bound to */ > -- > 2.17.1 > Reviewed-by: Filippo Sironi Amazon Development Center Germany GmbH Krausenstr. 38 10117 Berlin Geschaeftsfuehrung: Christian Schlaeger, Ralf Herbrich Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B Sitz: Berlin Ust-ID: DE 289 237 879 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 5/6] iommu/amd: Lock dev_data in attach/detach code paths
From: Joerg Roedel Make sure that attaching a detaching a device can't race against each other and protect the iommu_dev_data with a spin_lock in these code paths. Fixes: 92d420ec028d ("iommu/amd: Relax locking in dma_ops path") Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 9 + drivers/iommu/amd_iommu_types.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 459247c32dc0..bac4e20a5919 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -201,6 +201,7 @@ static struct iommu_dev_data *alloc_dev_data(u16 devid) if (!dev_data) return NULL; + spin_lock_init(&dev_data->lock); dev_data->devid = devid; ratelimit_default_init(&dev_data->rs); @@ -2157,6 +2158,8 @@ static int attach_device(struct device *dev, dev_data = get_dev_data(dev); + spin_lock(&dev_data->lock); + ret = -EBUSY; if (dev_data->domain != NULL) goto out; @@ -2199,6 +2202,8 @@ static int attach_device(struct device *dev, domain_flush_complete(domain); out: + spin_unlock(&dev_data->lock); + spin_unlock_irqrestore(&domain->lock, flags); return ret; @@ -2218,6 +2223,8 @@ static void detach_device(struct device *dev) spin_lock_irqsave(&domain->lock, flags); + spin_lock(&dev_data->lock); + /* * First check if the device is still attached. It might already * be detached from its domain because the generic @@ -2240,6 +2247,8 @@ static void detach_device(struct device *dev) dev_data->ats.enabled = false; out: + spin_unlock(&dev_data->lock); + spin_unlock_irqrestore(&domain->lock, flags); } diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 0186501ab971..c9c1612d52e0 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -633,6 +633,9 @@ struct devid_map { * This struct contains device specific data for the IOMMU */ struct iommu_dev_data { + /*Protect against attach/detach races */ + spinlock_t lock; + struct list_head list;/* For domain->dev_list */ struct llist_node dev_data_list; /* For global dev_data_list */ struct protection_domain *domain; /* Domain the device is bound to */ -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu