Re: [PATCH 5/6] iommu/amd: Lock dev_data in attach/detach code paths

2019-09-25 Thread Jerry Snitselaar

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

2019-09-25 Thread Sironi, Filippo via iommu



> 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

2019-09-25 Thread Joerg Roedel
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