[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 08/11] vpci: Refactor vpci_remove_register to remove matched registers


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jiqian Chen <Jiqian.Chen@xxxxxxx>
  • Date: Mon, 21 Apr 2025 14:19:00 +0800
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=U+g97RZjgCjOmy0NNzS3RYBikm+tUCQTcif7ks3wE9M=; b=ev7D3gETMvQ18/tOIR+QsS2YxSjSlO0b/2ulkWtzjo7V0Lc/e+sXOjHeLw0EJcQJuKcosxdPgfCWTi55I9o+wBMLoYX4i/2ofH1r922MR+Uiza6pajgDKM+pL3sQvgWqieH7XuwEusTuMZdsOIbbLuW5luIpfWhViAzu0gCc1YcHJwwF+hQlHl8l8LWyTfOzNHdom5ZgIVzcRXZGez7LITt67XMQdfnt73mu5CQJcU4jNsIe6nw34qXGgX4jrpqtDQzSjX4DrSvjBr0zU6WHJVaRMo2hz0ZHi2oivUzaRaWvH1ZECA0MJBqn5H3Hu8dNvjJ1GMQ5nKXXdnSIrZ3vOA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=QIjsrsAXzAJ/2H8L8KLTo2DPQPmLKM481ZTK4/yjf+TcKYabt+pa2mlyx8AnRzV3KPXtDZjel9sGvqf99f8Q4f6lIdXMpfUqNBo6baadCGJGTSKmlpmn+MPGvl3pJTa01cl1CC82U+rRdyE/qY3L8FPtun39jFnXdIBidUbf5ZhL1ph+4sH+n/JbIzlaojvtu/eoNCCtCbefY9IIyl5t5ycI27JsV/rT4+7WKuWuVpieCSeSawHrpiR60eyvAPR6LBd2CyzmJRPGUKWkLH6crzpPq2MUjQtYaae+s0iKmrandHSSZQ6Q1VuG280lH/bTvPArm6JOHJ0gM+I/Z31Tsw==
  • Cc: Huang Rui <ray.huang@xxxxxxx>, Jiqian Chen <Jiqian.Chen@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>
  • Delivery-date: Mon, 21 Apr 2025 06:19:47 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

vpci_remove_register() only supports removing a register in a time,
but the follow-on changes need to remove all registers within a
range. And vpci_remove_register() is only used for test currently.
So, refactor it to support removing all matched registers in a
calling time.

And it is no matter to remove a non exist register, so remove the
__must_check prefix.

Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx>
---
cc: "Roger Pau Monné" <roger.pau@xxxxxxxxxx>
cc: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
v2->v3 changes:
* Add new check to return error if registers overlap but not inside range.

v1->v2 changes:
new patch

Best regards,
Jiqian Chen.
---
 tools/tests/vpci/main.c |  4 ++--
 xen/drivers/vpci/vpci.c | 34 ++++++++++++++++++++--------------
 xen/include/xen/vpci.h  |  4 ++--
 3 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/tools/tests/vpci/main.c b/tools/tests/vpci/main.c
index 33223db3eb77..ca72877d60cd 100644
--- a/tools/tests/vpci/main.c
+++ b/tools/tests/vpci/main.c
@@ -132,10 +132,10 @@ static void vpci_write32_mask(const struct pci_dev *pdev, 
unsigned int reg,
                                   rsvdz_mask))
 
 #define VPCI_REMOVE_REG(off, size)                                          \
-    assert(!vpci_remove_register(test_pdev.vpci, off, size))
+    assert(!vpci_remove_registers(test_pdev.vpci, off, size))
 
 #define VPCI_REMOVE_INVALID_REG(off, size)                                  \
-    assert(vpci_remove_register(test_pdev.vpci, off, size))
+    assert(vpci_remove_registers(test_pdev.vpci, off, size))
 
 /* Read a 32b register using all possible sizes. */
 void multiread4_check(unsigned int reg, uint32_t val)
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index 8ff5169bdd18..904770628a2a 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -497,34 +497,40 @@ int vpci_add_register_mask(struct vpci *vpci, vpci_read_t 
*read_handler,
     return 0;
 }
 
-int vpci_remove_register(struct vpci *vpci, unsigned int offset,
-                         unsigned int size)
+int vpci_remove_registers(struct vpci *vpci, unsigned int start,
+                          unsigned int size)
 {
-    const struct vpci_register r = { .offset = offset, .size = size };
     struct vpci_register *rm;
+    unsigned int end = start + size;
 
     spin_lock(&vpci->lock);
     list_for_each_entry ( rm, &vpci->handlers, node )
     {
-        int cmp = vpci_register_cmp(&r, rm);
-
-        /*
-         * NB: do not use a switch so that we can use break to
-         * get out of the list loop earlier if required.
-         */
-        if ( !cmp && rm->offset == offset && rm->size == size )
+        /* Remove rm if rm is inside the range. */
+        if ( rm->offset >= start && rm->offset + rm->size <= end )
         {
+            struct vpci_register *prev =
+                list_entry(rm->node.prev, struct vpci_register, node);
+
             list_del(&rm->node);
-            spin_unlock(&vpci->lock);
             xfree(rm);
-            return 0;
+            rm = prev;
+            continue;
         }
-        if ( cmp <= 0 )
+
+        /* Return error if registers overlap but not inside. */
+        if ( rm->offset + rm->size > start && rm->offset < end )
+        {
+            spin_unlock(&vpci->lock);
+            return -EINVAL;
+        }
+
+        if ( start < rm->offset )
             break;
     }
     spin_unlock(&vpci->lock);
 
-    return -ENOENT;
+    return 0;
 }
 
 /* Wrappers for performing reads/writes to the underlying hardware. */
diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h
index 8e815b418b7d..4e226331fdf3 100644
--- a/xen/include/xen/vpci.h
+++ b/xen/include/xen/vpci.h
@@ -69,8 +69,8 @@ static inline int __must_check vpci_add_register(struct vpci 
*vpci,
                                   size, data, 0, 0, 0, 0);
 }
 
-int __must_check vpci_remove_register(struct vpci *vpci, unsigned int offset,
-                                      unsigned int size);
+int vpci_remove_registers(struct vpci *vpci, unsigned int start,
+                          unsigned int size);
 
 /* Generic read/write handlers for the PCI config space. */
 uint32_t vpci_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int size);
-- 
2.34.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.