qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/3] intel_iommu: Fix locking issues
@ 2025-04-28  5:12 CLEMENT MATHIEU--DRIF
  2025-04-28  5:12 ` [PATCH v4 1/3] intel_iommu: Take the bql before registering a new address space CLEMENT MATHIEU--DRIF
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2025-04-28  5:12 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com, peterx@redhat.com,
	mst@redhat.com, CLEMENT MATHIEU--DRIF

This series introduces 2 fixes and improves locking style
consistency in the VT-d device.

Clement Mathieu--Drif (3):
  intel_iommu: Take the bql before registering a new address space
  intel_iommu: Use BQL_LOCK_GUARD to manage cleanup automatically
  intel_iommu: Take the VTD lock when looking for and creating address
    spaces

 hw/i386/intel_iommu.c | 44 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 11 deletions(-)

-- 
2.49.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v4 1/3] intel_iommu: Take the bql before registering a new address space
  2025-04-28  5:12 [PATCH v4 0/3] intel_iommu: Fix locking issues CLEMENT MATHIEU--DRIF
@ 2025-04-28  5:12 ` CLEMENT MATHIEU--DRIF
  2025-04-28  5:12 ` [PATCH v4 2/3] intel_iommu: Use BQL_LOCK_GUARD to manage cleanup automatically CLEMENT MATHIEU--DRIF
  2025-04-28  5:12 ` [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and creating address spaces CLEMENT MATHIEU--DRIF
  2 siblings, 0 replies; 8+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2025-04-28  5:12 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com, peterx@redhat.com,
	mst@redhat.com, CLEMENT MATHIEU--DRIF

Address space creation might end up being called without holding the
bql as it is exposed through the IOMMU ops.

Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index dffd7ee885..cc8c9857e1 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -4238,6 +4238,12 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
         vtd_dev_as->context_cache_entry.context_cache_gen = 0;
         vtd_dev_as->iova_tree = iova_tree_new();
 
+        /*
+         * memory_region_add_subregion_overlap requires the bql,
+         * make sure we own it.
+         */
+        BQL_LOCK_GUARD();
+
         memory_region_init(&vtd_dev_as->root, OBJECT(s), name, UINT64_MAX);
         address_space_init(&vtd_dev_as->as, &vtd_dev_as->root, "vtd-root");
 
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 2/3] intel_iommu: Use BQL_LOCK_GUARD to manage cleanup automatically
  2025-04-28  5:12 [PATCH v4 0/3] intel_iommu: Fix locking issues CLEMENT MATHIEU--DRIF
  2025-04-28  5:12 ` [PATCH v4 1/3] intel_iommu: Take the bql before registering a new address space CLEMENT MATHIEU--DRIF
@ 2025-04-28  5:12 ` CLEMENT MATHIEU--DRIF
  2025-04-28  5:12 ` [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and creating address spaces CLEMENT MATHIEU--DRIF
  2 siblings, 0 replies; 8+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2025-04-28  5:12 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com, peterx@redhat.com,
	mst@redhat.com, CLEMENT MATHIEU--DRIF

vtd_switch_address_space needs to take the BQL if not already held.
Use BQL_LOCK_GUARD to make the iommu implementation more consistent.

Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index cc8c9857e1..b7855f4b87 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1728,8 +1728,6 @@ static bool vtd_as_pt_enabled(VTDAddressSpace *as)
 static bool vtd_switch_address_space(VTDAddressSpace *as)
 {
     bool use_iommu, pt;
-    /* Whether we need to take the BQL on our own */
-    bool take_bql = !bql_locked();
 
     assert(as);
 
@@ -1746,9 +1744,7 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
      * from vtd_pt_enable_fast_path(). However the memory APIs need
      * it. We'd better make sure we have had it already, or, take it.
      */
-    if (take_bql) {
-        bql_lock();
-    }
+    BQL_LOCK_GUARD();
 
     /* Turn off first then on the other */
     if (use_iommu) {
@@ -1801,10 +1797,6 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
         memory_region_set_enabled(&as->iommu_ir_fault, false);
     }
 
-    if (take_bql) {
-        bql_unlock();
-    }
-
     return use_iommu;
 }
 
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and creating address spaces
  2025-04-28  5:12 [PATCH v4 0/3] intel_iommu: Fix locking issues CLEMENT MATHIEU--DRIF
  2025-04-28  5:12 ` [PATCH v4 1/3] intel_iommu: Take the bql before registering a new address space CLEMENT MATHIEU--DRIF
  2025-04-28  5:12 ` [PATCH v4 2/3] intel_iommu: Use BQL_LOCK_GUARD to manage cleanup automatically CLEMENT MATHIEU--DRIF
@ 2025-04-28  5:12 ` CLEMENT MATHIEU--DRIF
  2025-04-28  8:55   ` Duan, Zhenzhong
  2 siblings, 1 reply; 8+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2025-04-28  5:12 UTC (permalink / raw)
  To: qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, zhenzhong.duan@intel.com,
	kevin.tian@intel.com, yi.l.liu@intel.com, peterx@redhat.com,
	mst@redhat.com, CLEMENT MATHIEU--DRIF

vtd_find_add_as can be called by multiple threads which leads to a race
condition on address space creation. The IOMMU lock must be taken to
avoid such a race.

Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
---
 hw/i386/intel_iommu.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index b7855f4b87..931ac01ef0 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -4203,11 +4203,15 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
         .pasid = pasid,
     };
     VTDAddressSpace *vtd_dev_as;
+    struct vtd_as_key *new_key = NULL;
     char name[128];
 
+    vtd_iommu_lock(s);
     vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
+    vtd_iommu_unlock(s);
+
     if (!vtd_dev_as) {
-        struct vtd_as_key *new_key = g_malloc(sizeof(*new_key));
+        new_key = g_malloc(sizeof(*new_key));
 
         new_key->bus = bus;
         new_key->devfn = devfn;
@@ -4302,9 +4306,29 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
                                             &vtd_dev_as->nodmar, 0);
 
         vtd_switch_address_space(vtd_dev_as);
+    }
 
-        g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
+    if (new_key != NULL) {
+        VTDAddressSpace *second_vtd_dev_as;
+
+        /*
+         * Take the lock again and recheck as the AS might have
+         * been created in the meantime.
+         */
+        vtd_iommu_lock(s);
+
+        second_vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
+        if (!second_vtd_dev_as) {
+            g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
+        } else {
+            vtd_dev_as = second_vtd_dev_as;
+            g_free(vtd_dev_as);
+            g_free(new_key);
+        }
+
+        vtd_iommu_unlock(s);
     }
+
     return vtd_dev_as;
 }
 
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* RE: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and creating address spaces
  2025-04-28  5:12 ` [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and creating address spaces CLEMENT MATHIEU--DRIF
@ 2025-04-28  8:55   ` Duan, Zhenzhong
  2025-04-28 14:32     ` CLEMENT MATHIEU--DRIF
  0 siblings, 1 reply; 8+ messages in thread
From: Duan, Zhenzhong @ 2025-04-28  8:55 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, Tian, Kevin, Liu, Yi L, peterx@redhat.com,
	mst@redhat.com

Hi Clement,

>-----Original Message-----
>From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>Subject: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and
>creating address spaces
>
>vtd_find_add_as can be called by multiple threads which leads to a race
>condition on address space creation. The IOMMU lock must be taken to
>avoid such a race.
>
>Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
>---
> hw/i386/intel_iommu.c | 28 ++++++++++++++++++++++++++--
> 1 file changed, 26 insertions(+), 2 deletions(-)
>
>diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>index b7855f4b87..931ac01ef0 100644
>--- a/hw/i386/intel_iommu.c
>+++ b/hw/i386/intel_iommu.c
>@@ -4203,11 +4203,15 @@ VTDAddressSpace
>*vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
>         .pasid = pasid,
>     };
>     VTDAddressSpace *vtd_dev_as;
>+    struct vtd_as_key *new_key = NULL;
>     char name[128];
>
>+    vtd_iommu_lock(s);
>     vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
>+    vtd_iommu_unlock(s);
>+
>     if (!vtd_dev_as) {
>-        struct vtd_as_key *new_key = g_malloc(sizeof(*new_key));
>+        new_key = g_malloc(sizeof(*new_key));
>
>         new_key->bus = bus;
>         new_key->devfn = devfn;
>@@ -4302,9 +4306,29 @@ VTDAddressSpace
>*vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
>                                             &vtd_dev_as->nodmar, 0);
>
>         vtd_switch_address_space(vtd_dev_as);
>+    }
>
>-        g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>+    if (new_key != NULL) {
>+        VTDAddressSpace *second_vtd_dev_as;
>+
>+        /*
>+         * Take the lock again and recheck as the AS might have
>+         * been created in the meantime.
>+         */
>+        vtd_iommu_lock(s);
>+
>+        second_vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
>+        if (!second_vtd_dev_as) {
>+            g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>+        } else {
>+            vtd_dev_as = second_vtd_dev_as;
>+            g_free(vtd_dev_as);
>+            g_free(new_key);

We need to release memory regions under this vtd_dev_as to avoid leak.

Thanks
Zhenzhong


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and creating address spaces
  2025-04-28  8:55   ` Duan, Zhenzhong
@ 2025-04-28 14:32     ` CLEMENT MATHIEU--DRIF
  2025-04-29  6:01       ` Duan, Zhenzhong
  0 siblings, 1 reply; 8+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2025-04-28 14:32 UTC (permalink / raw)
  To: Duan, Zhenzhong, qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, Tian, Kevin, Liu, Yi L, peterx@redhat.com,
	mst@redhat.com

Hi Zhenzhong,

On 28/04/2025 10:55 am, Duan, Zhenzhong wrote:
> Caution: External email. Do not open attachments or click links, unless this email comes from a known sender and you know the content is safe.
> 
> 
> Hi Clement,
> 
>> -----Original Message-----
>> From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>> Subject: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and
>> creating address spaces
>>
>> vtd_find_add_as can be called by multiple threads which leads to a race
>> condition on address space creation. The IOMMU lock must be taken to
>> avoid such a race.
>>
>> Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
>> ---
>> hw/i386/intel_iommu.c | 28 ++++++++++++++++++++++++++--
>> 1 file changed, 26 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>> index b7855f4b87..931ac01ef0 100644
>> --- a/hw/i386/intel_iommu.c
>> +++ b/hw/i386/intel_iommu.c
>> @@ -4203,11 +4203,15 @@ VTDAddressSpace
>> *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
>>          .pasid = pasid,
>>      };
>>      VTDAddressSpace *vtd_dev_as;
>> +    struct vtd_as_key *new_key = NULL;
>>      char name[128];
>>
>> +    vtd_iommu_lock(s);
>>      vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
>> +    vtd_iommu_unlock(s);
>> +
>>      if (!vtd_dev_as) {
>> -        struct vtd_as_key *new_key = g_malloc(sizeof(*new_key));
>> +        new_key = g_malloc(sizeof(*new_key));
>>
>>          new_key->bus = bus;
>>          new_key->devfn = devfn;
>> @@ -4302,9 +4306,29 @@ VTDAddressSpace
>> *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
>>                                              &vtd_dev_as->nodmar, 0);
>>
>>          vtd_switch_address_space(vtd_dev_as);
>> +    }
>>
>> -        g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>> +    if (new_key != NULL) {
>> +        VTDAddressSpace *second_vtd_dev_as;
>> +
>> +        /*
>> +         * Take the lock again and recheck as the AS might have
>> +         * been created in the meantime.
>> +         */
>> +        vtd_iommu_lock(s);
>> +
>> +        second_vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
>> +        if (!second_vtd_dev_as) {
>> +            g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>> +        } else {
>> +            vtd_dev_as = second_vtd_dev_as;
>> +            g_free(vtd_dev_as);
>> +            g_free(new_key);
> 
> We need to release memory regions under this vtd_dev_as to avoid leak.


Indeed, I'll have to take the BQL again.

Is it ok for you if it look like this:

vtd_iommu_lock(s);

second_vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
if (!second_vtd_dev_as) {
     g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
     vtd_iommu_unlock(s);
} else {
     vtd_iommu_unlock(s);
     BQL_LOCK_GUARD();

     memory_region_del_subregion(&vtd_dev_as->root, &vtd_dev_as->nodmar);
     memory_region_del_subregion(&vtd_dev_as->root,
                                 MEMORY_REGION(&vtd_dev_as->iommu));
     memory_region_del_subregion(&vtd_dev_as->root,
                                 &vtd_dev_as->iommu_ir_fault);
     memory_region_del_subregion(&vtd_dev_as->root,
                                 &vtd_dev_as->iommu_ir);

     memory_region_unref(MEMORY_REGION(&vtd_dev_as->iommu));
     memory_region_unref(&vtd_dev_as->iommu_ir_fault);
     memory_region_unref(&vtd_dev_as->iommu_ir);
     memory_region_unref(&vtd_dev_as->nodmar);

     address_space_destroy(&vtd_dev_as->as);

     g_free(vtd_dev_as);
     g_free(new_key);

     vtd_dev_as = second_vtd_dev_as;
}

...

return vtd_dev_as;


> 
> Thanks
> Zhenzhong

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and creating address spaces
  2025-04-28 14:32     ` CLEMENT MATHIEU--DRIF
@ 2025-04-29  6:01       ` Duan, Zhenzhong
  2025-04-30 12:58         ` CLEMENT MATHIEU--DRIF
  0 siblings, 1 reply; 8+ messages in thread
From: Duan, Zhenzhong @ 2025-04-29  6:01 UTC (permalink / raw)
  To: CLEMENT MATHIEU--DRIF, qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, Tian, Kevin, Liu, Yi L, peterx@redhat.com,
	mst@redhat.com



>-----Original Message-----
>From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>Subject: Re: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and
>creating address spaces
>
>Hi Zhenzhong,
>
>On 28/04/2025 10:55 am, Duan, Zhenzhong wrote:
>> Caution: External email. Do not open attachments or click links, unless this
>email comes from a known sender and you know the content is safe.
>>
>>
>> Hi Clement,
>>
>>> -----Original Message-----
>>> From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>>> Subject: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and
>>> creating address spaces
>>>
>>> vtd_find_add_as can be called by multiple threads which leads to a race
>>> condition on address space creation. The IOMMU lock must be taken to
>>> avoid such a race.
>>>
>>> Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
>>> ---
>>> hw/i386/intel_iommu.c | 28 ++++++++++++++++++++++++++--
>>> 1 file changed, 26 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>>> index b7855f4b87..931ac01ef0 100644
>>> --- a/hw/i386/intel_iommu.c
>>> +++ b/hw/i386/intel_iommu.c
>>> @@ -4203,11 +4203,15 @@ VTDAddressSpace
>>> *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
>>>          .pasid = pasid,
>>>      };
>>>      VTDAddressSpace *vtd_dev_as;
>>> +    struct vtd_as_key *new_key = NULL;
>>>      char name[128];
>>>
>>> +    vtd_iommu_lock(s);
>>>      vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
>>> +    vtd_iommu_unlock(s);
>>> +
>>>      if (!vtd_dev_as) {
>>> -        struct vtd_as_key *new_key = g_malloc(sizeof(*new_key));
>>> +        new_key = g_malloc(sizeof(*new_key));
>>>
>>>          new_key->bus = bus;
>>>          new_key->devfn = devfn;
>>> @@ -4302,9 +4306,29 @@ VTDAddressSpace
>>> *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
>>>                                              &vtd_dev_as->nodmar, 0);
>>>
>>>          vtd_switch_address_space(vtd_dev_as);
>>> +    }
>>>
>>> -        g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>>> +    if (new_key != NULL) {
>>> +        VTDAddressSpace *second_vtd_dev_as;
>>> +
>>> +        /*
>>> +         * Take the lock again and recheck as the AS might have
>>> +         * been created in the meantime.
>>> +         */
>>> +        vtd_iommu_lock(s);
>>> +
>>> +        second_vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces,
>&key);
>>> +        if (!second_vtd_dev_as) {
>>> +            g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>>> +        } else {
>>> +            vtd_dev_as = second_vtd_dev_as;
>>> +            g_free(vtd_dev_as);
>>> +            g_free(new_key);
>>
>> We need to release memory regions under this vtd_dev_as to avoid leak.
>
>
>Indeed, I'll have to take the BQL again.
>
>Is it ok for you if it look like this:
>
>vtd_iommu_lock(s);
>
>second_vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
>if (!second_vtd_dev_as) {
>     g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>     vtd_iommu_unlock(s);
>} else {
>     vtd_iommu_unlock(s);
>     BQL_LOCK_GUARD();
>
>     memory_region_del_subregion(&vtd_dev_as->root, &vtd_dev_as->nodmar);
>     memory_region_del_subregion(&vtd_dev_as->root,
>                                 MEMORY_REGION(&vtd_dev_as->iommu));
>     memory_region_del_subregion(&vtd_dev_as->root,
>                                 &vtd_dev_as->iommu_ir_fault);
>     memory_region_del_subregion(&vtd_dev_as->root,
>                                 &vtd_dev_as->iommu_ir);
>
>     memory_region_unref(MEMORY_REGION(&vtd_dev_as->iommu));
>     memory_region_unref(&vtd_dev_as->iommu_ir_fault);
>     memory_region_unref(&vtd_dev_as->iommu_ir);
>     memory_region_unref(&vtd_dev_as->nodmar);

s/memory_region_unref/object_unparent?

>
>     address_space_destroy(&vtd_dev_as->as);

object_unparent(vtd_dev_as->root);

Thanks
Zhenzhong

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and creating address spaces
  2025-04-29  6:01       ` Duan, Zhenzhong
@ 2025-04-30 12:58         ` CLEMENT MATHIEU--DRIF
  0 siblings, 0 replies; 8+ messages in thread
From: CLEMENT MATHIEU--DRIF @ 2025-04-30 12:58 UTC (permalink / raw)
  To: Duan, Zhenzhong, qemu-devel@nongnu.org
  Cc: jasowang@redhat.com, Tian, Kevin, Liu, Yi L, peterx@redhat.com,
	mst@redhat.com



On 29/04/2025 8:01 am, Duan, Zhenzhong wrote:
> Caution: External email. Do not open attachments or click links, unless this email comes from a known sender and you know the content is safe.
>
>
>> -----Original Message-----
>> From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>> Subject: Re: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and
>> creating address spaces
>>
>> Hi Zhenzhong,
>>
>> On 28/04/2025 10:55 am, Duan, Zhenzhong wrote:
>>> Caution: External email. Do not open attachments or click links, unless this
>> email comes from a known sender and you know the content is safe.
>>>
>>> Hi Clement,
>>>
>>>> -----Original Message-----
>>>> From: CLEMENT MATHIEU--DRIF <clement.mathieu--drif@eviden.com>
>>>> Subject: [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and
>>>> creating address spaces
>>>>
>>>> vtd_find_add_as can be called by multiple threads which leads to a race
>>>> condition on address space creation. The IOMMU lock must be taken to
>>>> avoid such a race.
>>>>
>>>> Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
>>>> ---
>>>> hw/i386/intel_iommu.c | 28 ++++++++++++++++++++++++++--
>>>> 1 file changed, 26 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>>>> index b7855f4b87..931ac01ef0 100644
>>>> --- a/hw/i386/intel_iommu.c
>>>> +++ b/hw/i386/intel_iommu.c
>>>> @@ -4203,11 +4203,15 @@ VTDAddressSpace
>>>> *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
>>>>           .pasid = pasid,
>>>>       };
>>>>       VTDAddressSpace *vtd_dev_as;
>>>> +    struct vtd_as_key *new_key = NULL;
>>>>       char name[128];
>>>>
>>>> +    vtd_iommu_lock(s);
>>>>       vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
>>>> +    vtd_iommu_unlock(s);
>>>> +
>>>>       if (!vtd_dev_as) {
>>>> -        struct vtd_as_key *new_key = g_malloc(sizeof(*new_key));
>>>> +        new_key = g_malloc(sizeof(*new_key));
>>>>
>>>>           new_key->bus = bus;
>>>>           new_key->devfn = devfn;
>>>> @@ -4302,9 +4306,29 @@ VTDAddressSpace
>>>> *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,
>>>>                                               &vtd_dev_as->nodmar, 0);
>>>>
>>>>           vtd_switch_address_space(vtd_dev_as);
>>>> +    }
>>>>
>>>> -        g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>>>> +    if (new_key != NULL) {
>>>> +        VTDAddressSpace *second_vtd_dev_as;
>>>> +
>>>> +        /*
>>>> +         * Take the lock again and recheck as the AS might have
>>>> +         * been created in the meantime.
>>>> +         */
>>>> +        vtd_iommu_lock(s);
>>>> +
>>>> +        second_vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces,
>> &key);
>>>> +        if (!second_vtd_dev_as) {
>>>> +            g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>>>> +        } else {
>>>> +            vtd_dev_as = second_vtd_dev_as;
>>>> +            g_free(vtd_dev_as);
>>>> +            g_free(new_key);
>>> We need to release memory regions under this vtd_dev_as to avoid leak.
>>
>> Indeed, I'll have to take the BQL again.
>>
>> Is it ok for you if it look like this:
>>
>> vtd_iommu_lock(s);
>>
>> second_vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
>> if (!second_vtd_dev_as) {
>>      g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as);
>>      vtd_iommu_unlock(s);
>> } else {
>>      vtd_iommu_unlock(s);
>>      BQL_LOCK_GUARD();
>>
>>      memory_region_del_subregion(&vtd_dev_as->root, &vtd_dev_as->nodmar);
>>      memory_region_del_subregion(&vtd_dev_as->root,
>>                                  MEMORY_REGION(&vtd_dev_as->iommu));
>>      memory_region_del_subregion(&vtd_dev_as->root,
>>                                  &vtd_dev_as->iommu_ir_fault);
>>      memory_region_del_subregion(&vtd_dev_as->root,
>>                                  &vtd_dev_as->iommu_ir);
>>
>>      memory_region_unref(MEMORY_REGION(&vtd_dev_as->iommu));
>>      memory_region_unref(&vtd_dev_as->iommu_ir_fault);
>>      memory_region_unref(&vtd_dev_as->iommu_ir);
>>      memory_region_unref(&vtd_dev_as->nodmar);
> s/memory_region_unref/object_unparent?
>
>>      address_space_destroy(&vtd_dev_as->as);
> object_unparent(vtd_dev_as->root);

Hi Zhenzhong,

I think the issue can be fixed differently in a cleaner way.
I sent a v5 for that.

Thanks

>
> Thanks
> Zhenzhong

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-04-30 12:59 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-28  5:12 [PATCH v4 0/3] intel_iommu: Fix locking issues CLEMENT MATHIEU--DRIF
2025-04-28  5:12 ` [PATCH v4 1/3] intel_iommu: Take the bql before registering a new address space CLEMENT MATHIEU--DRIF
2025-04-28  5:12 ` [PATCH v4 2/3] intel_iommu: Use BQL_LOCK_GUARD to manage cleanup automatically CLEMENT MATHIEU--DRIF
2025-04-28  5:12 ` [PATCH v4 3/3] intel_iommu: Take the VTD lock when looking for and creating address spaces CLEMENT MATHIEU--DRIF
2025-04-28  8:55   ` Duan, Zhenzhong
2025-04-28 14:32     ` CLEMENT MATHIEU--DRIF
2025-04-29  6:01       ` Duan, Zhenzhong
2025-04-30 12:58         ` CLEMENT MATHIEU--DRIF

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).