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