* [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).