On 15/4/25 09:42, Michael S. Tsirkin wrote:
On Tue, Apr 15, 2025 at 07:28:34AM +0000, CLEMENT MATHIEU--DRIF wrote:


On 15/04/2025 8:53 am, Philippe Mathieu-Daudé 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.


On 15/4/25 08:18, CLEMENT MATHIEU--DRIF wrote:
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--d...@eviden.com>
---
   hw/i386/intel_iommu.c | 10 ++++++++++
   1 file changed, 10 insertions(+)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index dffd7ee885..fea2220013 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -4216,6 +4216,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState
*s, PCIBus *bus,
       vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key);
       if (!vtd_dev_as) {
           struct vtd_as_key *new_key = g_malloc(sizeof(*new_key));
+        bool take_bql = !bql_locked();

           new_key->bus = bus;
           new_key->devfn = devfn;
@@ -4238,6 +4239,11 @@ 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();

+        /* Some functions in this branch require the bql, make sure
we own it */
+        if (take_bql) {
+            bql_lock();
+        }
+
           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");

@@ -4305,6 +4311,10 @@ VTDAddressSpace
*vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,

           vtd_switch_address_space(vtd_dev_as);

Would it help clarifying to propagate this argument down?
vtd_switch_address_space(VTDAddressSpace *as, bool need_lock);

Hi phil, vtd_switch_address_space already does the same kind of check



+        if (take_bql) {
+            bql_unlock();
+        }
+
           g_hash_table_insert(s->vtd_address_spaces, new_key,
vtd_dev_as);
       }
       return vtd_dev_as;



As an apropos, I think any caller of bql_lock really should call
bql_lock_impl so we know who took BQL. Or just use BQL_LOCK_GUARD.
But, that's an unrelated cleanup.


Yeah unrelated cleanup. Although I don't understand why these
code paths don't use memory_region_transaction_begin/commit and
have to access BQL.

Some untested idea to investigate:
-- >8 --
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index fea22200135..b2a809cb3db 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1726,3 +1726,6 @@ static bool vtd_as_pt_enabled(VTDAddressSpace *as)

-/* Return whether the device is using IOMMU translation. */
+/*
+ * Return whether the device is using IOMMU translation.
+ * Called with BQL locked.
+ */
 static bool vtd_switch_address_space(VTDAddressSpace *as)
@@ -1730,4 +1733,2 @@ 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();

@@ -1743,10 +1744,3 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)

-    /*
-     * It's possible that we reach here without BQL, e.g., when called
-     * 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();
-    }
+    memory_region_transaction_begin();

@@ -1803,5 +1797,3 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)

-    if (take_bql) {
-        bql_unlock();
-    }
+    memory_region_transaction_commit();

@@ -1905,2 +1897,4 @@ static void vtd_pt_enable_fast_path(IntelIOMMUState *s, uint16_t source_id)

+    BQL_LOCK_GUARD();
+
     if (vtd_switch_address_space(vtd_as) == false) {
@@ -4241,6 +4235,3 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,

- /* Some functions in this branch require the bql, make sure we own it */
-        if (take_bql) {
-            bql_lock();
-        }
+        memory_region_transaction_begin();

@@ -4313,5 +4304,3 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus,

-        if (take_bql) {
-            bql_unlock();
-        }
+        memory_region_transaction_commit();

---


Reply via email to