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

[RFC PATCH 2/9] Use GNTTAB_INTERFACE_V5


  • To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
  • Date: Fri, 23 Oct 2026 17:14:10 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID"
  • Cc: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
  • Delivery-date: Fri, 23 Oct 2026 15:14:30 +0000
  • Feedback-id: default:8631fc262581453bbf619ec5b2062170:Sweego
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

GNTTAB v5 fails straight away if the backend is still using the grant.
Spin in GranterPut until the backend lets go; otherwise, the caller
could reuse the page while the backend is still accessing it.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
 include/gnttab_interface.h | 90 ++++++++++++++++++++++++++++----------
 src/xenvbd.inf             |  6 +--
 src/xenvbd/granter.c       | 17 ++++---
 3 files changed, 81 insertions(+), 32 deletions(-)

diff --git a/include/gnttab_interface.h b/include/gnttab_interface.h
index 92a95a7..3ca4407 100644
--- a/include/gnttab_interface.h
+++ b/include/gnttab_interface.h
@@ -132,6 +132,26 @@ typedef NTSTATUS
     _Outptr_ PXENBUS_GNTTAB_ENTRY   *Entry
     );
 
+/*! \typedef XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS_V2
+    \brief Revoke foreign access and return the \a Entry to the \a Cache
+
+    \param Interface The interface header
+    \param Cache The grant table cache handle
+    \param Locked If mutually exclusive access to the cache is already
+    guaranteed then set this to TRUE
+    \param Entry The grant table entry handle
+
+    If the foreign domain is still accessing the granted page, this retries
+    for a while before giving up.
+*/
+typedef NTSTATUS
+(*XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS_V2)(
+    _In_ PINTERFACE                 Interface,
+    _In_ PXENBUS_GNTTAB_CACHE       Cache,
+    _In_ BOOLEAN                    Locked,
+    _In_ PXENBUS_GNTTAB_ENTRY       Entry
+    );
+
 /*! \typedef XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS
     \brief Revoke foreign access and return the \a Entry to the \a Cache
 
@@ -140,6 +160,12 @@ typedef NTSTATUS
     \param Locked If mutually exclusive access to the cache is already
     guaranteed then set this to TRUE
     \param Entry The grant table entry handle
+    \return STATUS_DEVICE_BUSY if the foreign domain is still accessing the
+    granted page
+
+    This does not wait for the foreign domain. On failure, foreign access
+    remains in effect and \a Entry remains valid: the caller must keep the
+    granted page alive, and should retry the revocation later.
 */
 typedef NTSTATUS
 (*XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS)(
@@ -239,16 +265,16 @@ DEFINE_GUID(GUID_XENBUS_GNTTAB_INTERFACE,
     \ingroup interfaces
 */
 struct _XENBUS_GNTTAB_INTERFACE_V2 {
-    INTERFACE                           Interface;
-    XENBUS_GNTTAB_ACQUIRE               GnttabAcquire;
-    XENBUS_GNTTAB_RELEASE               GnttabRelease;
-    XENBUS_GNTTAB_CREATE_CACHE_V1       GnttabCreateCacheVersion1;
-    XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS GnttabPermitForeignAccess;
-    XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS GnttabRevokeForeignAccess;
-    XENBUS_GNTTAB_GET_REFERENCE         GnttabGetReference;
-    XENBUS_GNTTAB_DESTROY_CACHE         GnttabDestroyCache;
-    XENBUS_GNTTAB_MAP_FOREIGN_PAGES     GnttabMapForeignPages;
-    XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES   GnttabUnmapForeignPages;
+    INTERFACE                               Interface;
+    XENBUS_GNTTAB_ACQUIRE                   GnttabAcquire;
+    XENBUS_GNTTAB_RELEASE                   GnttabRelease;
+    XENBUS_GNTTAB_CREATE_CACHE_V1           GnttabCreateCacheVersion1;
+    XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS     GnttabPermitForeignAccess;
+    XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS_V2  GnttabRevokeForeignAccessVersion2;
+    XENBUS_GNTTAB_GET_REFERENCE             GnttabGetReference;
+    XENBUS_GNTTAB_DESTROY_CACHE             GnttabDestroyCache;
+    XENBUS_GNTTAB_MAP_FOREIGN_PAGES         GnttabMapForeignPages;
+    XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES       GnttabUnmapForeignPages;
 };
 
 /*! \struct _XENBUS_GNTTAB_INTERFACE_V3
@@ -256,17 +282,17 @@ struct _XENBUS_GNTTAB_INTERFACE_V2 {
     \ingroup interfaces
 */
 struct _XENBUS_GNTTAB_INTERFACE_V3 {
-    INTERFACE                           Interface;
-    XENBUS_GNTTAB_ACQUIRE               GnttabAcquire;
-    XENBUS_GNTTAB_RELEASE               GnttabRelease;
-    XENBUS_GNTTAB_CREATE_CACHE_V1       GnttabCreateCacheVersion1;
-    XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS GnttabPermitForeignAccess;
-    XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS GnttabRevokeForeignAccess;
-    XENBUS_GNTTAB_GET_REFERENCE         GnttabGetReference;
-    XENBUS_GNTTAB_QUERY_REFERENCE       GnttabQueryReference;
-    XENBUS_GNTTAB_DESTROY_CACHE         GnttabDestroyCache;
-    XENBUS_GNTTAB_MAP_FOREIGN_PAGES     GnttabMapForeignPages;
-    XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES   GnttabUnmapForeignPages;
+    INTERFACE                               Interface;
+    XENBUS_GNTTAB_ACQUIRE                   GnttabAcquire;
+    XENBUS_GNTTAB_RELEASE                   GnttabRelease;
+    XENBUS_GNTTAB_CREATE_CACHE_V1           GnttabCreateCacheVersion1;
+    XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS     GnttabPermitForeignAccess;
+    XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS_V2  GnttabRevokeForeignAccessVersion2;
+    XENBUS_GNTTAB_GET_REFERENCE             GnttabGetReference;
+    XENBUS_GNTTAB_QUERY_REFERENCE           GnttabQueryReference;
+    XENBUS_GNTTAB_DESTROY_CACHE             GnttabDestroyCache;
+    XENBUS_GNTTAB_MAP_FOREIGN_PAGES         GnttabMapForeignPages;
+    XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES       GnttabUnmapForeignPages;
 };
 
 /*! \struct _XENBUS_GNTTAB_INTERFACE_V4
@@ -274,6 +300,24 @@ struct _XENBUS_GNTTAB_INTERFACE_V3 {
     \ingroup interfaces
 */
 struct _XENBUS_GNTTAB_INTERFACE_V4 {
+    INTERFACE                               Interface;
+    XENBUS_GNTTAB_ACQUIRE                   GnttabAcquire;
+    XENBUS_GNTTAB_RELEASE                   GnttabRelease;
+    XENBUS_GNTTAB_CREATE_CACHE              GnttabCreateCache;
+    XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS     GnttabPermitForeignAccess;
+    XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS_V2  GnttabRevokeForeignAccessVersion2;
+    XENBUS_GNTTAB_GET_REFERENCE             GnttabGetReference;
+    XENBUS_GNTTAB_QUERY_REFERENCE           GnttabQueryReference;
+    XENBUS_GNTTAB_DESTROY_CACHE             GnttabDestroyCache;
+    XENBUS_GNTTAB_MAP_FOREIGN_PAGES         GnttabMapForeignPages;
+    XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES       GnttabUnmapForeignPages;
+};
+
+/*! \struct _XENBUS_GNTTAB_INTERFACE_V5
+    \brief GNTTAB interface version 5
+    \ingroup interfaces
+*/
+struct _XENBUS_GNTTAB_INTERFACE_V5 {
     INTERFACE                           Interface;
     XENBUS_GNTTAB_ACQUIRE               GnttabAcquire;
     XENBUS_GNTTAB_RELEASE               GnttabRelease;
@@ -287,7 +331,7 @@ struct _XENBUS_GNTTAB_INTERFACE_V4 {
     XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES   GnttabUnmapForeignPages;
 };
 
-typedef struct _XENBUS_GNTTAB_INTERFACE_V4 XENBUS_GNTTAB_INTERFACE, 
*PXENBUS_GNTTAB_INTERFACE;
+typedef struct _XENBUS_GNTTAB_INTERFACE_V5 XENBUS_GNTTAB_INTERFACE, 
*PXENBUS_GNTTAB_INTERFACE;
 
 /*! \def XENBUS_GNTTAB
     \brief Macro at assist in method invocation
@@ -298,6 +342,6 @@ typedef struct _XENBUS_GNTTAB_INTERFACE_V4 
XENBUS_GNTTAB_INTERFACE, *PXENBUS_GNT
 #endif  // _WINDLL
 
 #define XENBUS_GNTTAB_INTERFACE_VERSION_MIN 2
-#define XENBUS_GNTTAB_INTERFACE_VERSION_MAX 4
+#define XENBUS_GNTTAB_INTERFACE_VERSION_MAX 5
 
 #endif  // _XENBUS_GNTTAB_INTERFACE_H
diff --git a/src/xenvbd.inf b/src/xenvbd.inf
index 28405f6..055ffdc 100644
--- a/src/xenvbd.inf
+++ b/src/xenvbd.inf
@@ -54,9 +54,9 @@ xencrsh.sys=0,,
 
 [Inst.NT@INF_ARCH@]
 %XenVbdName%=XenVbd_Inst,\
-XENBUS\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_VBD&REV_0900000C,\
-XENBUS\VEN_@VENDOR_PREFIX@0001&DEV_VBD&REV_0900000C,\
-XENBUS\VEN_@VENDOR_PREFIX@0002&DEV_VBD&REV_0900000C
+XENBUS\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_VBD&REV_0900000D,\
+XENBUS\VEN_@VENDOR_PREFIX@0001&DEV_VBD&REV_0900000D,\
+XENBUS\VEN_@VENDOR_PREFIX@0002&DEV_VBD&REV_0900000D
 
 [XenVbd_Inst] 
 CopyFiles=XenVbd_Copyfiles
diff --git a/src/xenvbd/granter.c b/src/xenvbd/granter.c
index eddcdcf..0673891 100644
--- a/src/xenvbd/granter.c
+++ b/src/xenvbd/granter.c
@@ -358,12 +358,17 @@ GranterPut(
     if (Granter->Connected == FALSE)
         return;
 
-    status = XENBUS_GNTTAB(RevokeForeignAccess,
-                           &Granter->GnttabInterface,
-                           Granter->Cache,
-                           FALSE,
-                           Entry);
-    ASSERT(NT_SUCCESS(status));
+    for (;;) {
+        status = XENBUS_GNTTAB(RevokeForeignAccess,
+                               &Granter->GnttabInterface,
+                               Granter->Cache,
+                               FALSE,
+                               Entry);
+        if (NT_SUCCESS(status))
+            break;
+
+        YieldProcessor();
+    }
 
     InterlockedDecrement(&Granter->Current);
 }
-- 
2.56.0.windows.3



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

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