From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:20:44 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:20:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468129.1677163 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq5j-0000wo-Ez; Mon, 02 Nov 2026 11:20:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468129.1677163; Mon, 02 Nov 2026 11:20:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq5j-0000wh-CI; Mon, 02 Nov 2026 11:20:43 +0000
Received: by outflank-mailman (input) for mailman id 1468129;
 Mon, 02 Nov 2026 11:20:41 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@swg.vates.tech>)
 id 1xNq5h-0000vT-CD
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:20:41 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq5g-00GWF4-7j
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:20:40 +0100
Received: from [10.42.69.10] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@swg.vates.tech>)
 id 6ae87200-2eae-0a2a0a5409dd-0a2a450aadb4-24
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:20:40 +0100
Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net)
 by tlsNG-4011c0.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@swg.vates.tech>)
 id 6ae87207-f2d2-0a2a450a0019-b9ff1c22ae97-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:20:40 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bfd5b0f000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:20:34 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id E6DB38282D;
 Mon,  2 Nov 2026 12:20:33 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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:Feedback-ID"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=SLJSbBJtJHmds+ldIcjzo1zS0pu0/PZUKe00gF5cCFk=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:feedback-id;
 b=Rl35+bnrRjMD7l0WyLBa6D8Hy7gTeMHmqJcNWa1NAhUgsthTDD9mfMGyQjNCqX8maOapaNDtZ
 NOne9E4C6mPCmHNfRj+iV4P3vUpnmmP6gphrFQw5eVR/eRpGXC3sOuTV3hGq4Qr6HluevijmdRW
 AliMiFWdCDSNYrpHcbGCgqqeTWqo66HFckp4KVs8H2fFD9PAtfpkiziFOBffmEzPCR5gOSteLvK
 V3fYfzFk6bCLo0rKgY+dXhGSXUTIFHDn7KQ+Nrn8GKzbUP/rxW1+eQLybPgWEWBZ8cB84GN7jqj
 d/WmHxvU5ymq2L0BzBwbC/8mio43fcAgqY86ijhIgKSw==
X-Zone-Loop: 39a7bc50cc557d21d4134ed6284396dab0a7a52bce12
x-campaign-type: default
x-transaction-id: e298e386-5721-4e93-8431-8d8ecbd6003e
x-swg-uid: 01-b2ca6398-2cca-4804-b267-44faf4705cbd
X-Mailer: Sweego
Message-ID:
 <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
x-swg-bid: 1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 00/11] Defer completion and ring destruction until backend grant release
Date: Mon,  2 Nov 2026 12:20:29 +0100
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.36b.7508632ee3950a69.1a19bfd57d5.8dbcffa201ace5e9=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618434005
X-purgate-ID: tlsNG-4011c0/1793618440-528DDCFC-2ABEE358/0/0
X-purgate-type: clean
X-purgate-size: 2921

---=Part.36b.7508632ee3950a69.1a19bfd57d5.8dbcffa201ace5e9=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

When a backend is accessing a grant entry, it'll set the GTF_reading|
GTF_writing bits on that entry=2E RevokeForeignAccess will fail as long as
these bits are still set=2E

WinPV drivers assume that you can ignore RevokeForeignAccess failures
after a certain number of retries=2E This is unfortunately not the case,
as backends can still access the grants and corrupt things=2E We've
observed data corruption that we suspect as being caused by this issue=2E

This series converts RevokeForeignAccess into a fallible call named
TryRevokeForeignAccess, and fixes the problem by deferring request
completion and ring destruction until after the corresponding grants
have been released by the backend=2E

It has undergone testing using a harness for suspending I/O handling at
critical points, and showed no deadlock or data corruption when the
associated issues in tapdisk are fixed=2E

This is the first series of fix for a class of similar issues=2E Further
fixes will be needed in other drivers using the grant interface (esp=2E
XenVif, XenIface); there are also other issues that have not been
discussed in this series=2E

Changes in v3:
* Try harder to release existing grants before deferring a request
* Add yet another fix to defer faking submitted requests until
  disconnect

Changes in V2:
* Rename RevokeForeignAccess in GNTTAB V5 to TryRevokeForeignAccess
* Fix a deadlock during RingD0ToD3 (see the "ring: Defer destruction
  until backend grant release" commit for more details)
* Add a fix for a C6387 warning in BlkifRing

Tu Dinh (11):
  ring: Fix warning C6387: 'BlkifRing' could be '0'
  granter: Correct the accounting of Current
  Use GNTTAB_INTERFACE_V5
  frontend: Initialize the granter before the ring
  granter: Split GranterTryPut to its own function
  granter: Decouple cache lifetime from Connected
  granter: Introduce GranterD0ToD3/D3ToD0
  ring: Introduce RingD3ToD0/RingD0ToD3
  ring: Defer destruction until backend grant release
  ring: Defer request completion until backend grant release
  ring: Defer faking submitted requests until disconnect

 include/gnttab_interface=2Eh | 116 ++++--
 src/xenvbd=2Einf             |   6 +-
 src/xenvbd/frontend=2Ec      |  63 ++--
 src/xenvbd/frontend=2Eh      |   4 +-
 src/xenvbd/granter=2Ec       | 177 +++++++--
 src/xenvbd/granter=2Eh       |  17 +-
 src/xenvbd/ring=2Ec          | 737 ++++++++++++++++++++++++++++++-------
 src/xenvbd/ring=2Eh          |  13 +
 8 files changed, 887 insertions(+), 246 deletions(-)

--
2=2E56=2E0=2Ewindows=2E4


-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.36b.7508632ee3950a69.1a19bfd57d5.8dbcffa201ace5e9=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:28 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:28 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468130.1677166 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7Q-0001E0-Jx; Mon, 02 Nov 2026 11:22:28 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468130.1677166; Mon, 02 Nov 2026 11:22:28 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7Q-0001Dt-HQ; Mon, 02 Nov 2026 11:22:28 +0000
Received: by outflank-mailman (input) for mailman id 1468130;
 Mon, 02 Nov 2026 11:22:27 +0000
Received: from mx.expurgate.net ([195.190.135.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff00f7000403d@swg.vates.tech>)
 id 1xNq7O-0001Dn-Of
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:26 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7N-00AYCq-Rg
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:25 +0100
Received: from [10.42.69.1] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff00f7000403d@swg.vates.tech>)
 id 6ae87265-e002-0a2a0a5209dd-0a2a45019232-48
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:25 +0100
Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net)
 by tlsNG-d62444.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff00f7000403d@swg.vates.tech>)
 id 6ae87271-5984-0a2a45010019-b9ff1c228255-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:25 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff00f7000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:22 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 0369F80D91;
 Mon,  2 Nov 2026 12:22:22 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=CLkTyNYTBHjJQ+wpgB17bdg4ASb3Wum7hweEhddF7qM=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=ZVxE7MXwyReFFv60rMep5F2aqc0hNMjeILHk+ODHU4Fy1KwyyAOoKWGbnkiKLvIf3PQlHOcv0
 l80SX5R9Ua8AQb5uIxfAPyZPZITH8KfRJaHyErjTT48gErMyuPydxUtRo4+hYaWs4VQdNi0Q1Il
 9JMvnkKxZjMcqiOaamFyccD5LTseDG+7DDcZkJfTNOl/Ai9Ioww7buhhrTiXSc8c65yU9MF4GgG
 TuJ/mqI1dkcL347R9kBl11+MaixNHyy/UiWBjCnKcTmQjNpVLN9ya/x+rgwOS+i3KBwMk2dOzzd
 GCgC2OhSqroBLMnXrbg4ymHC2X4jDsD1hMGoNK3uIHvQ==
X-Zone-Loop: 8898f0203dba4bd1d0b293122141e527a8b6edea70bb
x-campaign-type: default
x-transaction-id: b4222220-22b8-4c47-bc40-2d8037007c8f
x-swg-uid: 01-b8a7f35f-e253-45f8-8615-ed89944faddc
X-Mailer: Sweego
Message-ID:
 <1793618542.8631fc262581453bbf619ec5b2062170.1a19bff00f7000403d@vates.tech>
x-swg-bid: 1793618542.8631fc262581453bbf619ec5b2062170.1a19bff00f7000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3] Add GNTTAB_INTERFACE_V5
Date: Mon,  2 Nov 2026 12:20:44 +0100
In-Reply-To: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.36d.c437aaad48008fbe.1a19bfefdfc.18b9ab2259947437=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618542076
X-purgate-ID: tlsNG-d62444/1793618545-1F262757-D11595F0/0/0
X-purgate-type: clean
X-purgate-size: 15117

---=Part.36d.c437aaad48008fbe.1a19bfefdfc.18b9ab2259947437=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Rework RevokeForeignAccess into TryRevokeForeignAccess=2E Avoid retrying
and calling SCHEDOP_yield in TryRevokeForeignAccess=2E Leave the retry
logic to the individual drivers instead, because individual drivers need
to revoke grants in the background to avoid having backends trample over
pages that have an active grant entry yet have already been released to
the OS=2E

RevokeForeignAccessV2 continues providing the retry logic to legacy
clients=2E

Note that TryRevokeForeignAccess in GNTTAB_INTERFACE_V5 cannot
transparently replace RevokeForeignAccessV2 because of semantic changes=2E
Migrating to GNTTAB_INTERFACE_V5 requires reimplementing the drivers'
grant revocation path=2E

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 include/gnttab_interface=2Eh | 116 +++++++++++++++++++++++++------------
 include/revision=2Eh         |   3 +-
 src/xenbus/gnttab=2Ec        |  82 +++++++++++++++++++++-----
 3 files changed, 150 insertions(+), 51 deletions(-)

diff --git a/include/gnttab_interface=2Eh b/include/gnttab_interface=2Eh
index 92a95a7=2E=2E40ea821 100644
--- a/include/gnttab_interface=2Eh
+++ b/include/gnttab_interface=2Eh
@@ -132,7 +132,7 @@ typedef NTSTATUS
     _Outptr_ PXENBUS_GNTTAB_ENTRY   *Entry
     );
=20
-/*! \typedef XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS
+/*! \typedef XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS_V2
     \brief Revoke foreign access and return the \a Entry to the \a Cache
=20
     \param Interface The interface header
@@ -140,9 +140,35 @@ 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
+
+    If the foreign domain is still accessing the granted page, this retri=
es
+    for a while before giving up=2E
 */
 typedef NTSTATUS
-(*XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS)(
+(*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_TRY_REVOKE_FOREIGN_ACCESS
+    \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
+    \return STATUS_DEVICE_BUSY if the foreign domain is still accessing t=
he
+    granted page
+
+    This does not wait for the foreign domain=2E On failure, foreign acce=
ss
+    remains in effect and \a Entry remains valid: the caller must keep th=
e
+    granted page alive, and should retry the revocation later=2E
+*/
+typedef NTSTATUS
+(*XENBUS_GNTTAB_TRY_REVOKE_FOREIGN_ACCESS)(
     _In_ PINTERFACE                 Interface,
     _In_ PXENBUS_GNTTAB_CACHE       Cache,
     _In_ BOOLEAN                    Locked,
@@ -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  GnttabRevokeForeignAccessVers=
ion2;
+    XENBUS_GNTTAB_GET_REFERENCE             GnttabGetReference;
+    XENBUS_GNTTAB_DESTROY_CACHE             GnttabDestroyCache;
+    XENBUS_GNTTAB_MAP_FOREIGN_PAGES         GnttabMapForeignPages;
+    XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES       GnttabUnmapForeignPages;
 };
=20
 /*! \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  GnttabRevokeForeignAccessVers=
ion2;
+    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;
 };
=20
 /*! \struct _XENBUS_GNTTAB_INTERFACE_V4
@@ -274,20 +300,38 @@ 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 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              GnttabCreateCache;
+    XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS     GnttabPermitForeignAccess;
+    XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS_V2  GnttabRevokeForeignAccessVers=
ion2;
+    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;
+    XENBUS_GNTTAB_CREATE_CACHE              GnttabCreateCache;
+    XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS     GnttabPermitForeignAccess;
+    XENBUS_GNTTAB_TRY_REVOKE_FOREIGN_ACCESS GnttabTryRevokeForeignAccess;
+    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;
 };
=20
-typedef struct _XENBUS_GNTTAB_INTERFACE_V4 XENBUS_GNTTAB_INTERFACE, *PXEN=
BUS_GNTTAB_INTERFACE;
+typedef struct _XENBUS_GNTTAB_INTERFACE_V5 XENBUS_GNTTAB_INTERFACE, *PXEN=
BUS_GNTTAB_INTERFACE;
=20
 /*! \def XENBUS_GNTTAB
     \brief Macro at assist in method invocation
@@ -298,6 +342,6 @@ typedef struct _XENBUS_GNTTAB_INTERFACE_V4 XENBUS_GNTT=
AB_INTERFACE, *PXENBUS_GNT
 #endif  // _WINDLL
=20
 #define XENBUS_GNTTAB_INTERFACE_VERSION_MIN 2
-#define XENBUS_GNTTAB_INTERFACE_VERSION_MAX 4
+#define XENBUS_GNTTAB_INTERFACE_VERSION_MAX 5
=20
 #endif  // _XENBUS_GNTTAB_INTERFACE_H
diff --git a/include/revision=2Eh b/include/revision=2Eh
index a63e550=2E=2Ec1ab047 100644
--- a/include/revision=2Eh
+++ b/include/revision=2Eh
@@ -52,6 +52,7 @@
     DEFINE_REVISION(0x09000009,  1,  4,  9,  1,  2,  1,  2,  4,  1,  1,  =
2), \
     DEFINE_REVISION(0x0900000A,  1,  4,  9,  1,  2,  1,  2,  4,  2,  1,  =
2), \
     DEFINE_REVISION(0x0900000B,  1,  4,  9,  1,  2,  1,  2,  4,  3,  1,  =
2), \
-    DEFINE_REVISION(0x0900000C,  1,  4,  9,  1,  2,  1,  2,  4,  3,  1,  =
3)
+    DEFINE_REVISION(0x0900000C,  1,  4,  9,  1,  2,  1,  2,  4,  3,  1,  =
3), \
+    DEFINE_REVISION(0x0900000D,  1,  4,  9,  1,  2,  1,  2,  5,  3,  1,  =
3)
=20
 #endif  // _REVISION_H
diff --git a/src/xenbus/gnttab=2Ec b/src/xenbus/gnttab=2Ec
index bdf8b2b=2E=2E4c9b505 100644
--- a/src/xenbus/gnttab=2Ec
+++ b/src/xenbus/gnttab=2Ec
@@ -548,7 +548,7 @@ fail1:
 }
=20
 static NTSTATUS
-GnttabRevokeForeignAccess(
+GnttabTryRevokeForeignAccess(
     _In_ PINTERFACE             Interface,
     _In_ PXENBUS_GNTTAB_CACHE   Cache,
     _In_ BOOLEAN                Locked,
@@ -559,8 +559,6 @@ GnttabRevokeForeignAccess(
     PXENBUS_GNTTAB_FRAME        Frame;
     ULONG                       Index;
     volatile SHORT              *flags;
-    ULONG                       Attempt;
-    NTSTATUS                    status;
=20
     ASSERT3U(Entry->Magic, =3D=3D, XENBUS_GNTTAB_ENTRY_MAGIC);
     ASSERT3U(Entry->Reference, >=3D, XENBUS_GNTTAB_RESERVED_ENTRY_COUNT);
@@ -571,25 +569,21 @@ GnttabRevokeForeignAccess(
=20
     flags =3D (volatile SHORT *)&Frame->Entry[Index]=2Eflags;
=20
-    for (Attempt =3D 0; Attempt < 100; Attempt++) {
+    for (;;) {
         uint16_t    Old;
         uint16_t    New;
=20
         Old =3D *flags;
-        Old &=3D ~(GTF_reading | GTF_writing);
+
+        if (Old & (GTF_reading | GTF_writing))
+            return STATUS_DEVICE_BUSY;
=20
         New =3D Old & ~GTF_permit_access;
=20
         if (InterlockedCompareExchange16(flags, New, Old) =3D=3D Old)
             break;
-
-        SchedYield();
     }
=20
-    status =3D STATUS_UNSUCCESSFUL;
-    if (Attempt =3D=3D 100)
-        goto fail1;
-
     RtlZeroMemory(&Frame->Entry[Index], sizeof (grant_entry_v1_t));
     RtlZeroMemory(&Entry->Entry, sizeof (grant_entry_v1_t));
=20
@@ -600,6 +594,35 @@ GnttabRevokeForeignAccess(
                  Locked);
=20
     return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+GnttabRevokeForeignAccessVersion2(
+    _In_ PINTERFACE             Interface,
+    _In_ PXENBUS_GNTTAB_CACHE   Cache,
+    _In_ BOOLEAN                Locked,
+    _In_ PXENBUS_GNTTAB_ENTRY   Entry
+    )
+{
+    ULONG                       Attempt;
+    NTSTATUS                    status;
+
+    for (Attempt =3D 0; Attempt < 100; Attempt++) {
+        status =3D GnttabTryRevokeForeignAccess(Interface,
+                                              Cache,
+                                              Locked,
+                                              Entry);
+        if (NT_SUCCESS(status))
+            break;
+
+        SchedYield();
+    }
+
+    status =3D STATUS_UNSUCCESSFUL;
+    if (Attempt =3D=3D 100)
+        goto fail1;
+
+    return STATUS_SUCCESS;
=20
 fail1:
     Error("fail1 (%08x)\n", status);
@@ -1044,7 +1067,7 @@ static struct _XENBUS_GNTTAB_INTERFACE_V2   GnttabIn=
terfaceVersion2 =3D {
     GnttabRelease,
     GnttabCreateCacheVersion1,
     GnttabPermitForeignAccess,
-    GnttabRevokeForeignAccess,
+    GnttabRevokeForeignAccessVersion2,
     GnttabGetReference,
     GnttabDestroyCache,
     GnttabMapForeignPages,
@@ -1057,7 +1080,7 @@ static struct _XENBUS_GNTTAB_INTERFACE_V3   GnttabIn=
terfaceVersion3 =3D {
     GnttabRelease,
     GnttabCreateCacheVersion1,
     GnttabPermitForeignAccess,
-    GnttabRevokeForeignAccess,
+    GnttabRevokeForeignAccessVersion2,
     GnttabGetReference,
     GnttabQueryReference,
     GnttabDestroyCache,
@@ -1071,7 +1094,21 @@ static struct _XENBUS_GNTTAB_INTERFACE_V4   GnttabI=
nterfaceVersion4 =3D {
     GnttabRelease,
     GnttabCreateCache,
     GnttabPermitForeignAccess,
-    GnttabRevokeForeignAccess,
+    GnttabRevokeForeignAccessVersion2,
+    GnttabGetReference,
+    GnttabQueryReference,
+    GnttabDestroyCache,
+    GnttabMapForeignPages,
+    GnttabUnmapForeignPages
+};
+
+static struct _XENBUS_GNTTAB_INTERFACE_V5   GnttabInterfaceVersion5 =3D {
+    { sizeof (struct _XENBUS_GNTTAB_INTERFACE_V5), 5, NULL, NULL, NULL },
+    GnttabAcquire,
+    GnttabRelease,
+    GnttabCreateCache,
+    GnttabPermitForeignAccess,
+    GnttabTryRevokeForeignAccess,
     GnttabGetReference,
     GnttabQueryReference,
     GnttabDestroyCache,
@@ -1212,6 +1249,23 @@ GnttabGetInterface(
         status =3D STATUS_SUCCESS;
         break;
     }
+    case 5: {
+        struct _XENBUS_GNTTAB_INTERFACE_V5  *GnttabInterface;
+
+        GnttabInterface =3D (struct _XENBUS_GNTTAB_INTERFACE_V5 *)Interfa=
ce;
+
+        status =3D STATUS_BUFFER_OVERFLOW;
+        if (Size < sizeof (struct _XENBUS_GNTTAB_INTERFACE_V5))
+            break;
+
+        *GnttabInterface =3D GnttabInterfaceVersion5;
+
+        ASSERT3U(Interface->Version, =3D=3D, Version);
+        Interface->Context =3D Context;
+
+        status =3D STATUS_SUCCESS;
+        break;
+    }
     default:
         status =3D STATUS_NOT_SUPPORTED;
         break;
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.36d.c437aaad48008fbe.1a19bfefdfc.18b9ab2259947437=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:43 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468131.1677173 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7f-0001Jt-On; Mon, 02 Nov 2026 11:22:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468131.1677173; Mon, 02 Nov 2026 11:22:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7f-0001Jm-JA; Mon, 02 Nov 2026 11:22:43 +0000
Received: by outflank-mailman (input) for mailman id 1468131;
 Mon, 02 Nov 2026 11:22:41 +0000
Received: from mx.expurgate.net ([195.190.135.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4300000403d@swg.vates.tech>)
 id 1xNq7d-0001It-I0
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:41 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7c-00AYHw-Uj
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:40 +0100
Received: from [10.42.69.10] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4300000403d@swg.vates.tech>)
 id 6ae8727a-8faa-0a2a0a5109dd-0a2a450a8912-18
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:40 +0100
Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net)
 by tlsNG-4011c0.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4300000403d@swg.vates.tech>)
 id 6ae87280-f2d2-0a2a450a0019-b9ff1c238db5-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:40 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff4300000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:39 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 3D51482F57;
 Mon,  2 Nov 2026 12:22:39 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=z7Y1lp6j5g/ZIwctywAgawuoyofsr0g0MtYYUAFKufU=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=YT9+lYDcUf1ayw+vhhyMEdY2NsyftVwQfAsA+hhjFLUpZqtUhd3k5AjO1Eum+mQQcyhFRScqs
 v56RLlVrgsy4HRdBVyJEsYuw6KhRYWRYVO+f6w+yRjqcBN62keADWHSLoFIwJlNFqj6S//+701h
 Hc6w0XpJvdr6ZjyNMj5VIyIkAHsIiJcpJWhmSPPOYYIByacZFbFsQ8SKh+cM7HIZs3toJLH0UCT
 ElJ1Z7Pc2mlWFmtpBoETduFZ0lEUZ0qX9u9+LHF7CLthdy89B+1bmnQh1wcuk27CKcrOOgUX4P9
 ZI5pNW76Y0aoaEawLKOBe2wpLdLUiGXjb4JRAJeClLrA==
X-Zone-Loop: 035f573c78d3da1c5dbce06beed958e22d4cb7fc27f6
x-campaign-type: default
x-transaction-id: 366abaa2-0852-4de4-b8a4-62c5d968ece1
x-swg-uid: 01-2264eae4-4ffc-408e-819a-9107979a6441
X-Mailer: Sweego
Message-ID:
 <1793618559.8631fc262581453bbf619ec5b2062170.1a19bff4300000403d@vates.tech>
x-swg-bid: 1793618559.8631fc262581453bbf619ec5b2062170.1a19bff4300000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 02/11] granter: Correct the accounting of Current
Date: Mon,  2 Nov 2026 12:22:23 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.36f.a03f0a88624266b.1a19bff414b.f22e02672d8b6f7f=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618559307
X-purgate-ID: tlsNG-4011c0/1793618560-516C6CFC-A3267675/0/0
X-purgate-type: clean
X-purgate-size: 1764

---=Part.36f.a03f0a88624266b.1a19bff414b.f22e02672d8b6f7f=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Current serves as an upper bound on the number of taken grants and must
be 0 on GranterDisconnect=2E We must increment Current before calling
PermitForeignAccess, and decrement it again on failure=2E

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xenvbd/granter=2Ec | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/xenvbd/granter=2Ec b/src/xenvbd/granter=2Ec
index fd90965=2E=2Eeddcdcf 100644
--- a/src/xenvbd/granter=2Ec
+++ b/src/xenvbd/granter=2Ec
@@ -319,7 +319,9 @@ GranterGet(
     if (Granter->Connected =3D=3D FALSE)
         goto fail1;
=20
-    status =3D XENBUS_GNTTAB(PermitForeignAccess,=20
+    Value =3D InterlockedIncrement(&Granter->Current);
+
+    status =3D XENBUS_GNTTAB(PermitForeignAccess,
                            &Granter->GnttabInterface,
                            Granter->Cache,
                            FALSE,
@@ -329,8 +331,7 @@ GranterGet(
                            &Entry);
     if (!NT_SUCCESS(status))
         goto fail2;
-   =20
-    Value =3D InterlockedIncrement(&Granter->Current);
+
     if (Value > Granter->Maximum)
         Granter->Maximum =3D Value;
=20
@@ -339,6 +340,7 @@ GranterGet(
=20
 fail2:
     Error("fail2\n");
+    InterlockedDecrement(&Granter->Current);
 fail1:
     Error("fail1 %08x\n", status);
     return status;
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.36f.a03f0a88624266b.1a19bff414b.f22e02672d8b6f7f=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:44 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468133.1677177 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7f-0001Kc-Vj; Mon, 02 Nov 2026 11:22:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468133.1677177; Mon, 02 Nov 2026 11:22:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7f-0001K9-MZ; Mon, 02 Nov 2026 11:22:43 +0000
Received: by outflank-mailman (input) for mailman id 1468133;
 Mon, 02 Nov 2026 11:22:41 +0000
Received: from mx.expurgate.net ([195.190.135.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff44a2000403d@swg.vates.tech>)
 id 1xNq7d-0001Iz-TC
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:41 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7d-00AYId-9p
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [10.42.69.12] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff44a2000403d@swg.vates.tech>)
 id 6ae8727a-e002-0a2a0a5209dd-0a2a450ce2d2-28
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net)
 by tlsNG-d25034.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff44a2000403d@swg.vates.tech>)
 id 6ae87280-f479-0a2a450c0019-b9ff1c22805f-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff44a2000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:40 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id A436980D91;
 Mon,  2 Nov 2026 12:22:39 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=qdCpR98yAtY3YCVKhKymfkar7sa6JxRqU3bDcYxganU=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=M9L3vvmDzF5TCPUx4AiTVwSOSuqVE+/746pINZnignAqwwOn6KzKkZYO5g2oex6Lb+NwKQRfs
 4LM6a6euIMAa894AG/DQzDzKACnW43IFwMT4R/DmHepI4nlY6Y2EHMfgewg4F7D+jtsMYpmARSh
 m4ChBeuYgBhatmZyT6OCpdTCwDoJ7SrnAlA1HGnBVoIttg5YYd+AnWjaHXvUXc+/4aE7eO6cCC7
 gcQdD7Ktj7arnLk3y0DZIh+aZ91EngVUpF0VR8b+UQNWPdN9kkmGL96B09QQDnwSr3x3GADdo0B
 I9RvcVgc0jJKqCb6EnJgx5TRH1QQL7fSOY7+JNkE2Y4Q==
X-Zone-Loop: a0a3e660e836377f55ce34d9ca48d2d02cb943f81630
x-campaign-type: default
x-transaction-id: 2a6125be-47f5-4886-afbc-28a129b4a12e
x-swg-uid: 01-b874b019-102b-49e8-991f-a85fc1649ba0
X-Mailer: Sweego
Message-ID:
 <1793618560.8631fc262581453bbf619ec5b2062170.1a19bff44a2000403d@vates.tech>
x-swg-bid: 1793618560.8631fc262581453bbf619ec5b2062170.1a19bff44a2000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 04/11] frontend: Initialize the granter before the ring
Date: Mon,  2 Nov 2026 12:22:25 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.371.511b5eac77a23092.1a19bff42ef.471469ef3e7d7233=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618559727
X-purgate-ID: tlsNG-d25034/1793618561-51D34A5B-BD9B94A3/0/0
X-purgate-type: clean
X-purgate-size: 2236

---=Part.371.511b5eac77a23092.1a19bff42ef.471469ef3e7d7233=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

This is preparation for deferred grant revocation, as this requires the
granter to outlive the ring=2E

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xenvbd/frontend=2Ec | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/xenvbd/frontend=2Ec b/src/xenvbd/frontend=2Ec
index 06c7295=2E=2E8bf4f96 100644
--- a/src/xenvbd/frontend=2Ec
+++ b/src/xenvbd/frontend=2Ec
@@ -1907,11 +1907,11 @@ FrontendCreate(
     if (!NT_SUCCESS(status))
         goto fail3;
=20
-    status =3D RingCreate(Frontend, &Frontend->Ring);
+    status =3D GranterCreate(Frontend, &Frontend->Granter);
     if (!NT_SUCCESS(status))
         goto fail4;
=20
-    status =3D GranterCreate(Frontend, &Frontend->Granter);
+    status =3D RingCreate(Frontend, &Frontend->Ring);
     if (!NT_SUCCESS(status))
         goto fail5;
=20
@@ -1928,12 +1928,12 @@ FrontendCreate(
=20
 fail6:
     Error("fail6\n");
-    GranterDestroy(Frontend->Granter);
-    Frontend->Granter =3D NULL;
-fail5:
-    Error("fail5\n");
     RingDestroy(Frontend->Ring);
     Frontend->Ring =3D NULL;
+fail5:
+    Error("fail5\n");
+    GranterDestroy(Frontend->Granter);
+    Frontend->Granter =3D NULL;
 fail4:
     Error("fail4\n");
     RtlZeroMemory(Frontend->TargetPath, sizeof(Frontend->TargetPath));
@@ -1970,12 +1970,12 @@ FrontendDestroy(
     ThreadJoin(Frontend->BackendThread);
     Frontend->BackendThread =3D NULL;
=20
-    GranterDestroy(Frontend->Granter);
-    Frontend->Granter =3D NULL;
-
     RingDestroy(Frontend->Ring);
     Frontend->Ring =3D NULL;
=20
+    GranterDestroy(Frontend->Granter);
+    Frontend->Granter =3D NULL;
+
     RtlZeroMemory(&Frontend->StateLock, sizeof(KSPIN_LOCK));
=20
     RtlZeroMemory(Frontend->TargetPath, sizeof(Frontend->TargetPath));
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.371.511b5eac77a23092.1a19bff42ef.471469ef3e7d7233=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:44 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468132.1677175 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7f-0001KH-UI; Mon, 02 Nov 2026 11:22:43 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468132.1677175; Mon, 02 Nov 2026 11:22:43 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7f-0001Jy-KY; Mon, 02 Nov 2026 11:22:43 +0000
Received: by outflank-mailman (input) for mailman id 1468132;
 Mon, 02 Nov 2026 11:22:41 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff43c6000403d@swg.vates.tech>)
 id 1xNq7d-0001Iu-OX
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:41 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7d-00GWnJ-55
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [10.42.69.1] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff43c6000403d@swg.vates.tech>)
 id 6ae8727c-2eae-0a2a0a5409dd-0a2a4501aaac-16
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [185.255.28.18] (helo=prod-mta-13.swg-srv.net)
 by tlsNG-d62444.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff43c6000403d@swg.vates.tech>)
 id 6ae87280-5984-0a2a45010019-b9ff1c128e75-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff43c6000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:39 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 7406582F6F;
 Mon,  2 Nov 2026 12:22:39 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=U9TXcqn23eaCSz+UM4ttHXkmoZodyYZsaKJLXkBX7Fo=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=npdfWLjj1dWVJNXC700jJe4tQrGevA24xkVdI0BtMkIiWBBZ5hhlU7QhEmwTWQmtxC/ucgTL0
 HF7IelvSMsBaHlnVcFgSj2EftGUuprPDWdYMWuAPoYVj55SrYZBc1YXBjUPMMuMPdfnLg5r4A0p
 LVlmL+FvXidvg7OkX9xqWyJO3W8oOoili/8v65ZV+JTK6dF6w16z7a2BGrJH/kzJavV4j02+qly
 jT4O8jV7XQKnvMZnMNQqQgepYCXI5qi7UnYxyezVmY9JgIrYXDglDIB9rSewi5iUoejK0gAVRAM
 1ycVnY3eeL4XSqpFic/fmEH4s8NwfD8zNmoaNz6HTizA==
X-Zone-Loop: c04577ebd505adfecc052a80ed2871a32e6ad5dbe27f
x-campaign-type: default
x-transaction-id: 80095e0e-47d4-4268-a73d-4836770db372
x-swg-uid: 01-34dead57-5ca4-4945-bf65-98c5e80c479f
X-Mailer: Sweego
Message-ID:
 <1793618560.8631fc262581453bbf619ec5b2062170.1a19bff43c6000403d@vates.tech>
x-swg-bid: 1793618560.8631fc262581453bbf619ec5b2062170.1a19bff43c6000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 03/11] Use GNTTAB_INTERFACE_V5
Date: Mon,  2 Nov 2026 12:22:24 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.370.9659bd1b01ced8f8.1a19bff422a.d15ad41fa6deb53f=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618559530
X-purgate-ID: tlsNG-d62444/1793618561-1DA7E757-29DBF745/0/0
X-purgate-type: clean
X-purgate-size: 10681

---=Part.370.9659bd1b01ced8f8.1a19bff422a.d15ad41fa6deb53f=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

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

Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 include/gnttab_interface=2Eh | 116 +++++++++++++++++++++++++------------
 src/xenvbd=2Einf             |   6 +-
 src/xenvbd/granter=2Ec       |  17 ++++--
 3 files changed, 94 insertions(+), 45 deletions(-)

diff --git a/include/gnttab_interface=2Eh b/include/gnttab_interface=2Eh
index 92a95a7=2E=2E40ea821 100644
--- a/include/gnttab_interface=2Eh
+++ b/include/gnttab_interface=2Eh
@@ -132,7 +132,7 @@ typedef NTSTATUS
     _Outptr_ PXENBUS_GNTTAB_ENTRY   *Entry
     );
=20
-/*! \typedef XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS
+/*! \typedef XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS_V2
     \brief Revoke foreign access and return the \a Entry to the \a Cache
=20
     \param Interface The interface header
@@ -140,9 +140,35 @@ 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
+
+    If the foreign domain is still accessing the granted page, this retri=
es
+    for a while before giving up=2E
 */
 typedef NTSTATUS
-(*XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS)(
+(*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_TRY_REVOKE_FOREIGN_ACCESS
+    \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
+    \return STATUS_DEVICE_BUSY if the foreign domain is still accessing t=
he
+    granted page
+
+    This does not wait for the foreign domain=2E On failure, foreign acce=
ss
+    remains in effect and \a Entry remains valid: the caller must keep th=
e
+    granted page alive, and should retry the revocation later=2E
+*/
+typedef NTSTATUS
+(*XENBUS_GNTTAB_TRY_REVOKE_FOREIGN_ACCESS)(
     _In_ PINTERFACE                 Interface,
     _In_ PXENBUS_GNTTAB_CACHE       Cache,
     _In_ BOOLEAN                    Locked,
@@ -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  GnttabRevokeForeignAccessVers=
ion2;
+    XENBUS_GNTTAB_GET_REFERENCE             GnttabGetReference;
+    XENBUS_GNTTAB_DESTROY_CACHE             GnttabDestroyCache;
+    XENBUS_GNTTAB_MAP_FOREIGN_PAGES         GnttabMapForeignPages;
+    XENBUS_GNTTAB_UNMAP_FOREIGN_PAGES       GnttabUnmapForeignPages;
 };
=20
 /*! \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  GnttabRevokeForeignAccessVers=
ion2;
+    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;
 };
=20
 /*! \struct _XENBUS_GNTTAB_INTERFACE_V4
@@ -274,20 +300,38 @@ 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 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              GnttabCreateCache;
+    XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS     GnttabPermitForeignAccess;
+    XENBUS_GNTTAB_REVOKE_FOREIGN_ACCESS_V2  GnttabRevokeForeignAccessVers=
ion2;
+    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;
+    XENBUS_GNTTAB_CREATE_CACHE              GnttabCreateCache;
+    XENBUS_GNTTAB_PERMIT_FOREIGN_ACCESS     GnttabPermitForeignAccess;
+    XENBUS_GNTTAB_TRY_REVOKE_FOREIGN_ACCESS GnttabTryRevokeForeignAccess;
+    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;
 };
=20
-typedef struct _XENBUS_GNTTAB_INTERFACE_V4 XENBUS_GNTTAB_INTERFACE, *PXEN=
BUS_GNTTAB_INTERFACE;
+typedef struct _XENBUS_GNTTAB_INTERFACE_V5 XENBUS_GNTTAB_INTERFACE, *PXEN=
BUS_GNTTAB_INTERFACE;
=20
 /*! \def XENBUS_GNTTAB
     \brief Macro at assist in method invocation
@@ -298,6 +342,6 @@ typedef struct _XENBUS_GNTTAB_INTERFACE_V4 XENBUS_GNTT=
AB_INTERFACE, *PXENBUS_GNT
 #endif  // _WINDLL
=20
 #define XENBUS_GNTTAB_INTERFACE_VERSION_MIN 2
-#define XENBUS_GNTTAB_INTERFACE_VERSION_MAX 4
+#define XENBUS_GNTTAB_INTERFACE_VERSION_MAX 5
=20
 #endif  // _XENBUS_GNTTAB_INTERFACE_H
diff --git a/src/xenvbd=2Einf b/src/xenvbd=2Einf
index 28405f6=2E=2E055ffdc 100644
--- a/src/xenvbd=2Einf
+++ b/src/xenvbd=2Einf
@@ -54,9 +54,9 @@ xencrsh=2Esys=3D0,,
=20
 [Inst=2ENT@INF_ARCH@]
 %XenVbdName%=3DXenVbd_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
=20
 [XenVbd_Inst]=20
 CopyFiles=3DXenVbd_Copyfiles
diff --git a/src/xenvbd/granter=2Ec b/src/xenvbd/granter=2Ec
index eddcdcf=2E=2Ebacd245 100644
--- a/src/xenvbd/granter=2Ec
+++ b/src/xenvbd/granter=2Ec
@@ -358,12 +358,17 @@ GranterPut(
     if (Granter->Connected =3D=3D FALSE)
         return;
=20
-    status =3D XENBUS_GNTTAB(RevokeForeignAccess,
-                           &Granter->GnttabInterface,
-                           Granter->Cache,
-                           FALSE,
-                           Entry);
-    ASSERT(NT_SUCCESS(status));
+    for (;;) {
+        status =3D XENBUS_GNTTAB(TryRevokeForeignAccess,
+                               &Granter->GnttabInterface,
+                               Granter->Cache,
+                               FALSE,
+                               Entry);
+        if (NT_SUCCESS(status))
+            break;
+
+        YieldProcessor();
+    }
=20
     InterlockedDecrement(&Granter->Current);
 }
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.370.9659bd1b01ced8f8.1a19bff422a.d15ad41fa6deb53f=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:44 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468134.1677183 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7g-0001MO-6S; Mon, 02 Nov 2026 11:22:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468134.1677183; Mon, 02 Nov 2026 11:22:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7f-0001KY-OR; Mon, 02 Nov 2026 11:22:43 +0000
Received: by outflank-mailman (input) for mailman id 1468134;
 Mon, 02 Nov 2026 11:22:42 +0000
Received: from mx.expurgate.net ([195.190.135.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4562000403d@swg.vates.tech>)
 id 1xNq7e-0001JA-4A
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:42 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7d-00AYId-H6
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [10.42.69.6] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4562000403d@swg.vates.tech>)
 id 6ae87281-e002-0a2a0a5209dd-0a2a4506955a-0
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net)
 by tlsNG-16d1c6.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4562000403d@swg.vates.tech>)
 id 6ae87281-195a-0a2a45060019-b9ff1c238849-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff4562000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:40 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id D3AA182F57;
 Mon,  2 Nov 2026 12:22:39 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=hyFWeXp12KGaFQmcbX03ldyTQK1fbahbReir1EPBiLc=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=f6RGUt9W9VgBKNWxvP4AANFKS+Dk7hGZ9mzs1F+QuhOrhsi9454W/pXR2DViRoAZTgjme7w5J
 OXC2alLejN9KFuJolTweFhw7XRof6pJWTJC/TWDu9CBkOEo+tjGRtSBzjv34rxUp4Wxw4GbdSCi
 7ttRn120KjNSs1f6SD6QmxIDXRax7oTE0d8BOdd42fSBVCvZxYMzQ1RAFILipn7lF3+X2QL4sGV
 4XXTdEit5jH6KMZBoHw3zseB5i33y/4MalDS3xO3/XaJXje5nKOZOUCQTqT8a4VU+UBSBg7zd9j
 nOJI7ggRRWsLNOZcdtup68MBHpGYfZV+Nl9EYZ87uK0A==
X-Zone-Loop: 7d4e71cf84d8bab254a78750acdd3c6b8df8a61add33
x-campaign-type: default
x-transaction-id: a570ec0c-ee93-4b4e-9f38-5e3408cf7095
x-swg-uid: 01-34ef2028-67bf-4a3d-bd53-bdfcb08d459d
X-Mailer: Sweego
Message-ID:
 <1793618560.8631fc262581453bbf619ec5b2062170.1a19bff4562000403d@vates.tech>
x-swg-bid: 1793618560.8631fc262581453bbf619ec5b2062170.1a19bff4562000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 05/11] granter: Split GranterTryPut to its own function
Date: Mon,  2 Nov 2026 12:22:26 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.372.87d3244958cd6348.1a19bff43b2.b203cdc7737cd866=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618559922
X-purgate-ID: tlsNG-16d1c6/1793618561-F520877B-28D22FED/0/0
X-purgate-type: clean
X-purgate-size: 2783

---=Part.372.87d3244958cd6348.1a19bff43b2.b203cdc7737cd866=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

This allows ring consumers to test for still-pending grants and
eventually defer grant revocation=2E

Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xenvbd/granter=2Ec | 37 +++++++++++++++++++++++++++++--------
 src/xenvbd/granter=2Eh |  7 +++++++
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/src/xenvbd/granter=2Ec b/src/xenvbd/granter=2Ec
index bacd245=2E=2E8271771 100644
--- a/src/xenvbd/granter=2Ec
+++ b/src/xenvbd/granter=2Ec
@@ -346,31 +346,52 @@ fail1:
     return status;
 }
=20
+_Check_return_
+NTSTATUS
+GranterTryPut(
+    _Inout_ PXENVBD_GRANTER Granter,
+    _In_ PVOID              Handle
+    )
+{
+    PXENBUS_GNTTAB_ENTRY    Entry =3D Handle;
+    NTSTATUS                status;
+
+    ASSERT3P(Granter->Cache, !=3D, NULL);
+
+    status =3D XENBUS_GNTTAB(TryRevokeForeignAccess,
+                           &Granter->GnttabInterface,
+                           Granter->Cache,
+                           FALSE,
+                           Entry);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    InterlockedDecrement(&Granter->Current);
+
+    return STATUS_SUCCESS;
+
+fail1:
+    return status;
+}
+
 VOID
 GranterPut(
     _Inout_ PXENVBD_GRANTER Granter,
     _In_ PVOID              Handle
     )
 {
-    PXENBUS_GNTTAB_ENTRY    Entry =3D Handle;
     NTSTATUS                status;
=20
     if (Granter->Connected =3D=3D FALSE)
         return;
=20
     for (;;) {
-        status =3D XENBUS_GNTTAB(TryRevokeForeignAccess,
-                               &Granter->GnttabInterface,
-                               Granter->Cache,
-                               FALSE,
-                               Entry);
+        status =3D GranterTryPut(Granter, Handle);
         if (NT_SUCCESS(status))
             break;
=20
         YieldProcessor();
     }
-
-    InterlockedDecrement(&Granter->Current);
 }
=20
 ULONG
diff --git a/src/xenvbd/granter=2Eh b/src/xenvbd/granter=2Eh
index e8d0899=2E=2Ee609a8a 100644
--- a/src/xenvbd/granter=2Eh
+++ b/src/xenvbd/granter=2Eh
@@ -84,6 +84,13 @@ GranterGet(
     _Outptr_ PVOID          *Handle
     );
=20
+_Check_return_
+extern NTSTATUS
+GranterTryPut(
+    _Inout_ PXENVBD_GRANTER Granter,
+    _In_ PVOID              Handle
+    );
+
 extern VOID
 GranterPut(
     _Inout_ PXENVBD_GRANTER Granter,
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.372.87d3244958cd6348.1a19bff43b2.b203cdc7737cd866=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:44 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468135.1677186 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7g-0001NB-84; Mon, 02 Nov 2026 11:22:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468135.1677186; Mon, 02 Nov 2026 11:22:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7f-0001M4-QT; Mon, 02 Nov 2026 11:22:43 +0000
Received: by outflank-mailman (input) for mailman id 1468135;
 Mon, 02 Nov 2026 11:22:42 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff46e9000403d@swg.vates.tech>)
 id 1xNq7e-0001JB-4f
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:42 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7d-00GWnJ-Hc
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [10.42.69.11] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff46e9000403d@swg.vates.tech>)
 id 6ae87281-2eae-0a2a0a5409dd-0a2a450b8c68-0
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [185.255.28.18] (helo=prod-mta-13.swg-srv.net)
 by tlsNG-42698a.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff46e9000403d@swg.vates.tech>)
 id 6ae87281-b7e8-0a2a450b0019-b9ff1c12b1f9-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff46e9000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:40 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 4567080D91;
 Mon,  2 Nov 2026 12:22:40 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=oAvUD873/gfbuxfA4fhYPRQJPEM0/1F70W6cjNh4OnY=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=jtm3iXVmbT+f4xuCkALYfUtNhvnyPFSV2aTRkzflEyu32MBQAR5si+JRd1BQNBSze9mfEnIA8
 K5WFyk4y2IpdTzSt2lgbMibJztfRl5R/xdKWWQ+Q2C7ol1wN5oPDKnUaVmkuPRUzxufOlHNdod7
 ovW08SdR8+/T19bOFzknPrAN+t3A49D2YaRITDy4rO8gd+yruojzgG4o5fsOfhzI4318PgO55R5
 w2CPNJa9naZ6FkJf+Lg8xMKJLwgDejgMLzohVDcKFoXxyR9Ry+1/Zp26GCuhnif5zpXrAEZEieJ
 5MzWh8rmndj1vHTNJ6dOTFGI2gG+DFTGUPPm39H0VGsg==
X-Zone-Loop: a8e14713aeeb55ad1df0dfe7ccd4b19d974d3db20256
x-campaign-type: default
x-transaction-id: a6f0687e-d3c4-44d4-8f71-07a01592118c
x-swg-uid: 01-030dec72-e9c9-4f4e-b342-d3f26f98b2eb
X-Mailer: Sweego
Message-ID:
 <1793618560.8631fc262581453bbf619ec5b2062170.1a19bff46e9000403d@vates.tech>
x-swg-bid: 1793618560.8631fc262581453bbf619ec5b2062170.1a19bff46e9000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 07/11] granter: Introduce GranterD0ToD3/D3ToD0
Date: Mon,  2 Nov 2026 12:22:28 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.374.eb71909b4319ffa1.1a19bff4553.4acfac88c3fd915c=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618560339
X-purgate-ID: tlsNG-42698a/1793618561-1BED69EA-CC167312/0/0
X-purgate-type: clean
X-purgate-size: 4771

---=Part.374.eb71909b4319ffa1.1a19bff4553.4acfac88c3fd915c=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

XenBus requires all gnttab references to be dropped before hibernation;
otherwise, FdoS3ToS4 will crash=2E Since the granter cache can now outlive
a disconnect if there are outstanding grants, release it on D0->D3 at
the latest=2E

Nothing defers grant revocation yet, so Current is always zero there for
now=2E

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xenvbd/frontend=2Ec | 11 +++++++++--
 src/xenvbd/frontend=2Eh |  4 ++--
 src/xenvbd/granter=2Ec  | 41 +++++++++++++++++++++++++++++++++--------
 src/xenvbd/granter=2Eh  | 12 ++++++++++++
 4 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/src/xenvbd/frontend=2Ec b/src/xenvbd/frontend=2Ec
index 8bf4f96=2E=2E442e188 100644
--- a/src/xenvbd/frontend=2Ec
+++ b/src/xenvbd/frontend=2Ec
@@ -1669,7 +1669,7 @@ FrontendDebugCallback(
 }
=20
 _Check_return_
-_IRQL_requires_max_(DISPATCH_LEVEL)
+_IRQL_requires_(PASSIVE_LEVEL)
 NTSTATUS
 FrontendD3ToD0(
     _Inout_ PXENVBD_FRONTEND    Frontend
@@ -1679,6 +1679,8 @@ FrontendD3ToD0(
     KIRQL                       Irql;
     NTSTATUS                    status;
=20
+    GranterD3ToD0(Frontend->Granter);
+
     KeAcquireSpinLock(&Frontend->StateLock, &Irql);
=20
     AdapterGetStoreInterface(Adapter, &Frontend->StoreInterface);
@@ -1746,10 +1748,13 @@ fail1:
                   sizeof(XENBUS_STORE_INTERFACE));
=20
     KeReleaseSpinLock(&Frontend->StateLock, Irql);
+
+    GranterD0ToD3(Frontend->Granter);
+
     return status;
 }
=20
-_IRQL_requires_max_(DISPATCH_LEVEL)
+_IRQL_requires_(PASSIVE_LEVEL)
 VOID
 FrontendD0ToD3(
     _Inout_ PXENVBD_FRONTEND    Frontend
@@ -1787,6 +1792,8 @@ FrontendD0ToD3(
                   sizeof(XENBUS_STORE_INTERFACE));
=20
     KeReleaseSpinLock(&Frontend->StateLock, Irql);
+
+    GranterD0ToD3(Frontend->Granter);
 }
=20
 _Check_return_
diff --git a/src/xenvbd/frontend=2Eh b/src/xenvbd/frontend=2Eh
index 8b0ad8c=2E=2E3b43950 100644
--- a/src/xenvbd/frontend=2Eh
+++ b/src/xenvbd/frontend=2Eh
@@ -116,13 +116,13 @@ FrontendSetDeviceUsage(
     );
=20
 _Check_return_
-_IRQL_requires_max_(DISPATCH_LEVEL)
+_IRQL_requires_(PASSIVE_LEVEL)
 extern NTSTATUS
 FrontendD3ToD0(
     _Inout_ PXENVBD_FRONTEND    Frontend
     );
=20
-_IRQL_requires_max_(DISPATCH_LEVEL)
+_IRQL_requires_(PASSIVE_LEVEL)
 extern VOID
 FrontendD0ToD3(
     _Inout_ PXENVBD_FRONTEND    Frontend
diff --git a/src/xenvbd/granter=2Ec b/src/xenvbd/granter=2Ec
index 6adc578=2E=2E7b7a7c8 100644
--- a/src/xenvbd/granter=2Ec
+++ b/src/xenvbd/granter=2Ec
@@ -111,14 +111,7 @@ GranterDestroy(
     )
 {
     BUG_ON(Granter->Current !=3D 0);
-
-    if (Granter->Cache !=3D NULL) {
-        KIRQL   Irql;
-
-        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
-        __GranterDestroyCache(Granter);
-        KeLowerIrql(Irql);
-    }
+    ASSERT3P(Granter->Cache, =3D=3D, NULL);
=20
     Granter->Frontend =3D NULL;
     RtlZeroMemory(&Granter->Lock, sizeof(KSPIN_LOCK));
@@ -367,6 +360,38 @@ GranterDisconnect(
     __GranterDestroyCache(Granter);
 }
=20
+_IRQL_requires_(PASSIVE_LEVEL)
+VOID
+GranterD3ToD0(
+    _Inout_ PXENVBD_GRANTER Granter
+    )
+{
+    ASSERT3P(Granter->Cache, =3D=3D, NULL);
+    ASSERT3S(Granter->Current, =3D=3D, 0);
+}
+
+_IRQL_requires_(PASSIVE_LEVEL)
+VOID
+GranterD0ToD3(
+    _Inout_ PXENVBD_GRANTER Granter
+    )
+{
+    KIRQL                   Irql;
+
+    ASSERT(!Granter->Connected);
+
+    // All grants must be revoked before transitioning to S3=2E
+
+    BUG_ON(Granter->Current !=3D 0);
+
+    if (Granter->Cache =3D=3D NULL)
+        return;
+
+    KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+    __GranterDestroyCache(Granter);
+    KeLowerIrql(Irql);
+}
+
 NTSTATUS
 GranterGet(
     _Inout_ PXENVBD_GRANTER Granter,
diff --git a/src/xenvbd/granter=2Eh b/src/xenvbd/granter=2Eh
index e609a8a=2E=2E93b962c 100644
--- a/src/xenvbd/granter=2Eh
+++ b/src/xenvbd/granter=2Eh
@@ -50,6 +50,18 @@ GranterDestroy(
     _Inout_ PXENVBD_GRANTER Granter
     );
=20
+_IRQL_requires_(PASSIVE_LEVEL)
+extern VOID
+GranterD3ToD0(
+    _Inout_ PXENVBD_GRANTER Granter
+    );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+extern VOID
+GranterD0ToD3(
+    _Inout_ PXENVBD_GRANTER Granter
+    );
+
 extern NTSTATUS
 GranterConnect(
     _Inout_ PXENVBD_GRANTER Granter
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.374.eb71909b4319ffa1.1a19bff4553.4acfac88c3fd915c=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:44 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468137.1677195 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7g-0001PK-IF; Mon, 02 Nov 2026 11:22:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468137.1677195; Mon, 02 Nov 2026 11:22:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7g-0001OA-2n; Mon, 02 Nov 2026 11:22:44 +0000
Received: by outflank-mailman (input) for mailman id 1468137;
 Mon, 02 Nov 2026 11:22:42 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff47d2000403d@swg.vates.tech>)
 id 1xNq7e-0001JO-HQ
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:42 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7d-00GWnJ-UN
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [10.42.69.11] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff47d2000403d@swg.vates.tech>)
 id 6ae87281-2eae-0a2a0a5409dd-0a2a450b8c68-2
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net)
 by tlsNG-42698a.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff47d2000403d@swg.vates.tech>)
 id 6ae87281-b7e8-0a2a450b0019-b9ff1c228187-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff47d2000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:40 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 75BA981E0A;
 Mon,  2 Nov 2026 12:22:40 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=zWRjNJTSgiq7D8o0Ia1xYRSuD4KFvgxDuyym+NpdpiQ=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=YKxPxV7qBK69B2HWFK0ynaqyUmkSQVenJx9gmGBkXQqtddjmCXZNYh3MHGQ0JeWP/A6z+V7I8
 eR3xfNytAc3zT9xjVPWt2to8Jnp/No6Ehn7VxjRJn2bSHssukuFbs3RpCf7ZuUlacgRbG/7cx5c
 4LgpNAW6E525qKGhbWUZOECBqO+LvUg7ItpAhxktRWxAVrKArpnPVi5G44wvbme+WmC/3c27yMs
 GIbh4jI1CIROvqc/230BUCLeKDscGRC3UIrS1SdMaiiom4/lwsYc+WDrOE29ylFK9xpaw3haV1O
 QQ8tEdpq1vvHabgquF1rvv0iTfKYIoK/qRYlXyUzrCIg==
X-Zone-Loop: 398cb971106e4cd780ca96414b680635f4a63f2e35cf
x-campaign-type: default
x-transaction-id: 3548c78f-f63e-4a97-9dfe-2727f7e63341
x-swg-uid: 01-d966ec19-725c-4032-90c8-4d6e45abd8fd
X-Mailer: Sweego
Message-ID:
 <1793618561.8631fc262581453bbf619ec5b2062170.1a19bff47d2000403d@vates.tech>
x-swg-bid: 1793618561.8631fc262581453bbf619ec5b2062170.1a19bff47d2000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 08/11] ring: Introduce RingD3ToD0/RingD0ToD3
Date: Mon,  2 Nov 2026 12:22:29 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.375.9bad41807b2726df.1a19bff4618.5f1e287385e6b853=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618560537
X-purgate-ID: tlsNG-42698a/1793618561-19AC09EA-DA24F4E8/0/0
X-purgate-type: clean
X-purgate-size: 5190

---=Part.375.9bad41807b2726df.1a19bff4618.5f1e287385e6b853=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Add D0 power transition hooks to the ring, called by the frontend at
PASSIVE_LEVEL outside of its state lock, so that the ring can manage
resources that must only exist while in D0=2E

They do nothing yet=2E

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xenvbd/frontend=2Ec | 34 ++++++++++++++++++++++------------
 src/xenvbd/ring=2Ec     | 25 +++++++++++++++++++++++++
 src/xenvbd/ring=2Eh     | 13 +++++++++++++
 3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/src/xenvbd/frontend=2Ec b/src/xenvbd/frontend=2Ec
index 442e188=2E=2E20207ba 100644
--- a/src/xenvbd/frontend=2Ec
+++ b/src/xenvbd/frontend=2Ec
@@ -1681,6 +1681,10 @@ FrontendD3ToD0(
=20
     GranterD3ToD0(Frontend->Granter);
=20
+    status =3D RingD3ToD0(Frontend->Ring);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     KeAcquireSpinLock(&Frontend->StateLock, &Irql);
=20
     AdapterGetStoreInterface(Adapter, &Frontend->StoreInterface);
@@ -1689,15 +1693,15 @@ FrontendD3ToD0(
=20
     status =3D XENBUS_STORE(Acquire, &Frontend->StoreInterface);
     if (!NT_SUCCESS(status))
-        goto fail1;
+        goto fail2;
=20
     status =3D XENBUS_DEBUG(Acquire, &Frontend->DebugInterface);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail3;
=20
     status =3D XENBUS_SUSPEND(Acquire, &Frontend->SuspendInterface);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail4;
=20
     status =3D XENBUS_SUSPEND(Register,
                             &Frontend->SuspendInterface,
@@ -1706,7 +1710,7 @@ FrontendD3ToD0(
                             Frontend,
                             &Frontend->SuspendCallback);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail5;
=20
     status =3D XENBUS_DEBUG(Register,
                           &Frontend->DebugInterface,
@@ -1715,30 +1719,30 @@ FrontendD3ToD0(
                           Frontend,
                           &Frontend->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail6;
=20
     Frontend->Active =3D TRUE;
=20
     KeReleaseSpinLock(&Frontend->StateLock, Irql);
     return STATUS_SUCCESS;
=20
-fail5:
-    Error("fail5\n");
+fail6:
+    Error("fail6\n");
     XENBUS_SUSPEND(Deregister,
                    &Frontend->SuspendInterface,
                    Frontend->SuspendCallback);
     Frontend->SuspendCallback =3D NULL;
+fail5:
+    Error("fail5\n");
+    XENBUS_SUSPEND(Release, &Frontend->SuspendInterface);
 fail4:
     Error("fail4\n");
-    XENBUS_SUSPEND(Release, &Frontend->SuspendInterface);
+    XENBUS_DEBUG(Release, &Frontend->DebugInterface);
 fail3:
     Error("fail3\n");
-    XENBUS_DEBUG(Release, &Frontend->DebugInterface);
+    XENBUS_STORE(Release, &Frontend->StoreInterface);
 fail2:
     Error("fail2\n");
-    XENBUS_STORE(Release, &Frontend->StoreInterface);
-fail1:
-    Error("fail1 (%08x)\n", status);
=20
     RtlZeroMemory(&Frontend->SuspendInterface,
                   sizeof(XENBUS_SUSPEND_INTERFACE));
@@ -1749,6 +1753,11 @@ fail1:
=20
     KeReleaseSpinLock(&Frontend->StateLock, Irql);
=20
+    RingD0ToD3(Frontend->Ring);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
     GranterD0ToD3(Frontend->Granter);
=20
     return status;
@@ -1793,6 +1802,7 @@ FrontendD0ToD3(
=20
     KeReleaseSpinLock(&Frontend->StateLock, Irql);
=20
+    RingD0ToD3(Frontend->Ring);
     GranterD0ToD3(Frontend->Granter);
 }
=20
diff --git a/src/xenvbd/ring=2Ec b/src/xenvbd/ring=2Ec
index 5ef62c9=2E=2E341ce52 100644
--- a/src/xenvbd/ring=2Ec
+++ b/src/xenvbd/ring=2Ec
@@ -2595,6 +2595,31 @@ RingDestroy(
     __RingFree(Ring);
 }
=20
+_Check_return_
+_IRQL_requires_(PASSIVE_LEVEL)
+NTSTATUS
+RingD3ToD0(
+    _Inout_ PXENVBD_RING    Ring
+    )
+{
+    UNREFERENCED_PARAMETER(Ring);
+
+    ASSERT3U(KeGetCurrentIrql(), =3D=3D, PASSIVE_LEVEL);
+
+    return STATUS_SUCCESS;
+}
+
+_IRQL_requires_(PASSIVE_LEVEL)
+VOID
+RingD0ToD3(
+    _Inout_ PXENVBD_RING    Ring
+    )
+{
+    UNREFERENCED_PARAMETER(Ring);
+
+    ASSERT3U(KeGetCurrentIrql(), =3D=3D, PASSIVE_LEVEL);
+}
+
 NTSTATUS
 RingConnect(
     _Inout_ PXENVBD_RING    Ring
diff --git a/src/xenvbd/ring=2Eh b/src/xenvbd/ring=2Eh
index 6dfdb74=2E=2Ebd5f322 100644
--- a/src/xenvbd/ring=2Eh
+++ b/src/xenvbd/ring=2Eh
@@ -49,6 +49,19 @@ RingDestroy(
     _Inout_ PXENVBD_RING    Ring
     );
=20
+_Check_return_
+_IRQL_requires_(PASSIVE_LEVEL)
+extern NTSTATUS
+RingD3ToD0(
+    _Inout_ PXENVBD_RING    Ring
+    );
+
+_IRQL_requires_(PASSIVE_LEVEL)
+extern VOID
+RingD0ToD3(
+    _Inout_ PXENVBD_RING    Ring
+    );
+
 extern NTSTATUS
 RingConnect(
     _Inout_ PXENVBD_RING    Ring
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.375.9bad41807b2726df.1a19bff4618.5f1e287385e6b853=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:44 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468136.1677192 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7g-0001O8-GG; Mon, 02 Nov 2026 11:22:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468136.1677192; Mon, 02 Nov 2026 11:22:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7f-0001NR-V3; Mon, 02 Nov 2026 11:22:43 +0000
Received: by outflank-mailman (input) for mailman id 1468136;
 Mon, 02 Nov 2026 11:22:42 +0000
Received: from mx.expurgate.net ([195.190.135.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff48c2000403d@swg.vates.tech>)
 id 1xNq7e-0001JI-D4
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:42 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7d-00AYId-Q8
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [10.42.69.12] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff48c2000403d@swg.vates.tech>)
 id 6ae8727a-e002-0a2a0a5209dd-0a2a450ce2d2-32
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net)
 by tlsNG-d25034.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff48c2000403d@swg.vates.tech>)
 id 6ae87280-f479-0a2a450c0019-b9ff1c22805f-4
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff48c2000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:41 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id A7F4F82F6F;
 Mon,  2 Nov 2026 12:22:40 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=UVp1vTbXEczF625upFnC4eKt3pj0Nvz0t+p4bY13X9o=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=XKIyP8z+voHP1AUdpf0Et59dYq+W1hboQ4wISyY6yTcMVULEpRiYTjn16brJEoZainomkGFGU
 J/YQEpy0sIHn/taS62akTdlbkfJV6w3nrPWXUAgt+vuedcCDDJiTsFR+uhUmltAkEEeIdjtPWvG
 uVdKzyubFRPE9v+DU6MTK0hdtsB+XgQ6YbY7jq53nODgJhdhVbbYeGDrZvlY7AGaxjb4J5MmJOp
 6xn+dfKekfVqIKV1rVZeV4mWAOVjrQPEBBfI0XcTsuV3eZWlvcdBL3Y1/nZFZuwoLInRlWycvWR
 sH7Xe8U5O2M2AWU/W9sbfH7A5pwsTT+Lo0dF2BrvqHMQ==
X-Zone-Loop: 3443e33e10fe480a83d7bf589c2fddab0ed1cc782208
x-campaign-type: default
x-transaction-id: 7f527e9e-a29e-46d5-907d-e8eb81005855
x-swg-uid: 01-e7a725ca-7ab3-41cd-b395-c0a36647f561
X-Mailer: Sweego
Message-ID:
 <1793618561.8631fc262581453bbf619ec5b2062170.1a19bff48c2000403d@vates.tech>
x-swg-bid: 1793618561.8631fc262581453bbf619ec5b2062170.1a19bff48c2000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 09/11] ring: Defer destruction until backend grant release
Date: Mon,  2 Nov 2026 12:22:30 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.376.7abedc14eae6d017.1a19bff46fd.b78faef2481a8d7=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618560765
X-purgate-ID: tlsNG-d25034/1793618561-00CCBA5B-AA34760E/0/0
X-purgate-type: clean
X-purgate-size: 17866

---=Part.376.7abedc14eae6d017.1a19bff46fd.b78faef2481a8d7=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

If the backend is still accessing the ring page grants, we must defer
ring destruction until the backend has fully released them=2E

Implement a reclaim thread that polls for grant revocation=2E If grant
revocation ever fails, the reclaim thread will take care of polling for
grant release=2E Wait for a reclaim when transitioning to D3=2E

The reclaim thread lives from RingCreate to RingDestroy, not just while
in D0=2E This is because exiting a thread can cause a page fault that
reads kernel code from the boot disk=2E In D0->D3, the boot disk is
already disconnected at that point, so the read never completes and
shutdown hangs=2E (Note that RingDestroy is not called during shutdown)

We must use a while loop in RingD0ToD3=2E Otherwise, this sequence can
occur:
* The reclaim thread wakes and finds nothing deferred on queue 0=2E
* D0->D3 disconnects queue 0=2E The backend still maps a ring page, so the
  driver defers the pages=2E
* RingD0ToD3 sees queue 0 deferring=2E It clears ReclaimEvent and waits=2E
* The reclaim thread finishes its pass and sets ReclaimEvent=2E Its
  result is old: it checked queue 0 before the deferral=2E
* RingD0ToD3 returns=2E The backend still holds queue 0's grants=2E

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
v3: Release as many grants as possible before deferring=2E Put some checks
under #ifdef=2E
---
 src/xenvbd/ring=2Ec | 348 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 313 insertions(+), 35 deletions(-)

diff --git a/src/xenvbd/ring=2Ec b/src/xenvbd/ring=2Ec
index 341ce52=2E=2Eb41c9c3 100644
--- a/src/xenvbd/ring=2Ec
+++ b/src/xenvbd/ring=2Ec
@@ -57,6 +57,14 @@
 #define XENVBD_MAX_RING_PAGE_ORDER  (4)
 #define XENVBD_MAX_RING_PAGES       (1 << XENVBD_MAX_RING_PAGE_ORDER)

+// Separate struct to be transferred to ReclaimThread on ring page reclai=
m=2E
+typedef struct _XENVBD_BLKIF_PAGES {
+    LIST_ENTRY                      ListEntry;
+    PMDL                            Mdl;
+    ULONG                           Count;
+    PXENBUS_GNTTAB_ENTRY            Grants[XENVBD_MAX_RING_PAGES];
+} XENVBD_BLKIF_PAGES, *PXENVBD_BLKIF_PAGES;
+
 typedef struct _XENVBD_BLKIF_RING {
     PXENVBD_RING                    Ring;
     ULONG                           Index;
@@ -64,10 +72,9 @@ typedef struct _XENVBD_BLKIF_RING {
     PXENBUS_CACHE                   RequestCache;
     PXENBUS_CACHE                   SegmentCache;
     PXENBUS_CACHE                   IndirectCache;
-    PMDL                            Mdl;
+    PXENVBD_BLKIF_PAGES             Pages;
     blkif_sring_t                   *Shared;
     blkif_front_ring_t              Front;
-    PXENBUS_GNTTAB_ENTRY            Grants[XENVBD_MAX_RING_PAGES];
     PXENBUS_EVTCHN_CHANNEL          Channel;
     KDPC                            Dpc;
     ULONG                           Dpcs;
@@ -84,6 +91,8 @@ typedef struct _XENVBD_BLKIF_RING {
     LIST_ENTRY                      PreparedQueue;
     LIST_ENTRY                      SubmittedList;
     LIST_ENTRY                      ShutdownQueue;
+    // List of XENVBD_BLKIF_PAGES still being held by the backend
+    LIST_ENTRY                      DeferredPages;
     ULONG                           SrbsQueued;
     ULONG                           SrbsCompleted;
     ULONG                           SrbsFailed;
@@ -119,6 +128,8 @@ struct _XENVBD_RING {
     PXENBUS_DEBUG_CALLBACK          DebugCallback;
     ULONG                           Order;
     PXENVBD_BLKIF_RING              *Ring;
+    PXENVBD_THREAD                  ReclaimThread;
+    KEVENT                          ReclaimEvent;
     LONG                            Stats[XENVBD_STAT__MAX];
 };

@@ -1754,6 +1765,239 @@ RingWatchdog(
     return STATUS_SUCCESS;
 }

+static PXENVBD_BLKIF_PAGES
+BlkifRingAllocatePages(
+    _In_ ULONG          Count
+    )
+{
+    PXENVBD_BLKIF_PAGES Pages;
+
+    ASSERT3U(Count, <=3D, XENVBD_MAX_RING_PAGES);
+
+    Pages =3D __RingAllocate(sizeof(XENVBD_BLKIF_PAGES));
+    if (Pages =3D=3D NULL)
+        goto fail1;
+
+    Pages->Mdl =3D __AllocatePages(Count, FALSE);
+    if (Pages->Mdl =3D=3D NULL)
+        goto fail2;
+
+    Pages->Count =3D Count;
+
+    return Pages;
+
+fail2:
+    __RingFree(Pages);
+
+fail1:
+    return NULL;
+}
+
+static VOID
+__BlkifRingFreePages(
+    _In_ PXENVBD_BLKIF_PAGES    Pages
+    )
+{
+#if DBG
+    ULONG                       Index;
+
+    for (Index =3D 0; Index < Pages->Count; ++Index)
+        ASSERT3P(Pages->Grants[Index], =3D=3D, NULL);
+#endif
+
+    __FreePages(Pages->Mdl);
+    Pages->Mdl =3D NULL;
+    Pages->Count =3D 0;
+
+    RtlZeroMemory(&Pages->ListEntry, sizeof(LIST_ENTRY));
+
+    ASSERT(IsZeroMemory(Pages, sizeof(XENVBD_BLKIF_PAGES)));
+    __RingFree(Pages);
+}
+
+_Check_return_
+static BOOLEAN
+__BlkifRingRevokePages(
+    _In_ PXENVBD_BLKIF_RING     BlkifRing,
+    _Inout_ PXENVBD_BLKIF_PAGES Pages
+    )
+{
+    PXENVBD_RING                Ring =3D BlkifRing->Ring;
+    PXENVBD_GRANTER             Granter =3D FrontendGetGranter(Ring->Fron=
tend);
+    ULONG                       Index;
+    BOOLEAN                     Revoked =3D TRUE;
+
+    for (Index =3D 0; Index < Pages->Count; ++Index) {
+        if (Pages->Grants[Index] =3D=3D NULL)
+            continue;
+
+        if (NT_SUCCESS(GranterTryPut(Granter, Pages->Grants[Index])))
+            Pages->Grants[Index] =3D NULL;
+        else
+            Revoked =3D FALSE;
+    }
+
+    return Revoked;
+}
+
+_IRQL_requires_(DISPATCH_LEVEL)
+static VOID
+BlkifRingReleasePages(
+    _Inout_ PXENVBD_BLKIF_RING  BlkifRing
+    )
+{
+    PXENVBD_RING                Ring =3D BlkifRing->Ring;
+    PXENVBD_BLKIF_PAGES         Pages =3D BlkifRing->Pages;
+
+    BlkifRing->Shared =3D NULL;
+    BlkifRing->Pages =3D NULL;
+
+    if (__BlkifRingRevokePages(BlkifRing, Pages)) {
+        __BlkifRingFreePages(Pages);
+        return;
+    }
+
+    Warning("Target[%u][%u] : deferring ring pages\n",
+            FrontendGetTargetId(Ring->Frontend),
+            BlkifRing->Index);
+
+    __BlkifRingAcquireLock(BlkifRing);
+    InsertTailList(&BlkifRing->DeferredPages, &Pages->ListEntry);
+    __BlkifRingReleaseLock(BlkifRing);
+
+    ThreadWake(Ring->ReclaimThread);
+}
+
+static FORCEINLINE BOOLEAN
+__BlkifRingIsDeferring(
+    _In_ PXENVBD_BLKIF_RING BlkifRing
+    )
+{
+    return !IsListEmpty(&BlkifRing->DeferredPages);
+}
+
+_IRQL_requires_(DISPATCH_LEVEL)
+static VOID
+BlkifRingReclaim(
+    _Inout_ PXENVBD_BLKIF_RING  BlkifRing
+    )
+{
+#if DBG
+    ASSERT3P(BlkifRing->LockThread, =3D=3D, KeGetCurrentThread());
+#endif
+
+    while (!IsListEmpty(&BlkifRing->DeferredPages)) {
+        PLIST_ENTRY         ListEntry;
+        PXENVBD_BLKIF_PAGES Pages;
+
+        ListEntry =3D RemoveHeadList(&BlkifRing->DeferredPages);
+        Pages =3D CONTAINING_RECORD(ListEntry, XENVBD_BLKIF_PAGES, ListEn=
try);
+
+        if (!__BlkifRingRevokePages(BlkifRing, Pages)) {
+            // Move this reclaim failure to the back so that entries behi=
nd it
+            // are tried first on the next pass=2E
+            InsertTailList(&BlkifRing->DeferredPages, ListEntry);
+            break;
+        }
+
+        __BlkifRingFreePages(Pages);
+    }
+}
+
+#define XENVBD_RECLAIM_PERIOD           TIME_MS(1000)
+
+static NTSTATUS
+RingReclaim(
+    _In_ PXENVBD_THREAD Self,
+    _In_ PVOID          Context
+    )
+{
+    PXENVBD_RING        Ring =3D Context;
+    LARGE_INTEGER       Timeout;
+    BOOLEAN             Deferring;
+
+    Trace("=3D=3D=3D=3D>\n");
+
+    Timeout=2EQuadPart =3D TIME_RELATIVE(XENVBD_RECLAIM_PERIOD);
+    Deferring =3D FALSE;
+
+    for (;;) {
+        PKEVENT Event;
+        ULONG   Index;
+        KIRQL   Irql;
+
+        Event =3D ThreadGetEvent(Self);
+
+        (VOID) KeWaitForSingleObject(Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     Deferring ? &Timeout : NULL);
+        KeClearEvent(Event);
+
+        if (ThreadIsAlerted(Self))
+            break;
+
+        Deferring =3D FALSE;
+
+        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+
+        for (Index =3D 0; Index < FrontendGetMaxQueues(Ring->Frontend); +=
+Index) {
+            PXENVBD_BLKIF_RING  BlkifRing =3D Ring->Ring[Index];
+
+            __BlkifRingAcquireLock(BlkifRing);
+
+            BlkifRingReclaim(BlkifRing);
+
+            if (__BlkifRingIsDeferring(BlkifRing))
+                Deferring =3D TRUE;
+
+            __BlkifRingReleaseLock(BlkifRing);
+        }
+
+        KeLowerIrql(Irql);
+
+        if (!Deferring)
+            KeSetEvent(&Ring->ReclaimEvent, IO_NO_INCREMENT, FALSE);
+    }
+
+    KeSetEvent(&Ring->ReclaimEvent, IO_NO_INCREMENT, FALSE);
+
+    Trace("<=3D=3D=3D=3D\n");
+
+    return STATUS_SUCCESS;
+}
+
+_IRQL_requires_(PASSIVE_LEVEL)
+static BOOLEAN
+RingIsDeferring(
+    _In_ PXENVBD_RING   Ring
+    )
+{
+    ULONG               Index;
+    KIRQL               Irql;
+    BOOLEAN             Deferring;
+
+    Deferring =3D FALSE;
+
+    KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+
+    for (Index =3D 0; Index < FrontendGetMaxQueues(Ring->Frontend); ++Ind=
ex) {
+        PXENVBD_BLKIF_RING  BlkifRing =3D Ring->Ring[Index];
+
+        __BlkifRingAcquireLock(BlkifRing);
+
+        if (__BlkifRingIsDeferring(BlkifRing))
+            Deferring =3D TRUE;
+
+        __BlkifRingReleaseLock(BlkifRing);
+    }
+
+    KeLowerIrql(Irql);
+
+    return Deferring;
+}
+
 static FORCEINLINE NTSTATUS
 BlkifRingCacheCreate(
     _Inout_ PXENVBD_BLKIF_RING  BlkifRing
@@ -1940,6 +2184,7 @@ BlkifRingCreate(
     InitializeListHead(&(*BlkifRing)->ShutdownQueue);
     InitializeListHead(&(*BlkifRing)->SubmittedList);
     InitializeListHead(&(*BlkifRing)->PreparedQueue);
+    InitializeListHead(&(*BlkifRing)->DeferredPages);

     KeInitializeThreadedDpc(&(*BlkifRing)->Dpc, BlkifRingDpc, *BlkifRing)=
;

@@ -1956,6 +2201,7 @@ fail4:

     RtlZeroMemory(&(*BlkifRing)->Dpc, sizeof(KDPC));

+    RtlZeroMemory(&(*BlkifRing)->DeferredPages, sizeof(LIST_ENTRY));
     RtlZeroMemory(&(*BlkifRing)->PreparedQueue, sizeof(LIST_ENTRY));
     RtlZeroMemory(&(*BlkifRing)->SubmittedList, sizeof(LIST_ENTRY));
     RtlZeroMemory(&(*BlkifRing)->ShutdownQueue, sizeof(LIST_ENTRY));
@@ -1988,8 +2234,12 @@ BlkifRingDestroy(
     ThreadJoin(BlkifRing->WatchdogThread);
     BlkifRing->WatchdogThread =3D NULL;

+    BUG_ON(__BlkifRingIsDeferring(BlkifRing));
+
     RtlZeroMemory(&BlkifRing->Dpc, sizeof(KDPC));

+    RtlZeroMemory(&BlkifRing->DeferredPages, sizeof(LIST_ENTRY));
+
     ASSERT(IsListEmpty(&BlkifRing->PreparedQueue));
     RtlZeroMemory(&BlkifRing->PreparedQueue, sizeof(LIST_ENTRY));

@@ -2045,13 +2295,13 @@ BlkifRingConnect(
     if (!NT_SUCCESS(status))
         goto fail1;

-    BlkifRing->Mdl =3D __AllocatePages(1 << Ring->Order, FALSE);
+    BlkifRing->Pages =3D BlkifRingAllocatePages(1ul << Ring->Order);

     status =3D STATUS_NO_MEMORY;
-    if (BlkifRing->Mdl =3D=3D NULL)
+    if (BlkifRing->Pages =3D=3D NULL)
         goto fail2;

-    BlkifRing->Shared =3D MmGetSystemAddressForMdlSafe(BlkifRing->Mdl,
+    BlkifRing->Shared =3D MmGetSystemAddressForMdlSafe(BlkifRing->Pages->=
Mdl,
                                                      NormalPagePriority);
     ASSERT(BlkifRing->Shared !=3D NULL);

@@ -2062,11 +2312,11 @@ BlkifRingConnect(
     FRONT_RING_INIT(&BlkifRing->Front, BlkifRing->Shared, PAGE_SIZE << Ri=
ng->Order);
 #pragma warning(pop)

-    for (Index =3D 0; Index < (1ul << Ring->Order); ++Index) {
+    for (Index =3D 0; Index < BlkifRing->Pages->Count; ++Index) {
         status =3D GranterGet(Granter,
-                            MmGetMdlPfnArray(BlkifRing->Mdl)[Index],
+                            MmGetMdlPfnArray(BlkifRing->Pages->Mdl)[Index=
],
                             FALSE,
-                            &BlkifRing->Grants[Index]);
+                            &BlkifRing->Pages->Grants[Index]);
         if (!NT_SUCCESS(status))
             goto fail3;
     }
@@ -2121,19 +2371,9 @@ fail4:
     Error("fail4\n");
 fail3:
     Error("fail3\n");
-    for (Index =3D 0; Index < (1ul << Ring->Order); ++Index) {
-        if (BlkifRing->Grants[Index] =3D=3D NULL)
-            continue;
-
-        GranterPut(Granter, BlkifRing->Grants[Index]);
-        BlkifRing->Grants[Index] =3D NULL;
-    }
-
     RtlZeroMemory(&BlkifRing->Front, sizeof(blkif_front_ring_t));

-    __FreePages(BlkifRing->Mdl);
-    BlkifRing->Shared =3D NULL;
-    BlkifRing->Mdl =3D NULL;
+    BlkifRingReleasePages(BlkifRing);
 fail2:
     Error("fail2\n");
     BlkifRingCacheDestroy(BlkifRing);
@@ -2177,13 +2417,13 @@ BlkifRingStoreWrite(
                               Path,
                               "ring-ref",
                               "%u",
-                              GranterReference(Granter, BlkifRing->Grants=
[0]));
+                              GranterReference(Granter, BlkifRing->Pages-=
>Grants[0]));
         if (!NT_SUCCESS(status))
             goto fail2;
     } else {
         ULONG           Index;

-        for (Index =3D 0; Index < (1ul << Ring->Order); ++Index) {
+        for (Index =3D 0; Index < BlkifRing->Pages->Count; ++Index) {
             CHAR        Name[MAX_NAME_LEN + 1];

             status =3D RtlStringCchPrintfA(Name,
@@ -2199,7 +2439,7 @@ BlkifRingStoreWrite(
                                   Path,
                                   Name,
                                   "%u",
-                                  GranterReference(Granter, BlkifRing->Gr=
ants[Index]));
+                                  GranterReference(Granter, BlkifRing->Pa=
ges->Grants[Index]));
             if (!NT_SUCCESS(status))
                 goto fail4;
         }
@@ -2331,8 +2571,6 @@ BlkifRingDisconnect(
     )
 {
     PXENVBD_RING                Ring =3D BlkifRing->Ring;
-    PXENVBD_GRANTER             Granter =3D FrontendGetGranter(Ring->Fron=
tend);
-    ULONG                       Index;

     Trace("=3D=3D=3D=3D> %u\n", BlkifRing->Index);
     ASSERT(BlkifRing->Connected);
@@ -2347,19 +2585,15 @@ BlkifRingDisconnect(
                   BlkifRing->Channel);
     BlkifRing->Channel =3D NULL;

-    for (Index =3D 0; Index < (1ul << Ring->Order); ++Index) {
-        if (BlkifRing->Grants[Index] =3D=3D NULL)
-            continue;
-
-        GranterPut(Granter, BlkifRing->Grants[Index]);
-        BlkifRing->Grants[Index] =3D NULL;
-    }
+    // Normally the backend has closed by now, so ring pages left over fr=
om
+    // earlier connections should be revocable
+    __BlkifRingAcquireLock(BlkifRing);
+    BlkifRingReclaim(BlkifRing);
+    __BlkifRingReleaseLock(BlkifRing);

     RtlZeroMemory(&BlkifRing->Front, sizeof(blkif_front_ring_t));

-    __FreePages(BlkifRing->Mdl);
-    BlkifRing->Shared =3D NULL;
-    BlkifRing->Mdl =3D NULL;
+    BlkifRingReleasePages(BlkifRing);

     BlkifRingCacheDestroy(BlkifRing);

@@ -2514,8 +2748,21 @@ RingCreate(
         Index++;
     }

+    KeInitializeEvent(&(*Ring)->ReclaimEvent, NotificationEvent, FALSE);
+
+    status =3D ThreadCreate(RingReclaim,
+                          *Ring,
+                          &(*Ring)->ReclaimThread);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
     return STATUS_SUCCESS;

+fail4:
+    Error("fail4\n");
+
+    RtlZeroMemory(&(*Ring)->ReclaimEvent, sizeof(KEVENT));
+
 fail3:
     Error("fail3\n");

@@ -2561,6 +2808,12 @@ RingDestroy(
 {
     LONG                    Index;

+    ThreadAlert(Ring->ReclaimThread);
+    ThreadJoin(Ring->ReclaimThread);
+    Ring->ReclaimThread =3D NULL;
+
+    RtlZeroMemory(&Ring->ReclaimEvent, sizeof(KEVENT));
+
     Index =3D (LONG) FrontendGetMaxQueues(Ring->Frontend);
     ASSERT3U(Index, !=3D, 0);

@@ -2615,9 +2868,34 @@ RingD0ToD3(
     _Inout_ PXENVBD_RING    Ring
     )
 {
-    UNREFERENCED_PARAMETER(Ring);
+    ULONG                   Index;

     ASSERT3U(KeGetCurrentIrql(), =3D=3D, PASSIVE_LEVEL);
+
+#if DBG
+    // Grants are only handed over to the reclaim thread at disconnect, s=
o a
+    // ring still connected here would never be drained
+    for (Index =3D 0; Index < FrontendGetMaxQueues(Ring->Frontend); ++Ind=
ex)
+        ASSERT(!Ring->Ring[Index]->Connected);
+#endif
+
+    // Only return once the backend has released everything, so that no g=
rant
+    // survives into D3=2E Freeing pages that backends may still access i=
s worse
+    // than holding up D0->D3=2E
+    while (RingIsDeferring(Ring)) {
+        Trace("waiting for reclaim thread=2E=2E=2E\n");
+
+        KeClearEvent(&Ring->ReclaimEvent);
+        ThreadWake(Ring->ReclaimThread);
+
+        (VOID) KeWaitForSingleObject(&Ring->ReclaimEvent,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+
+        Trace("done\n");
+    }
 }

 NTSTATUS
--
2=2E56=2E0=2Ewindows=2E4


-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.376.7abedc14eae6d017.1a19bff46fd.b78faef2481a8d7=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:44 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468138.1677198 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7g-0001QG-MX; Mon, 02 Nov 2026 11:22:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468138.1677198; Mon, 02 Nov 2026 11:22:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7g-0001P8-6V; Mon, 02 Nov 2026 11:22:44 +0000
Received: by outflank-mailman (input) for mailman id 1468138;
 Mon, 02 Nov 2026 11:22:43 +0000
Received: from mx.expurgate.net ([194.145.224.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff422e000403d@swg.vates.tech>)
 id 1xNq7f-0001Is-2O
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:43 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7c-003S8x-Ul
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:40 +0100
Received: from [10.42.69.11] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff422e000403d@swg.vates.tech>)
 id 6ae87277-bab6-0a2a0a5309dd-0a2a450bde54-40
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:40 +0100
Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net)
 by tlsNG-42698a.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff422e000403d@swg.vates.tech>)
 id 6ae87280-b7e8-0a2a450b0019-b9ff1c239da1-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:40 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff422e000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:39 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 01F7B80D91;
 Mon,  2 Nov 2026 12:22:38 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=t+NZvBc7vnJPuh/lGcDXi9RQx9v3XUpMWrOPz0QzOus=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=qd+O8tU+uhc9rIEk6h7aYsvUX+AXSPQDAZb/oIfQ9MD7R9ckWDH3S5V4BF9en4Gg2b9+1b2CA
 Dw5w7a3fIQN/cnpxF3OoskXc1FMBl9h/kTs911wW1hH8j9ObFV47+8ltarOrRidNs6WLBnLTv8m
 CqjO9n0G572Ax4ucOh8xAizfJ2HiAnoopG/b4P+QQYqrhHt4I11xHS3QR7g4wGUxsVhx81aDKUV
 rjzz1fdZUcLoPEMT0YR4Rl9KFexJeZTHRkLhW241KPJG8wOQbi/ySOHmRS/zSnwgGrXV3otqURq
 e2GuDg5BgNdQUGDnEpajz07+hQ66ASiCrYlllXnIRsUg==
X-Zone-Loop: 8b25d730d769c579ddcbe6cd406d11ac50d17d0a8f9c
x-campaign-type: default
x-transaction-id: 72ac2c16-fa4e-44bb-99fc-6fffddb04182
x-swg-uid: 01-965b6910-3b2d-4ef4-aef7-46aa37436262
X-Mailer: Sweego
Message-ID:
 <1793618559.8631fc262581453bbf619ec5b2062170.1a19bff422e000403d@vates.tech>
x-swg-bid: 1793618559.8631fc262581453bbf619ec5b2062170.1a19bff422e000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 01/11] ring: Fix warning C6387: 'BlkifRing' could be '0'
Date: Mon,  2 Nov 2026 12:22:22 +0100
In-Reply-To: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.36e.f4f0fdd21bba760e.1a19bff4080.88aa09716f41a5c6=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618559104
X-purgate-ID: tlsNG-42698a/1793618560-A88C99EA-44A26D88/0/0
X-purgate-type: clean
X-purgate-size: 950

---=Part.36e.f4f0fdd21bba760e.1a19bff4080.88aa09716f41a5c6=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xenvbd/ring=2Ec | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/xenvbd/ring=2Ec b/src/xenvbd/ring=2Ec
index dae2ca0=2E=2E5ef62c9 100644
--- a/src/xenvbd/ring=2Ec
+++ b/src/xenvbd/ring=2Ec
@@ -2568,7 +2568,8 @@ RingDestroy(
         PXENVBD_BLKIF_RING  BlkifRing =3D Ring->Ring[Index];
=20
         Ring->Ring[Index] =3D NULL;
-        BlkifRingDestroy(BlkifRing);
+        if (BlkifRing)
+            BlkifRingDestroy(BlkifRing);
     }
=20
     __RingFree(Ring->Ring);
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.36e.f4f0fdd21bba760e.1a19bff4080.88aa09716f41a5c6=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:44 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:44 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468139.1677202 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7g-0001TA-PR; Mon, 02 Nov 2026 11:22:44 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468139.1677202; Mon, 02 Nov 2026 11:22:44 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7g-0001Qy-BI; Mon, 02 Nov 2026 11:22:44 +0000
Received: by outflank-mailman (input) for mailman id 1468139;
 Mon, 02 Nov 2026 11:22:43 +0000
Received: from mx.expurgate.net ([194.145.224.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4620000403d@swg.vates.tech>)
 id 1xNq7f-0001J1-2P
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:43 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7d-003S8x-CQ
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [10.42.69.11] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4620000403d@swg.vates.tech>)
 id 6ae87277-bab6-0a2a0a5309dd-0a2a450bde54-46
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net)
 by tlsNG-42698a.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4620000403d@swg.vates.tech>)
 id 6ae87280-b7e8-0a2a450b0019-b9ff1c239da1-4
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:41 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff4620000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:40 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 12A2282F6F;
 Mon,  2 Nov 2026 12:22:40 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=+v6w6qRohHpcV+XQ8TkPeHS2hYaEzn9epDyYdyEtRjo=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=kPYHPqj9rljfXsT2vQNW4ra1zYviGw8TQ4QoX/h5Ucj9UIwIKQafVp7i3t9OMnJK3kitpNPkI
 Tn40KN6vcfZhF4peoJwYQnDlUoxemgahOR6wcVhprDOKCSt1cRzhFCTtrUUHGSqhs2L1y9LAqdH
 fBwplybxecmAqMB4rwIGBrjaVJ7YTYEolGFsgj9K1ZqO2MA4YzOmwM5nCb7dBNL1zEfOgpkjuuI
 Sf+9rI2lD8RK6waxtauw3joa6BRiEQLNwK0S3harnA/+6+DYpa47JizSpbp46FQ4B4YkzjNAUnc
 U8ZXmGyj2YJRZ72UeU2Evr8lHzewb7YX+hY0TSmwIINw==
X-Zone-Loop: ae6ccccd086fe7741678c6ada8092be33610ccd6efec
x-campaign-type: default
x-transaction-id: bf6917d7-4826-4105-917a-e2fcb2f20db7
x-swg-uid: 01-157d64c1-775f-4752-8f0f-e0501518ba5d
X-Mailer: Sweego
Message-ID:
 <1793618560.8631fc262581453bbf619ec5b2062170.1a19bff4620000403d@vates.tech>
x-swg-bid: 1793618560.8631fc262581453bbf619ec5b2062170.1a19bff4620000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 06/11] granter: Decouple cache lifetime from Connected
Date: Mon,  2 Nov 2026 12:22:27 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.373.516f1a42b5bdf60b.1a19bff4486.4438cbdbe2cd559b=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618560134
X-purgate-ID: tlsNG-42698a/1793618561-19CC79EA-75C0FF86/0/0
X-purgate-type: clean
X-purgate-size: 6682

---=Part.373.516f1a42b5bdf60b.1a19bff4486.4438cbdbe2cd559b=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

We must keep the cache alive until the very last grant has been released
by the backend=2E

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xenvbd/granter=2Ec | 129 +++++++++++++++++++++++++++++++------------
 1 file changed, 95 insertions(+), 34 deletions(-)

diff --git a/src/xenvbd/granter=2Ec b/src/xenvbd/granter=2Ec
index 8271771=2E=2E6adc578 100644
--- a/src/xenvbd/granter=2Ec
+++ b/src/xenvbd/granter=2Ec
@@ -100,11 +100,26 @@ fail1:
     return status;
 }
=20
+static VOID
+__GranterDestroyCache(
+    _Inout_ PXENVBD_GRANTER Granter
+    );
+
 VOID
 GranterDestroy(
     _Inout_ PXENVBD_GRANTER Granter
     )
 {
+    BUG_ON(Granter->Current !=3D 0);
+
+    if (Granter->Cache !=3D NULL) {
+        KIRQL   Irql;
+
+        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+        __GranterDestroyCache(Granter);
+        KeLowerIrql(Irql);
+    }
+
     Granter->Frontend =3D NULL;
     RtlZeroMemory(&Granter->Lock, sizeof(KSPIN_LOCK));
=20
@@ -166,8 +181,8 @@ GranterDebugCallback(
=20
 #define MAXNAMELEN  32
=20
-NTSTATUS
-GranterConnect(
+static NTSTATUS
+__GranterCreateCache(
     _Inout_ PXENVBD_GRANTER Granter
     )
 {
@@ -175,25 +190,20 @@ GranterConnect(
     CHAR                    Name[MAXNAMELEN];
     NTSTATUS                status;
=20
-    ASSERT(Granter->Connected =3D=3D FALSE);
+    ASSERT3P(Granter->Cache, =3D=3D, NULL);
=20
     AdapterGetGnttabInterface(Adapter, &Granter->GnttabInterface);
-    AdapterGetDebugInterface(Adapter, &Granter->DebugInterface);
=20
     status =3D XENBUS_GNTTAB(Acquire, &Granter->GnttabInterface);
     if (!NT_SUCCESS(status))
         goto fail1;
=20
-    status =3D XENBUS_DEBUG(Acquire, &Granter->DebugInterface);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
     status =3D RtlStringCbPrintfA(Name,
                                 sizeof (Name),
                                 "disk_%u",
                                 FrontendGetTargetId(Granter->Frontend));
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
=20
     status =3D XENBUS_GNTTAB(CreateCache,
                            &Granter->GnttabInterface,
@@ -205,7 +215,64 @@ GranterConnect(
                            Granter,
                            &Granter->Cache);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail3;
+
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
+
+fail1:
+    Error("fail1 %08x\n", status);
+
+    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFA=
CE));
+
+    return status;
+}
+
+static VOID
+__GranterDestroyCache(
+    _Inout_ PXENVBD_GRANTER Granter
+    )
+{
+    ASSERT3S(Granter->Current, =3D=3D, 0);
+
+    XENBUS_GNTTAB(DestroyCache,
+                  &Granter->GnttabInterface,
+                  Granter->Cache);
+    Granter->Cache =3D NULL;
+
+    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
+
+    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFA=
CE));
+}
+
+NTSTATUS
+GranterConnect(
+    _Inout_ PXENVBD_GRANTER Granter
+    )
+{
+    PXENVBD_ADAPTER         Adapter =3D TargetGetAdapter(FrontendGetTarge=
t(Granter->Frontend));
+    NTSTATUS                status;
+
+    ASSERT(Granter->Connected =3D=3D FALSE);
+
+    if (Granter->Cache =3D=3D NULL) {
+        status =3D __GranterCreateCache(Granter);
+        if (!NT_SUCCESS(status))
+            goto fail1;
+    }
+
+    AdapterGetDebugInterface(Adapter, &Granter->DebugInterface);
+
+    status =3D XENBUS_DEBUG(Acquire, &Granter->DebugInterface);
+    if (!NT_SUCCESS(status))
+        goto fail2;
=20
     status =3D XENBUS_DEBUG(Register,
                           &Granter->DebugInterface,
@@ -214,30 +281,26 @@ GranterConnect(
                           Granter,
                           &Granter->DebugCallback);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail3;
=20
     Granter->Connected =3D TRUE;
     return STATUS_SUCCESS;
=20
-fail5:
-    Error("fail5\n");
-    XENBUS_GNTTAB(DestroyCache,
-                  &Granter->GnttabInterface,
-                  Granter->Cache);
-    Granter->Cache =3D NULL;
-fail4:
-    Error("fail4\n");
 fail3:
     Error("fail3\n");
+
     XENBUS_DEBUG(Release, &Granter->DebugInterface);
+
 fail2:
     Error("fail2\n");
-    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
-fail1:
-    Error("fail1 %08x\n", status);
=20
     RtlZeroMemory(&Granter->DebugInterface, sizeof(XENBUS_DEBUG_INTERFACE=
));
-    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFA=
CE));
+
+    if (Granter->Current =3D=3D 0)
+        __GranterDestroyCache(Granter);
+
+fail1:
+    Error("fail1 %08x\n", status);
=20
     return status;
 }
@@ -281,7 +344,6 @@ GranterDisconnect(
 {
     ASSERT(Granter->Connected =3D=3D TRUE);
=20
-    ASSERT3S(Granter->Current, =3D=3D, 0);
     Granter->Maximum =3D 0;
=20
     XENBUS_DEBUG(Deregister,
@@ -289,18 +351,20 @@ GranterDisconnect(
                  Granter->DebugCallback);
     Granter->DebugCallback =3D NULL;
=20
-    XENBUS_GNTTAB(DestroyCache,
-                  &Granter->GnttabInterface,
-                  Granter->Cache);
-    Granter->Cache =3D NULL;
-
     XENBUS_DEBUG(Release, &Granter->DebugInterface);
-    XENBUS_GNTTAB(Release, &Granter->GnttabInterface);
=20
     RtlZeroMemory(&Granter->DebugInterface, sizeof(XENBUS_DEBUG_INTERFACE=
));
-    RtlZeroMemory(&Granter->GnttabInterface, sizeof(XENBUS_GNTTAB_INTERFA=
CE));
=20
     Granter->Connected =3D FALSE;
+
+    if (Granter->Current !=3D 0) {
+        Warning("Target[%u] : %ld grants outstanding\n",
+                FrontendGetTargetId(Granter->Frontend),
+                Granter->Current);
+        return;
+    }
+
+    __GranterDestroyCache(Granter);
 }
=20
 NTSTATUS
@@ -382,9 +446,6 @@ GranterPut(
 {
     NTSTATUS                status;
=20
-    if (Granter->Connected =3D=3D FALSE)
-        return;
-
     for (;;) {
         status =3D GranterTryPut(Granter, Handle);
         if (NT_SUCCESS(status))
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.373.516f1a42b5bdf60b.1a19bff4486.4438cbdbe2cd559b=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:48 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468140.1677207 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7k-0001cF-Jv; Mon, 02 Nov 2026 11:22:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468140.1677207; Mon, 02 Nov 2026 11:22:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7k-0001c5-GY; Mon, 02 Nov 2026 11:22:48 +0000
Received: by outflank-mailman (input) for mailman id 1468140;
 Mon, 02 Nov 2026 11:22:47 +0000
Received: from mx.expurgate.net ([194.145.224.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4a73000403d@swg.vates.tech>)
 id 1xNq7j-0001bE-F5
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:47 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7i-003SCN-OE
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:46 +0100
Received: from [10.42.69.11] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4a73000403d@swg.vates.tech>)
 id 6ae87281-2eae-0a2a0a5409dd-0a2a450b8c68-12
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:46 +0100
Received: from [185.255.28.18] (helo=prod-mta-13.swg-srv.net)
 by tlsNG-42698a.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4a73000403d@swg.vates.tech>)
 id 6ae87281-b7e8-0a2a450b0019-b9ff1c12b1f9-4
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:46 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff4a73000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:41 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 24F3E81E0A;
 Mon,  2 Nov 2026 12:22:41 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=ARoTL543LUwMDtLtW+6WcyFF1kGkGnZdBpzV9IIDHBE=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=CiJBa2865lww5TFB7DDXtQavnarb3VbMvc2BOZznxrmD9KPxbDz4YNzIThIajsoIg0EELB7AE
 CNpQM/2OVOXrJbvs7j20sk7YQdT+6a+10Z54newFQiECWp2cqPpQwzRNPAKHBcFWgXoLXeEKPYy
 VwS5fVSXqmo+Kx29a5s4jHH/3wzVoIHYyq1zXzqfEt9Aex1qRv+isY9RiTPT4hU1YA1gxFTNe4z
 Bk/LRHc72J8kEUbjYJG/kmZr82SMXUlTNiNJJP7vn/Q5jmV2l60Uk0230/XKMjIS+QBId/hEipe
 36Stspc4wyEoG2semT0WNQ66BUwAQnLY2eMtl8ww9fJA==
X-Zone-Loop: 745f40729f6796b80b3b97f2a53a83fee21b239c7d59
x-campaign-type: default
x-transaction-id: 53b356b1-4e87-4a08-bca3-c317da094a32
x-swg-uid: 01-1fdbbdd0-2b73-4605-b33c-ee7aa2129928
X-Mailer: Sweego
Message-ID:
 <1793618561.8631fc262581453bbf619ec5b2062170.1a19bff4a73000403d@vates.tech>
x-swg-bid: 1793618561.8631fc262581453bbf619ec5b2062170.1a19bff4a73000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 11/11] ring: Defer faking submitted requests until disconnect
Date: Mon,  2 Nov 2026 12:22:32 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.378.323bb1fba03028b2.1a19bff48b5.c8a2c064d28beca1=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618561205
X-purgate-ID: tlsNG-42698a/1793618566-1ACDF9EA-E44F77BC/0/0
X-purgate-type: clean
X-purgate-size: 2818

---=Part.378.323bb1fba03028b2.1a19bff48b5.c8a2c064d28beca1=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Currently, XenVbd fakes responses before the ring close is truly
acknowledged by the backend=2E Since the backend is not made aware that we
are going to complete the faked requests on our own, it may end up
servicing these requests after we have already faked the responses=2E

We should do things the other way around instead, i=2Ee=2E close the ring
first, then fake responses later=2E

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
New in v3=2E
---
 src/xenvbd/ring=2Ec | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/xenvbd/ring=2Ec b/src/xenvbd/ring=2Ec
index d71bbe1=2E=2E4a63ac8 100644
--- a/src/xenvbd/ring=2Ec
+++ b/src/xenvbd/ring=2Ec
@@ -2656,19 +2656,8 @@ BlkifRingDisable(
     __BlkifRingAcquireLock(BlkifRing);
     BlkifRing->Enabled =3D FALSE;

-    while (!IsListEmpty(&BlkifRing->SubmittedList)) {
-        PLIST_ENTRY ListEntry;
-        PXENVBD_REQUEST Request;
-
-        ListEntry =3D RemoveHeadList(&BlkifRing->SubmittedList);
-        ASSERT3P(ListEntry, !=3D, &BlkifRing->SubmittedList);
-
-        Request =3D CONTAINING_RECORD(ListEntry, XENVBD_REQUEST, ListEntr=
y);
-        BlkifRing->ResponsesProcessed++;
-        __BlkifRingCompleteResponse(BlkifRing, Request, BLKIF_RSP_ERROR);
-
+    if (!IsListEmpty(&BlkifRing->SubmittedList))
         BlkifRing->Poisoned =3D TRUE;
-    }

     while (!IsListEmpty(&BlkifRing->PreparedQueue)) {
         PLIST_ENTRY ListEntry;
@@ -2712,9 +2701,22 @@ BlkifRingDisconnect(
                   BlkifRing->Channel);
     BlkifRing->Channel =3D NULL;

+    __BlkifRingAcquireLock(BlkifRing);
+
+    while (!IsListEmpty(&BlkifRing->SubmittedList)) {
+        PLIST_ENTRY     ListEntry;
+        PXENVBD_REQUEST Request;
+
+        ListEntry =3D RemoveHeadList(&BlkifRing->SubmittedList);
+        ASSERT3P(ListEntry, !=3D, &BlkifRing->SubmittedList);
+
+        Request =3D CONTAINING_RECORD(ListEntry, XENVBD_REQUEST, ListEntr=
y);
+        BlkifRing->ResponsesProcessed++;
+        __BlkifRingCompleteResponse(BlkifRing, Request, BLKIF_RSP_ERROR);
+    }
+
     // Normally the backend has closed by now, so anything still deferred
     // should be revocable
-    __BlkifRingAcquireLock(BlkifRing);
     BlkifRingReclaim(BlkifRing);
     Deferring =3D !IsListEmpty(&BlkifRing->DeferredList);
     __BlkifRingReleaseLock(BlkifRing);
--
2=2E56=2E0=2Ewindows=2E4


-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.378.323bb1fba03028b2.1a19bff48b5.c8a2c064d28beca1=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:22:48 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:22:48 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468141.1677213 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7k-0001ca-Nv; Mon, 02 Nov 2026 11:22:48 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468141.1677213; Mon, 02 Nov 2026 11:22:48 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq7k-0001cJ-Ht; Mon, 02 Nov 2026 11:22:48 +0000
Received: by outflank-mailman (input) for mailman id 1468141;
 Mon, 02 Nov 2026 11:22:47 +0000
Received: from mx.expurgate.net ([195.190.135.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4998000403d@swg.vates.tech>)
 id 1xNq7j-0001b8-Bl
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:22:47 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq7i-00AYId-LO
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:22:46 +0100
Received: from [10.42.69.12] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4998000403d@swg.vates.tech>)
 id 6ae8727a-e002-0a2a0a5209dd-0a2a450ce2d2-44
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:46 +0100
Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net)
 by tlsNG-d25034.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19bff4998000403d@swg.vates.tech>)
 id 6ae87280-f479-0a2a450c0019-b9ff1c22805f-5
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:22:46 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19bff4998000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:22:41 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id DF64F80D91;
 Mon,  2 Nov 2026 12:22:40 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=4Vqhep1GCQq0wDFMwwg/bZ1fckZ+fsg/ZmLA/8HwTKc=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=jLekKNjKMRZDAWvTr2JH042zXtGapBl6st+B4wVsKKtqWLnNotJkzUvWgYXujODmnv0pLj8dj
 CiCMhd6o+jLfVP+S3K2JkKyUeYulMWAkMIfPSWGtDk+soknlcdwPq4NzMdS0colh0rA7pZn+RBw
 vXZAb1wGlnfDxyumokgD40AFP5/hP1hbs9WVVYXT3lTea9siQIm4j4bYwdsPJ8NWDWaLh0su5hp
 xm6flagzFeNA6B0jJvQqov1GD3LlyCL2RFKXB4J1mOZIG21zRfFAwbWuzluO9v390iqQv+svukD
 9ipa09X8fL7l+/rxov/3SUXlF6/wJYCvd3881nxvknjQ==
X-Zone-Loop: 538eb831e9cbbcc2b7fd3094cec4901e682af34926d6
x-campaign-type: default
x-transaction-id: 4b60db97-92f1-4496-9a49-82674b3ab59a
x-swg-uid: 01-39e509ff-7e40-4ce1-b26b-299795959950
X-Mailer: Sweego
Message-ID:
 <1793618561.8631fc262581453bbf619ec5b2062170.1a19bff4998000403d@vates.tech>
x-swg-bid: 1793618561.8631fc262581453bbf619ec5b2062170.1a19bff4998000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH v3 10/11] ring: Defer request completion until backend grant release
Date: Mon,  2 Nov 2026 12:22:31 +0100
In-Reply-To: <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
References: <1793618434.8631fc262581453bbf619ec5b2062170.1a19bfd5b0f000403d@vates.tech>
 <20261102112236.1649-1-ngoc-tu.dinh@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.377.f64df77581c32dce.1a19bff47e0.b2d5b6a16d09d4c9=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618560992
X-purgate-ID: tlsNG-d25034/1793618566-51538A5B-3398D165/0/0
X-purgate-type: clean
X-purgate-size: 25123

---=Part.377.f64df77581c32dce.1a19bff47e0.b2d5b6a16d09d4c9=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

If the backend is still accessing the request grants, we must defer
completion until the backend has fully released them=2E

Check for request grant revocation results=2E If it fails, queue the
request onto the reclaim thread=2E

Request lifecycle changes are documented in BlkifRingGetRequest=2E
GranterPut is removed since there are no more users=2E

Assisted-by: LLM
Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
v3: Release as many grants as possible before deferring=2E
---
 src/xenvbd/granter=2Ec |  17 ---
 src/xenvbd/granter=2Eh |   6 -
 src/xenvbd/ring=2Ec    | 351 +++++++++++++++++++++++++++++++------------
 3 files changed, 251 insertions(+), 123 deletions(-)

diff --git a/src/xenvbd/granter=2Ec b/src/xenvbd/granter=2Ec
index 7b7a7c8=2E=2Ecbd5022 100644
--- a/src/xenvbd/granter=2Ec
+++ b/src/xenvbd/granter=2Ec
@@ -463,23 +463,6 @@ fail1:
     return status;
 }

-VOID
-GranterPut(
-    _Inout_ PXENVBD_GRANTER Granter,
-    _In_ PVOID              Handle
-    )
-{
-    NTSTATUS                status;
-
-    for (;;) {
-        status =3D GranterTryPut(Granter, Handle);
-        if (NT_SUCCESS(status))
-            break;
-
-        YieldProcessor();
-    }
-}
-
 ULONG
 GranterReference(
     _In_ PXENVBD_GRANTER    Granter,
diff --git a/src/xenvbd/granter=2Eh b/src/xenvbd/granter=2Eh
index 93b962c=2E=2E873f028 100644
--- a/src/xenvbd/granter=2Eh
+++ b/src/xenvbd/granter=2Eh
@@ -103,12 +103,6 @@ GranterTryPut(
     _In_ PVOID              Handle
     );

-extern VOID
-GranterPut(
-    _Inout_ PXENVBD_GRANTER Granter,
-    _In_ PVOID              Handle
-    );
-
 extern ULONG
 GranterReference(
     _In_ PXENVBD_GRANTER    Granter,
diff --git a/src/xenvbd/ring=2Ec b/src/xenvbd/ring=2Ec
index b41c9c3=2E=2Ed71bbe1 100644
--- a/src/xenvbd/ring=2Ec
+++ b/src/xenvbd/ring=2Ec
@@ -91,8 +91,12 @@ typedef struct _XENVBD_BLKIF_RING {
     LIST_ENTRY                      PreparedQueue;
     LIST_ENTRY                      SubmittedList;
     LIST_ENTRY                      ShutdownQueue;
+    // List of XENVBD_REQUEST still being held by the backend
+    LIST_ENTRY                      DeferredList;
     // List of XENVBD_BLKIF_PAGES still being held by the backend
     LIST_ENTRY                      DeferredPages;
+    ULONG                           RequestsDeferred;
+    ULONG                           RequestsReclaimed;
     ULONG                           SrbsQueued;
     ULONG                           SrbsCompleted;
     ULONG                           SrbsFailed;
@@ -288,12 +292,8 @@ BlkifRingPutIndirect(
     )
 {
     PXENVBD_RING                Ring =3D BlkifRing->Ring;
-    PXENVBD_FRONTEND            Frontend =3D Ring->Frontend;
-    PXENVBD_GRANTER             Granter =3D FrontendGetGranter(Frontend);

-    if (Indirect->Grant)
-        GranterPut(Granter, Indirect->Grant);
-    Indirect->Grant =3D NULL;
+    ASSERT3P(Indirect->Grant, =3D=3D, NULL);

     RtlZeroMemory(&Indirect->ListEntry, sizeof(LIST_ENTRY));

@@ -325,12 +325,9 @@ BlkifRingPutSegment(
 {
     PXENVBD_RING            Ring =3D BlkifRing->Ring;
     PXENVBD_FRONTEND        Frontend =3D Ring->Frontend;
-    PXENVBD_GRANTER         Granter =3D FrontendGetGranter(Frontend);
     PXENVBD_BOUNCE          Bounce =3D Segment->Bounce;

-    if (Segment->Grant)
-        GranterPut(Granter, Segment->Grant);
-    Segment->Grant =3D NULL;
+    ASSERT3P(Segment->Grant, =3D=3D, NULL);

     if (Bounce) {
         if (Bounce->SourcePtr) {
@@ -358,6 +355,19 @@ BlkifRingPutSegment(
                  TRUE);
 }

+/*
+ * Request lifecycle:
+ * - Prepare: BlkifRingPrepare*() attach segments, bounce buffers, indire=
ct
+ *   pages and grants, and take a SrbExt->RequestCount reference for each
+ *   request=2E The SRB completes when the last reference is dropped=2E
+ * - Done (response received or faked, or preparation failed):
+ *   BlkifRingTryPutRequest(), then BlkifRingDeferRequest() if that fails=
=2E
+ * - If deferred: ReclaimThread retries BlkifRingTryPutRequest() until it
+ *   succeeds=2E
+ * - BlkifRingTryPutRequest() revokes all grants first, then puts everyth=
ing
+ *   back into the caches and drops the SRB reference (__BlkifRingPutSrb(=
))=2E
+ *   Revocation can fail and be retried=2E
+ */
 static PXENVBD_REQUEST
 BlkifRingGetRequest(
     _In_ PXENVBD_BLKIF_RING BlkifRing
@@ -372,47 +382,17 @@ BlkifRingGetRequest(
 }

 static VOID
-BlkifRingPutRequest(
-    _In_ PXENVBD_BLKIF_RING BlkifRing,
-    _Inout_ PXENVBD_REQUEST Request
+BlkifRingDeferRequest(
+    _Inout_ PXENVBD_BLKIF_RING  BlkifRing,
+    _Inout_ PXENVBD_REQUEST     Request
     )
 {
-    PXENVBD_RING            Ring =3D BlkifRing->Ring;
-    PLIST_ENTRY             ListEntry;
-
-    for (;;) {
-        PXENVBD_SEGMENT Segment;
-
-        ListEntry =3D RemoveHeadList(&Request->Segments);
-        if (ListEntry =3D=3D &Request->Segments)
-            break;
-        Segment =3D CONTAINING_RECORD(ListEntry, XENVBD_SEGMENT, ListEntr=
y);
-        BlkifRingPutSegment(BlkifRing, Segment);
-    }
-
-    for (;;) {
-        PXENVBD_INDIRECT    Indirect;
-
-        ListEntry =3D RemoveHeadList(&Request->Indirects);
-        if (ListEntry =3D=3D &Request->Indirects)
-            break;
-        Indirect =3D CONTAINING_RECORD(ListEntry, XENVBD_INDIRECT, ListEn=
try);
-        BlkifRingPutIndirect(BlkifRing, Indirect);
-    }
+    PXENVBD_RING                Ring =3D BlkifRing->Ring;

-    Request->SrbExt =3D NULL;
-    Request->Operation =3D 0;
-    Request->Flags =3D 0;
-    Request->NrSegments =3D 0;
-    Request->FirstSector =3D 0;
-    Request->NrSectors =3D 0;
-    RtlZeroMemory(&Request->ListEntry, sizeof(LIST_ENTRY));
+    InsertTailList(&BlkifRing->DeferredList, &Request->ListEntry);
+    BlkifRing->RequestsDeferred++;

-    XENBUS_CACHE(Put,
-                 &Ring->CacheInterface,
-                 BlkifRing->RequestCache,
-                 Request,
-                 TRUE);
+    ThreadWake(Ring->ReclaimThread);
 }

 static DECLSPEC_NOINLINE NTSTATUS
@@ -552,6 +532,13 @@ BlkifRingDebugCallback(
                  BlkifRing->SrbsCompleted,
                  BlkifRing->SrbsFailed);

+    XENBUS_DEBUG(Printf,
+                 &Ring->DebugInterface,
+                 "RequestsDeferred =3D %u RequestsReclaimed =3D %u%s\n",
+                 BlkifRing->RequestsDeferred,
+                 BlkifRing->RequestsReclaimed,
+                 IsListEmpty(&BlkifRing->DeferredPages) ? "" : " (ring pa=
ges deferred)");
+
     XENBUS_DEBUG(Printf,
                  &Ring->DebugInterface,
                  "Dpcs =3D %u, Events =3D %u\n",
@@ -586,6 +573,101 @@ __BlkifRingCompleteSrb(
     AdapterCompleteSrb(Adapter, SrbExt);
 }

+static FORCEINLINE VOID
+__BlkifRingPutSrb(
+    _Inout_ PXENVBD_BLKIF_RING  BlkifRing,
+    _In_ PXENVBD_SRBEXT         SrbExt
+    )
+{
+    ASSERT3S(SrbExt->RequestCount, >, 0);
+
+    if (--SrbExt->RequestCount =3D=3D 0)
+        __BlkifRingCompleteSrb(BlkifRing, SrbExt);
+}
+
+_Check_return_
+static BOOLEAN
+BlkifRingTryPutRequest(
+    _Inout_ PXENVBD_BLKIF_RING  BlkifRing,
+    _Inout_ PXENVBD_REQUEST     Request
+    )
+{
+    PXENVBD_RING                Ring =3D BlkifRing->Ring;
+    PXENVBD_GRANTER             Granter =3D FrontendGetGranter(Ring->Fron=
tend);
+    PXENVBD_SRBEXT              SrbExt =3D Request->SrbExt;
+    PLIST_ENTRY                 ListEntry;
+    BOOLEAN                     Revoked =3D TRUE;
+
+    for (ListEntry =3D Request->Segments=2EFlink;
+         ListEntry !=3D &Request->Segments;
+         ListEntry =3D ListEntry->Flink) {
+        PXENVBD_SEGMENT Segment =3D CONTAINING_RECORD(ListEntry, XENVBD_S=
EGMENT, ListEntry);
+
+        if (Segment->Grant =3D=3D NULL)
+            continue;
+
+        if (NT_SUCCESS(GranterTryPut(Granter, Segment->Grant)))
+            Segment->Grant =3D NULL;
+        else
+            Revoked =3D FALSE;
+    }
+
+    for (ListEntry =3D Request->Indirects=2EFlink;
+         ListEntry !=3D &Request->Indirects;
+         ListEntry =3D ListEntry->Flink) {
+        PXENVBD_INDIRECT    Indirect =3D CONTAINING_RECORD(ListEntry, XEN=
VBD_INDIRECT, ListEntry);
+
+        if (Indirect->Grant =3D=3D NULL)
+            continue;
+
+        if (NT_SUCCESS(GranterTryPut(Granter, Indirect->Grant)))
+            Indirect->Grant =3D NULL;
+        else
+            Revoked =3D FALSE;
+    }
+
+    if (!Revoked)
+        return FALSE;
+
+    for (;;) {
+        PXENVBD_SEGMENT Segment;
+
+        ListEntry =3D RemoveHeadList(&Request->Segments);
+        if (ListEntry =3D=3D &Request->Segments)
+            break;
+        Segment =3D CONTAINING_RECORD(ListEntry, XENVBD_SEGMENT, ListEntr=
y);
+        BlkifRingPutSegment(BlkifRing, Segment);
+    }
+
+    for (;;) {
+        PXENVBD_INDIRECT    Indirect;
+
+        ListEntry =3D RemoveHeadList(&Request->Indirects);
+        if (ListEntry =3D=3D &Request->Indirects)
+            break;
+        Indirect =3D CONTAINING_RECORD(ListEntry, XENVBD_INDIRECT, ListEn=
try);
+        BlkifRingPutIndirect(BlkifRing, Indirect);
+    }
+
+    Request->SrbExt =3D NULL;
+    Request->Operation =3D 0;
+    Request->Flags =3D 0;
+    Request->NrSegments =3D 0;
+    Request->FirstSector =3D 0;
+    Request->NrSectors =3D 0;
+    RtlZeroMemory(&Request->ListEntry, sizeof(LIST_ENTRY));
+
+    XENBUS_CACHE(Put,
+                 &Ring->CacheInterface,
+                 BlkifRing->RequestCache,
+                 Request,
+                 TRUE);
+
+    __BlkifRingPutSrb(BlkifRing, SrbExt);
+
+    return TRUE;
+}
+
 static FORCEINLINE VOID
 BlkifRingUnprepareRequest(
     _In_ PXENVBD_BLKIF_RING BlkifRing,
@@ -604,7 +686,8 @@ BlkifRingUnprepareRequest(
                                     XENVBD_REQUEST,
                                     ListEntry);

-        BlkifRingPutRequest(BlkifRing, Request);
+        if (!BlkifRingTryPutRequest(BlkifRing, Request))
+            BlkifRingDeferRequest(BlkifRing, Request);
     }
 }

@@ -771,8 +854,6 @@ BlkifRingPrepareReadWrite(

     Srb->SrbStatus =3D SRB_STATUS_PENDING;

-    SrbExt->RequestCount =3D 0;
-
     while (SectorsLeft > 0) {
         ULONG           Index;
         ULONG           MaxSegments;
@@ -846,7 +927,6 @@ fail3:
 fail2:
 fail1:
     BlkifRingUnprepareRequest(BlkifRing, &List);
-    SrbExt->RequestCount =3D 0;
     Srb->SrbStatus =3D SRB_STATUS_ERROR;
     return STATUS_UNSUCCESSFUL;
 }
@@ -871,8 +951,6 @@ BlkifRingPrepareUnmap(
     Count =3D _byteswap_ushort(*(PUSHORT)Unmap->BlockDescrDataLength) / s=
izeof(UNMAP_BLOCK_DESCRIPTOR);
     Srb->SrbStatus =3D SRB_STATUS_PENDING;

-    SrbExt->RequestCount =3D 0;
-
     for (Index =3D 0; Index < Count; ++Index) {
         PUNMAP_BLOCK_DESCRIPTOR Descr =3D &Unmap->Descriptors[Index];
         PXENVBD_REQUEST         Request;
@@ -885,13 +963,14 @@ BlkifRingPrepareUnmap(
         InsertTailList(&List, &Request->ListEntry);
         SrbExt->RequestCount++;

+        Request->SrbExt =3D SrbExt;
+
         StartLBA =3D _byteswap_uint64(*(PULONG64)Descr->StartingLba);
         CountLBA =3D _byteswap_ulong(*(PULONG)Descr->LbaCount);

         if (!DiskInfoIsValidExtent(DiskInfo, StartLBA, CountLBA))
             goto fail2;

-        Request->SrbExt =3D SrbExt;
         Request->Operation =3D BLKIF_OP_DISCARD;
         Request->FirstSector =3D StartLBA << DiskInfo->SectorShift;
         Request->NrSectors =3D CountLBA << DiskInfo->SectorShift;
@@ -904,7 +983,6 @@ BlkifRingPrepareUnmap(
 fail2:
 fail1:
     BlkifRingUnprepareRequest(BlkifRing, &List);
-    SrbExt->RequestCount =3D 0;
     Srb->SrbStatus =3D SRB_STATUS_ERROR;
     return STATUS_UNSUCCESSFUL;
 }
@@ -931,8 +1009,6 @@ BlkifRingPrepareSyncCache(
     else
         Operation =3D BLKIF_OP_WRITE_BARRIER;

-    SrbExt->RequestCount =3D 0;
-
     Request =3D BlkifRingGetRequest(BlkifRing);
     if (Request =3D=3D NULL)
         goto fail1;
@@ -948,35 +1024,50 @@ BlkifRingPrepareSyncCache(

 fail1:
     BlkifRingUnprepareRequest(BlkifRing, &List);
-    SrbExt->RequestCount =3D 0;
     Srb->SrbStatus =3D SRB_STATUS_ERROR;
     return STATUS_UNSUCCESSFUL;
 }

-static DECLSPEC_NOINLINE NTSTATUS
+static DECLSPEC_NOINLINE VOID
 __BlkifRingPrepareSrb(
     _Inout_ PXENVBD_BLKIF_RING  BlkifRing,
     _Inout_ PXENVBD_SRBEXT      SrbExt
     )
 {
-    switch (Cdb_OperationEx(SrbExt->Srb)) {
+    PSCSI_REQUEST_BLOCK         Srb =3D SrbExt->Srb;
+    NTSTATUS                    status;
+
+    // Held while the requests are built, so that releasing them on failu=
re
+    // cannot complete the SRB before its status is set
+    SrbExt->RequestCount =3D 1;
+
+    switch (Cdb_OperationEx(Srb)) {
     case SCSIOP_READ:
     case SCSIOP_WRITE:
-        return BlkifRingPrepareReadWrite(BlkifRing,
-                                         SrbExt);
+        status =3D BlkifRingPrepareReadWrite(BlkifRing,
+                                           SrbExt);
+        break;

     case SCSIOP_SYNCHRONIZE_CACHE:
-        return BlkifRingPrepareSyncCache(BlkifRing,
-                                         SrbExt);
+        status =3D BlkifRingPrepareSyncCache(BlkifRing,
+                                           SrbExt);
+        break;

     case SCSIOP_UNMAP:
-        return BlkifRingPrepareUnmap(BlkifRing,
-                                     SrbExt);
+        status =3D BlkifRingPrepareUnmap(BlkifRing,
+                                       SrbExt);
+        break;

     default:
         ASSERT(FALSE);
-        return STATUS_NOT_SUPPORTED;
+        status =3D STATUS_NOT_SUPPORTED;
+        break;
     }
+
+    if (!NT_SUCCESS(status))
+        Srb->SrbStatus =3D SRB_STATUS_BUSY;
+
+    __BlkifRingPutSrb(BlkifRing, SrbExt);
 }

 static FORCEINLINE VOID
@@ -1213,12 +1304,8 @@ __BlkifRingCompleteResponse(
         }
     }

-    BlkifRingPutRequest(BlkifRing, Request);
-
-    // complete srb
-    if (--SrbExt->RequestCount =3D=3D 0) {
-        __BlkifRingCompleteSrb(BlkifRing, SrbExt);
-    }
+    if (!BlkifRingTryPutRequest(BlkifRing, Request))
+        BlkifRingDeferRequest(BlkifRing, Request);
 }

 static FORCEINLINE BOOLEAN
@@ -1468,12 +1555,7 @@ BlkifRingSchedule(
                                    XENVBD_SRBEXT,
                                    ListEntry);

-        status =3D __BlkifRingPrepareSrb(BlkifRing, SrbExt);
-        if (!NT_SUCCESS(status)) {
-            PSCSI_REQUEST_BLOCK Srb =3D SrbExt->Srb;
-            Srb->SrbStatus =3D SRB_STATUS_BUSY;
-            __BlkifRingCompleteSrb(BlkifRing, SrbExt);
-        }
+        __BlkifRingPrepareSrb(BlkifRing, SrbExt);
     }

     __BlkifRingPushRequests(BlkifRing);
@@ -1873,7 +1955,8 @@ __BlkifRingIsDeferring(
     _In_ PXENVBD_BLKIF_RING BlkifRing
     )
 {
-    return !IsListEmpty(&BlkifRing->DeferredPages);
+    return !IsListEmpty(&BlkifRing->DeferredList) ||
+           !IsListEmpty(&BlkifRing->DeferredPages);
 }

 _IRQL_requires_(DISPATCH_LEVEL)
@@ -1886,6 +1969,23 @@ BlkifRingReclaim(
     ASSERT3P(BlkifRing->LockThread, =3D=3D, KeGetCurrentThread());
 #endif

+    while (!IsListEmpty(&BlkifRing->DeferredList)) {
+        PLIST_ENTRY         ListEntry;
+        PXENVBD_REQUEST     Request;
+
+        ListEntry =3D RemoveHeadList(&BlkifRing->DeferredList);
+        Request =3D CONTAINING_RECORD(ListEntry, XENVBD_REQUEST, ListEntr=
y);
+
+        if (!BlkifRingTryPutRequest(BlkifRing, Request)) {
+            // Move this reclaim failure to the back so that entries behi=
nd it
+            // are tried first on the next pass=2E
+            InsertTailList(&BlkifRing->DeferredList, ListEntry);
+            break;
+        }
+
+        BlkifRing->RequestsReclaimed++;
+    }
+
     while (!IsListEmpty(&BlkifRing->DeferredPages)) {
         PLIST_ENTRY         ListEntry;
         PXENVBD_BLKIF_PAGES Pages;
@@ -1894,8 +1994,6 @@ BlkifRingReclaim(
         Pages =3D CONTAINING_RECORD(ListEntry, XENVBD_BLKIF_PAGES, ListEn=
try);

         if (!__BlkifRingRevokePages(BlkifRing, Pages)) {
-            // Move this reclaim failure to the back so that entries behi=
nd it
-            // are tried first on the next pass=2E
             InsertTailList(&BlkifRing->DeferredPages, ListEntry);
             break;
         }
@@ -2011,13 +2109,19 @@ BlkifRingCacheCreate(
     Ring =3D BlkifRing->Ring;
     Frontend =3D Ring->Frontend;

+    // The caches hold their own reference on the interface, as they outl=
ive
+    // a disconnect while any of their objects are deferred=2E
+    status =3D XENBUS_CACHE(Acquire, &Ring->CacheInterface);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     status =3D RtlStringCbPrintfA(Name,
                                 sizeof(Name),
                                 "vbd_%u_queue_%u_request",
                                 FrontendGetTargetId(Frontend),
                                 BlkifRing->Index);
     if (!NT_SUCCESS(status))
-        goto fail1;
+        goto fail2;

     status =3D XENBUS_CACHE(Create,
                           &Ring->CacheInterface,
@@ -2032,7 +2136,7 @@ BlkifRingCacheCreate(
                           BlkifRing,
                           &BlkifRing->RequestCache);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail3;

     status =3D RtlStringCbPrintfA(Name,
                                 sizeof(Name),
@@ -2040,7 +2144,7 @@ BlkifRingCacheCreate(
                                 FrontendGetTargetId(Frontend),
                                 BlkifRing->Index);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail4;

     status =3D XENBUS_CACHE(Create,
                           &Ring->CacheInterface,
@@ -2055,7 +2159,7 @@ BlkifRingCacheCreate(
                           BlkifRing,
                           &BlkifRing->SegmentCache);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail5;

     status =3D RtlStringCbPrintfA(Name,
                                 sizeof(Name),
@@ -2063,7 +2167,7 @@ BlkifRingCacheCreate(
                                 FrontendGetTargetId(Frontend),
                                 BlkifRing->Index);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail6;

     status =3D XENBUS_CACHE(Create,
                           &Ring->CacheInterface,
@@ -2078,35 +2182,40 @@ BlkifRingCacheCreate(
                           BlkifRing,
                           &BlkifRing->IndirectCache);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail7;

     return STATUS_SUCCESS;

+fail7:
+    Error("fail7\n");
+
 fail6:
     Error("fail6\n");

-fail5:
-    Error("fail5\n");
-
     XENBUS_CACHE(Destroy,
                  &Ring->CacheInterface,
                  BlkifRing->SegmentCache);
     BlkifRing->SegmentCache =3D NULL;

+fail5:
+    Error("fail5\n");
+
 fail4:
     Error("fail4\n");

-fail3:
-    Error("fail3\n");
-
     XENBUS_CACHE(Destroy,
                  &Ring->CacheInterface,
                  BlkifRing->RequestCache);
     BlkifRing->RequestCache =3D NULL;

+fail3:
+    Error("fail3\n");
+
 fail2:
     Error("fail2\n");

+    XENBUS_CACHE(Release, &Ring->CacheInterface);
+
 fail1:
     Error("fail1 %08x\n", status);

@@ -2136,6 +2245,8 @@ BlkifRingCacheDestroy(
                  &Ring->CacheInterface,
                  BlkifRing->RequestCache);
     BlkifRing->RequestCache =3D NULL;
+
+    XENBUS_CACHE(Release, &Ring->CacheInterface);
 }

 static NTSTATUS
@@ -2184,6 +2295,7 @@ BlkifRingCreate(
     InitializeListHead(&(*BlkifRing)->ShutdownQueue);
     InitializeListHead(&(*BlkifRing)->SubmittedList);
     InitializeListHead(&(*BlkifRing)->PreparedQueue);
+    InitializeListHead(&(*BlkifRing)->DeferredList);
     InitializeListHead(&(*BlkifRing)->DeferredPages);

     KeInitializeThreadedDpc(&(*BlkifRing)->Dpc, BlkifRingDpc, *BlkifRing)=
;
@@ -2202,6 +2314,7 @@ fail4:
     RtlZeroMemory(&(*BlkifRing)->Dpc, sizeof(KDPC));

     RtlZeroMemory(&(*BlkifRing)->DeferredPages, sizeof(LIST_ENTRY));
+    RtlZeroMemory(&(*BlkifRing)->DeferredList, sizeof(LIST_ENTRY));
     RtlZeroMemory(&(*BlkifRing)->PreparedQueue, sizeof(LIST_ENTRY));
     RtlZeroMemory(&(*BlkifRing)->SubmittedList, sizeof(LIST_ENTRY));
     RtlZeroMemory(&(*BlkifRing)->ShutdownQueue, sizeof(LIST_ENTRY));
@@ -2235,10 +2348,15 @@ BlkifRingDestroy(
     BlkifRing->WatchdogThread =3D NULL;

     BUG_ON(__BlkifRingIsDeferring(BlkifRing));
+    ASSERT3P(BlkifRing->RequestCache, =3D=3D, NULL);
+
+    BlkifRing->RequestsDeferred =3D 0;
+    BlkifRing->RequestsReclaimed =3D 0;

     RtlZeroMemory(&BlkifRing->Dpc, sizeof(KDPC));

     RtlZeroMemory(&BlkifRing->DeferredPages, sizeof(LIST_ENTRY));
+    RtlZeroMemory(&BlkifRing->DeferredList, sizeof(LIST_ENTRY));

     ASSERT(IsListEmpty(&BlkifRing->PreparedQueue));
     RtlZeroMemory(&BlkifRing->PreparedQueue, sizeof(LIST_ENTRY));
@@ -2274,6 +2392,7 @@ BlkifRingConnect(
     PXENVBD_FRONTEND            Frontend =3D Ring->Frontend;
     PXENVBD_GRANTER             Granter =3D FrontendGetGranter(Frontend);
     CHAR                        Name[MAX_NAME_LEN];
+    BOOLEAN                     CacheCreated;
     ULONG                       Index;
     NTSTATUS                    status;

@@ -2291,9 +2410,15 @@ BlkifRingConnect(
     }
     KeSetImportanceDpc(&BlkifRing->Dpc, MediumHighImportance);

-    status =3D BlkifRingCacheCreate(BlkifRing);
-    if (!NT_SUCCESS(status))
-        goto fail1;
+    // The caches are kept by a disconnect that left requests deferred
+    CacheCreated =3D FALSE;
+    if (BlkifRing->RequestCache =3D=3D NULL) {
+        status =3D BlkifRingCacheCreate(BlkifRing);
+        if (!NT_SUCCESS(status))
+            goto fail1;
+
+        CacheCreated =3D TRUE;
+    }

     BlkifRing->Pages =3D BlkifRingAllocatePages(1ul << Ring->Order);

@@ -2376,7 +2501,8 @@ fail3:
     BlkifRingReleasePages(BlkifRing);
 fail2:
     Error("fail2\n");
-    BlkifRingCacheDestroy(BlkifRing);
+    if (CacheCreated)
+        BlkifRingCacheDestroy(BlkifRing);
 fail1:
     Error("fail1 %08x\n", status);
     return status;
@@ -2571,6 +2697,7 @@ BlkifRingDisconnect(
     )
 {
     PXENVBD_RING                Ring =3D BlkifRing->Ring;
+    BOOLEAN                     Deferring;

     Trace("=3D=3D=3D=3D> %u\n", BlkifRing->Index);
     ASSERT(BlkifRing->Connected);
@@ -2585,17 +2712,27 @@ BlkifRingDisconnect(
                   BlkifRing->Channel);
     BlkifRing->Channel =3D NULL;

-    // Normally the backend has closed by now, so ring pages left over fr=
om
-    // earlier connections should be revocable
+    // Normally the backend has closed by now, so anything still deferred
+    // should be revocable
     __BlkifRingAcquireLock(BlkifRing);
     BlkifRingReclaim(BlkifRing);
+    Deferring =3D !IsListEmpty(&BlkifRing->DeferredList);
     __BlkifRingReleaseLock(BlkifRing);

     RtlZeroMemory(&BlkifRing->Front, sizeof(blkif_front_ring_t));

     BlkifRingReleasePages(BlkifRing);

-    BlkifRingCacheDestroy(BlkifRing);
+    // Deferred requests still own objects from the caches, so keep them =
(and
+    // let the next connection reuse them) until the requests are reclaim=
ed
+    if (Deferring) {
+        Warning("Target[%u][%u] : %u request(s) still deferred\n",
+                FrontendGetTargetId(Ring->Frontend),
+                BlkifRing->Index,
+                BlkifRing->RequestsDeferred - BlkifRing->RequestsReclaime=
d);
+    } else {
+        BlkifRingCacheDestroy(BlkifRing);
+    }

     BlkifRing->Events =3D 0;
     BlkifRing->Dpcs =3D 0;
@@ -2896,6 +3033,20 @@ RingD0ToD3(

         Trace("done\n");
     }
+
+    // Caches kept by a disconnect that left requests deferred, along wit=
h
+    // their cache interface references, can go now
+    for (Index =3D 0; Index < FrontendGetMaxQueues(Ring->Frontend); ++Ind=
ex) {
+        PXENVBD_BLKIF_RING  BlkifRing =3D Ring->Ring[Index];
+        KIRQL               Irql;
+
+        if (BlkifRing->RequestCache =3D=3D NULL)
+            continue;
+
+        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+        BlkifRingCacheDestroy(BlkifRing);
+        KeLowerIrql(Irql);
+    }
 }

 NTSTATUS
--
2=2E56=2E0=2Ewindows=2E4


-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.377.f64df77581c32dce.1a19bff47e0.b2d5b6a16d09d4c9=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:23:34 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:23:34 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468142.1677214 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq8U-0001yD-OL; Mon, 02 Nov 2026 11:23:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468142.1677214; Mon, 02 Nov 2026 11:23:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNq8U-0001y6-Lq; Mon, 02 Nov 2026 11:23:34 +0000
Received: by outflank-mailman (input) for mailman id 1468142;
 Mon, 02 Nov 2026 11:23:33 +0000
Received: from mx.expurgate.net ([194.145.224.20])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19c000c2b000403d@swg.vates.tech>)
 id 1xNq8T-0001xV-3V
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:23:33 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNq8S-003STf-GV
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:23:32 +0100
Received: from [10.42.69.11] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19c000c2b000403d@swg.vates.tech>)
 id 6ae872a2-bab6-0a2a0a5309dd-0a2a450b97c6-32
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:23:32 +0100
Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net)
 by tlsNG-42698a.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19c000c2b000403d@swg.vates.tech>)
 id 6ae872b4-b7e8-0a2a450b0019-b9ff1c23a309-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:23:32 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19c000c2b000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:23:31 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 941D880D91;
 Mon,  2 Nov 2026 12:23:30 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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:Feedback-ID"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=usRjH31RJ4Pnmgmc3skr/ufhAUEAo0/9gJpLa/TDrqY=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:feedback-id;
 b=Ix6n/R/DRZ5WTV/+V017ulE5DpqlqWx9m+lgEtQ0iPBWfWpHcUrxymgb/61o/SqX4dIayvdXU
 y6Oo3Yp6xmVBoQUd29bIJx6x/auMtF7JrSv+nlIemeMvwqr7/ArvRnG6s/GntiyQcOEmuM+FHAq
 IRYBXUbhyWvA1j29cfUXdw0Epx/p106IkeYJBaCbSNNPRcvd/x2/sg2OIi6jRmTKy9Vdx0CxZy6
 gOrhWB+LJNJxgFGJ1oQDRFHENF1h3nhAJk8jKpgZN/myOx1ZNqco4X6/YvH+4+r9C8HFrY3UEEj
 /988HDNWhK05PURfNaKkr5U2YbXwM/dR/lCHWGU7WMlw==
X-Zone-Loop: 35b8dc7a13faf90584c22c3b1459e9d75963f0e8a0a3
x-campaign-type: default
x-transaction-id: 74dd77ac-e9c3-4af3-80b5-80f938538899
x-swg-uid: 01-0823ff88-7b3b-40ea-8367-f272352c82ca
X-Mailer: Sweego
Message-ID:
 <1793618611.8631fc262581453bbf619ec5b2062170.1a19c000c2b000403d@vates.tech>
x-swg-bid: 1793618611.8631fc262581453bbf619ec5b2062170.1a19c000c2b000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH] stream: Guard against failure to acquire ConsoleInterface
Date: Mon,  2 Nov 2026 12:23:27 +0100
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.379.c58580c0105e52ca.1a19c0009ea.c7699471304ba7c3=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793618610667
X-purgate-ID: tlsNG-42698a/1793618612-18AC89EA-20A69C50/0/0
X-purgate-type: clean
X-purgate-size: 4065

---=Part.379.c58580c0105e52ca.1a19c0009ea.c7699471304ba7c3=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

If console access is not enabled in XenBus (e=2Eg=2E via UseConsole or
similar), console IRPs will block forever during reads and writes until
canceled=2E We should rather explicitly signal instead that the console is
not available=2E

Add a Stream->Failed flag that denies all incoming IRPs if
ConsoleAcquire failed=2E This must be done in StreamCsqInsertIrpEx to
avoid racing with the worker setting Failed =3D TRUE=2E

Because this flag deals with new IRPs, already-queued IRPs at the time
the worker fails need to be completed manually with an error code=2E

Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xencons/stream=2Ec | 52 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/src/xencons/stream=2Ec b/src/xencons/stream=2Ec
index 8760e7e=2E=2E421fc42 100644
--- a/src/xencons/stream=2Ec
+++ b/src/xencons/stream=2Ec
@@ -43,12 +43,13 @@
 #define STREAM_POOL 'ETRS'
=20
 struct _XENCONS_STREAM {
-    PXENCONS_FDO            	Fdo;
-    PXENCONS_THREAD         	Thread;
-    IO_CSQ                  	Csq;
-    LIST_ENTRY              	List;
-    KSPIN_LOCK           	Lock;
-    XENBUS_CONSOLE_INTERFACE 	ConsoleInterface;
+    PXENCONS_FDO                Fdo;
+    PXENCONS_THREAD             Thread;
+    IO_CSQ                      Csq;
+    LIST_ENTRY                  List;
+    KSPIN_LOCK                  Lock;
+    XENBUS_CONSOLE_INTERFACE    ConsoleInterface;
+    BOOLEAN                     Failed;
 };
=20
 static FORCEINLINE PVOID
@@ -78,9 +79,14 @@ StreamCsqInsertIrpEx(
 {
     BOOLEAN             ReInsert =3D (BOOLEAN)(ULONG_PTR)InsertContext;
     PXENCONS_STREAM     Stream;
+    NTSTATUS            status;
=20
     Stream =3D CONTAINING_RECORD(Csq, XENCONS_STREAM, Csq);
=20
+    status =3D STATUS_UNSUCCESSFUL;
+    if (Stream->Failed)
+        goto fail1;
+
     if (ReInsert) {
         // This only occurs if the worker thread de-queued the IRP but
         // then found the console to be blocked=2E
@@ -91,6 +97,11 @@ StreamCsqInsertIrpEx(
     }
=20
     return STATUS_SUCCESS;
+
+fail1:
+    Trace("fail1 (%08x)\n", status);
+
+    return status;
 }
=20
 IO_CSQ_REMOVE_IRP StreamCsqRemoveIrp;
@@ -206,6 +217,7 @@ StreamWorker(
     PXENCONS_STREAM         Stream =3D Context;
     PKEVENT                 Event;
     PXENBUS_CONSOLE_WAKEUP  Wakeup;
+    KIRQL                   Irql;
     NTSTATUS                status;
=20
     Trace("=3D=3D=3D=3D>\n");
@@ -344,6 +356,32 @@ fail2:
 fail1:
     Error("fail1 (%08x)\n", status);
=20
+    KeAcquireSpinLock(&Stream->Lock, &Irql);
+    Stream->Failed =3D TRUE;
+    KeReleaseSpinLock(&Stream->Lock, Irql);
+
+    for (;;) {
+        PIRP                Irp;
+        PIO_STACK_LOCATION  StackLocation;
+        UCHAR               MajorFunction;
+
+        Irp =3D IoCsqRemoveNextIrp(&Stream->Csq, NULL);
+        if (Irp =3D=3D NULL)
+            break;
+
+        StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
+        MajorFunction =3D StackLocation->MajorFunction;
+
+        Irp->IoStatus=2EInformation =3D 0;
+        Irp->IoStatus=2EStatus =3D STATUS_UNSUCCESSFUL;
+
+        Trace("FAILED (%02x:%s)\n",
+              MajorFunction,
+              MajorFunctionName(MajorFunction));
+
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+
     return status;
 }
=20
@@ -432,6 +470,8 @@ StreamDestroy(
     }
     ASSERT(IsListEmpty(&Stream->List));
=20
+    Stream->Failed =3D FALSE;
+
     RtlZeroMemory(&Stream->Csq, sizeof (IO_CSQ));
=20
     RtlZeroMemory(&Stream->List, sizeof (LIST_ENTRY));
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.379.c58580c0105e52ca.1a19c0009ea.c7699471304ba7c3=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:58:02 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:58:02 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468169.1677246 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNqfp-0002p6-SD; Mon, 02 Nov 2026 11:58:01 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468169.1677246; Mon, 02 Nov 2026 11:58:01 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNqfp-0002oy-PN; Mon, 02 Nov 2026 11:58:01 +0000
Received: by outflank-mailman (input) for mailman id 1468169;
 Mon, 02 Nov 2026 11:58:00 +0000
Received: from mx.expurgate.net ([194.145.224.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19c1f9484000403d@swg.vates.tech>)
 id 1xNqfo-0002or-RB
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:58:00 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNqfn-009ReV-Sn
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:57:59 +0100
Received: from [10.42.69.11] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19c1f9484000403d@swg.vates.tech>)
 id 6ae87ac7-2eae-0a2a0a5409dd-0a2a450bdd92-0
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:57:59 +0100
Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net)
 by tlsNG-42698a.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19c1f9484000403d@swg.vates.tech>)
 id 6ae87ac7-b7e8-0a2a450b0019-b9ff1c229377-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:57:59 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19c1f9484000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:57:57 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 188CB81D3D;
 Mon,  2 Nov 2026 12:57:57 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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:Feedback-ID"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=1piTU7sNZ0IO7/nydc03g/Mshykfgmzp+F6voW5SSNQ=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:feedback-id;
 b=Kj26lFZ6aZjyOyS2sy8TWDdA9twKUqoYRxVIw9LRexnZMUcfZ5T0iuxr3FwdqV4/eeKxGttwF
 PPvMGp7lLkKBzOjn01m1W2T1uT8zoSj85lL367Uuoj0Jf+OXYVuOV86YB1BUt++V8zv1bfv0jrn
 O4eQGE6pt1h/GdqgviUBSMLUhePhG2yZ/4P3VoQqdz8eg/D9hn2sVyEB667Xx6KiP3Xub92iUhw
 +iTwvcmFQ/kF+fX0VsbF/IN30u3xOJ6h2OJo8vKZLywF/C3Mu9cCCh3eNIuSWSyl6ShTUenlqb1
 vAaBkWqlrMguDV2nyizyPGmer2JNTbtq/K9fUWC9ZxnQ==
X-Zone-Loop: d40781f90c55c07b7cdee0c923eeb4e4c4708f285f47
x-campaign-type: default
x-transaction-id: 973d2535-6507-476e-9803-e7bd4d12394e
x-swg-uid: 01-40caa1b4-5ce6-4150-8340-71d1b5b28d9e
X-Mailer: Sweego
Message-ID:
 <1793620677.8631fc262581453bbf619ec5b2062170.1a19c1f9484000403d@vates.tech>
x-swg-bid: 1793620677.8631fc262581453bbf619ec5b2062170.1a19c1f9484000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH 1/2] frontend: Cache 0x80/0x83 inquiry overrides
Date: Mon,  2 Nov 2026 12:57:49 +0100
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.37d.8ff6e2477752e7b8.1a19c1f922b.cc044de83c2646f2=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793620677164
X-purgate-ID: tlsNG-42698a/1793620679-ABAD09EA-C500B190/0/0
X-purgate-type: clean
X-purgate-size: 6531

---=Part.37d.8ff6e2477752e7b8.1a19c1f922b.cc044de83c2646f2=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Storport uses the results of 0x80/0x83 VPD pages to identify an unique
storage unit=2E However, storage migration may cause the VDI UUID (and
thus the 0x80/0x83 inquiry values sent by sm) to change=2E If we pass on
the VPD change to Storport, then the disk will be considered as surprise
removed by Windows=2E

Instead, we must cache and use 0x80/0x83 overrides exactly once through
the entire lifetime of the frontend=2E

Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xenvbd/frontend=2Ec | 115 +++++++++++++++++++++++++-----------------
 1 file changed, 70 insertions(+), 45 deletions(-)

diff --git a/src/xenvbd/frontend=2Ec b/src/xenvbd/frontend=2Ec
index 20207ba=2E=2E038de09 100644
--- a/src/xenvbd/frontend=2Ec
+++ b/src/xenvbd/frontend=2Ec
@@ -75,6 +75,7 @@ struct _XENVBD_FRONTEND {
     XENVBD_DISKINFO             DiskInfo;
     XENVBD_PAGE                 Page80;
     XENVBD_PAGE                 Page83;
+    BOOLEAN                     InquiryInitialized;
     ULONG                       MaxQueues;
     ULONG                       NumQueues;
=20
@@ -927,44 +928,85 @@ FrontendReadDiskInfo(
 }
=20
 static FORCEINLINE VOID
-FrontendReadInquiryOverrides(
-    _Inout_ PXENVBD_FRONTEND    Frontend
+__FrontendFreePage(
+    _Inout_ PXENVBD_PAGE        Page
+    )
+{
+    if (Page->Data)
+        Base64Free(Page->Data);
+    Page->Data =3D NULL;
+    Page->Size =3D 0;
+}
+
+static FORCEINLINE BOOLEAN
+__FrontendPageEqual(
+    _In_ PXENVBD_PAGE           Page1,
+    _In_ PXENVBD_PAGE           Page2
+    )
+{
+    if (Page1->Size !=3D Page2->Size)
+        return FALSE;
+    if (Page1->Size =3D=3D 0)
+        return TRUE;
+    return RtlEqualMemory(Page1->Data, Page2->Data, Page1->Size);
+}
+
+static FORCEINLINE VOID
+__FrontendReadPage(
+    _In_ PXENVBD_FRONTEND       Frontend,
+    _In_ PCHAR                  Node,
+    _Out_ PXENVBD_PAGE          Page
     )
 {
     PCHAR                       Buffer;
     NTSTATUS                    status;
=20
+    Page->Data =3D NULL;
+    Page->Size =3D 0;
+
     status =3D XENBUS_STORE(Read,
                           &Frontend->StoreInterface,
                           NULL,
                           Frontend->BackendPath,
-                          "sm-data/scsi/0x12/0x80",
+                          Node,
                           &Buffer);
-    if (NT_SUCCESS(status)) {
-        (VOID) Base64Decode(Buffer,
-                            &Frontend->Page80=2EData,
-                            &Frontend->Page80=2ESize);
+    if (!NT_SUCCESS(status))
+        return;
=20
-        XENBUS_STORE(Free,
-                     &Frontend->StoreInterface,
-                     Buffer);
-    }
+    (VOID) Base64Decode(Buffer,
+                        &Page->Data,
+                        &Page->Size);
=20
-    status =3D XENBUS_STORE(Read,
-                          &Frontend->StoreInterface,
-                          NULL,
-                          Frontend->BackendPath,
-                          "sm-data/scsi/0x12/0x83",
-                          &Buffer);
-    if (NT_SUCCESS(status)) {
-        (VOID) Base64Decode(Buffer,
-                            &Frontend->Page83=2EData,
-                            &Frontend->Page83=2ESize);
+    XENBUS_STORE(Free,
+                 &Frontend->StoreInterface,
+                 Buffer);
+}
=20
-        XENBUS_STORE(Free,
-                     &Frontend->StoreInterface,
-                     Buffer);
+static FORCEINLINE VOID
+FrontendReadInquiryOverrides(
+    _Inout_ PXENVBD_FRONTEND    Frontend
+    )
+{
+    XENVBD_PAGE                 Page80;
+    XENVBD_PAGE                 Page83;
+
+    __FrontendReadPage(Frontend, "sm-data/scsi/0x12/0x80", &Page80);
+    __FrontendReadPage(Frontend, "sm-data/scsi/0x12/0x83", &Page83);
+
+    if (!Frontend->InquiryInitialized) {
+        Frontend->Page80 =3D Page80;
+        Frontend->Page83 =3D Page83;
+        Frontend->InquiryInitialized =3D TRUE;
+        return;
     }
+
+    if (!__FrontendPageEqual(&Frontend->Page80, &Page80) ||
+        !__FrontendPageEqual(&Frontend->Page83, &Page83))
+        Warning("Target[%d] : backend inquiry data has changed, using cac=
hed value\n",
+                Frontend->TargetId);
+
+    __FrontendFreePage(&Page80);
+    __FrontendFreePage(&Page83);
 }
=20
 //=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
@@ -1287,17 +1329,6 @@ abort:
 fail7:
     Error("Fail7\n");
     RtlZeroMemory(&Frontend->Features, sizeof(XENVBD_FEATURES));
-
-    if (Frontend->Page80=2EData)
-        Base64Free(Frontend->Page80=2EData);
-    Frontend->Page80=2EData =3D NULL;
-    Frontend->Page80=2ESize =3D 0;
-
-    if (Frontend->Page83=2EData)
-        Base64Free(Frontend->Page83=2EData);
-    Frontend->Page83=2EData =3D NULL;
-    Frontend->Page83=2ESize =3D 0;
-
     RtlZeroMemory(&Frontend->DiskInfo, sizeof(XENVBD_DISKINFO));
=20
 fail6:
@@ -1328,16 +1359,6 @@ FrontendDisconnect(
=20
     Frontend->NumQueues =3D 0;
=20
-    if (Frontend->Page80=2EData)
-        Base64Free(Frontend->Page80=2EData);
-    Frontend->Page80=2EData =3D NULL;
-    Frontend->Page80=2ESize =3D 0;
-
-    if (Frontend->Page83=2EData)
-        Base64Free(Frontend->Page83=2EData);
-    Frontend->Page83=2EData =3D NULL;
-    Frontend->Page83=2ESize =3D 0;
-
     RtlZeroMemory(&Frontend->Features, sizeof(XENVBD_FEATURES));
 }
 _IRQL_requires_(DISPATCH_LEVEL)
@@ -2000,6 +2021,10 @@ FrontendDestroy(
     RtlZeroMemory(&Frontend->DiskInfo, sizeof(XENVBD_DISKINFO));
     RtlZeroMemory(&Frontend->Caps, sizeof(XENVBD_CAPS));
=20
+    __FrontendFreePage(&Frontend->Page83);
+    __FrontendFreePage(&Frontend->Page80);
+    Frontend->InquiryInitialized =3D FALSE;
+
     ASSERT3P(Frontend->BackendPath, =3D=3D, NULL);
     ASSERT3P(Frontend->BackendWatch, =3D=3D, NULL);
=20
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.37d.8ff6e2477752e7b8.1a19c1f922b.cc044de83c2646f2=---


From win-pv-devel-bounces@lists.xenproject.org Mon Nov 02 11:59:07 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 02 Nov 2026 11:59:07 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1468170.1677250 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNqgt-0003i2-VU; Mon, 02 Nov 2026 11:59:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1468170.1677250; Mon, 02 Nov 2026 11:59:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1xNqgt-0003hv-Sz; Mon, 02 Nov 2026 11:59:07 +0000
Received: by outflank-mailman (input) for mailman id 1468170;
 Mon, 02 Nov 2026 11:59:06 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19c20973c000403d@swg.vates.tech>)
 id 1xNqgs-0003hp-KH
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 11:59:06 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1xNqgr-00GdCf-WD
 for win-pv-devel@lists.xenproject.org; Mon, 02 Nov 2026 12:59:06 +0100
Received: from [10.42.69.12] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19c20973c000403d@swg.vates.tech>)
 id 6ae87af6-8faa-0a2a0a5109dd-0a2a450c8862-34
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:59:05 +0100
Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net)
 by tlsNG-d25034.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1)
 (envelope-from
 <prod-mta-13.8631fc262581453bbf619ec5b2062170.1a19c20973c000403d@swg.vates.tech>)
 id 6ae87b09-f479-0a2a450c0019-b9ff1c239b2b-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 02 Nov 2026 12:59:05 +0100
Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr)
 (Authenticated sender:
 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e)
 by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id
 1a19c20973c000403d.001 for <win-pv-devel@lists.xenproject.org>
 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384);
 Mon, 02 Nov 2026 11:59:03 +0000
Received: from localhost.localdomain (142.220.66.37.rev.sfr.net
 [37.66.220.142]) (Authenticated sender: ngoc-tu.dinh@vates.tech)
 by mail2.vates.fr (Postfix) with ESMTPSA id 33E7B81EE6;
 Mon,  2 Nov 2026 12:59:03 +0100 (CET)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
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"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech;
 q=dns/txt; s=selector1; bh=01yOt1vRWGkcUSqEZqSuEs8o6ZMmLJvFaeRITgc2AGA=;
 h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id;
 b=sAIQ249yoItmQuiFmG2Jkm72lV2Huphj9TImrhv41jpKmuDONiUo59bCiBPvJw7vpmwrc1ceI
 yRqXQtu2IJSgC64a0IrK30qEtJOWonmFAiTS9SRHnz/e48lbHzoQ5X/AD95G16e6Ac7Og9ucLy/
 BU6Ni6RaBBk/dARfh2qsl07QBV27z4MhK5Krkxqm/sOe7pOzESpW+f0a6X9pyzCvval955xnYxO
 veY4NXSE2GSlndVG/JiKC+GBMeHuu7jYdlvOmbprKrbA3KfXEi9O6u6wCjQgbnwnVbrnKnxd29J
 0TsUZ509485ZampSFGjUi7zaflbXWdAkh78qsp/AI2uw==
X-Zone-Loop: 29bb23c0b078c426fbce2d0e458a75a225fc8c42f6d8
x-campaign-type: default
x-transaction-id: 3b74cf96-1dfa-4407-80c6-8b32a1be9884
x-swg-uid: 01-600038cd-174d-435f-b98e-beb2e188e74f
X-Mailer: Sweego
Message-ID:
 <1793620744.8631fc262581453bbf619ec5b2062170.1a19c20973c000403d@vates.tech>
x-swg-bid: 1793620744.8631fc262581453bbf619ec5b2062170.1a19c20973c000403d
Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego
x-campaign-id: default
x-client-id: 8631fc262581453bbf619ec5b2062170
X-Originating-IP: [37.26.189.201]
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh <ngoc-tu.dinh@vates.tech>
Subject: [PATCH 2/2] Use virtual-device as target ID
Date: Mon,  2 Nov 2026 12:58:59 +0100
In-Reply-To: <1793620677.8631fc262581453bbf619ec5b2062170.1a19c1f9484000403d@vates.tech>
References: <1793620677.8631fc262581453bbf619ec5b2062170.1a19c1f9484000403d@vates.tech>
MIME-Version: 1.0
X-BM-Disclaimer: Yes
Content-Type: multipart/alternative; boundary="-=Part.37e.eae2148c8b2de585.1a19c209461.d8560939d1187862=-"
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1793620743265
X-purgate-ID: tlsNG-d25034/1793620745-77CD3A5B-4D18889B/0/0
X-purgate-type: clean
X-purgate-size: 4501

---=Part.37e.eae2148c8b2de585.1a19c209461.d8560939d1187862=-
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Per blkif=2Eh, this is the only value that can be used as target ID=2E
There's no guarantee that the frontend path will equal the value found
in virtual-device=2E

Signed-off-by: Tu Dinh <ngoc-tu=2Edinh@vates=2Etech>
---
 src/xenvbd/adapter=2Ec | 52 ++++++++++++++++++++++++++++++++++++++++++++
 src/xenvbd/target=2Ec  |  7 +++---
 src/xenvbd/target=2Eh  |  1 +
 3 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/src/xenvbd/adapter=2Ec b/src/xenvbd/adapter=2Ec
index 5b787d1=2E=2E4ff4e80 100644
--- a/src/xenvbd/adapter=2Ec
+++ b/src/xenvbd/adapter=2Ec
@@ -378,6 +378,50 @@ ignore:
     return TRUE;
 }
=20
+static FORCEINLINE NTSTATUS
+__AdapterGetVirtualDevice(
+    _In_ PXENVBD_ADAPTER    Adapter,
+    _In_ PSTR               DeviceId,
+    _Out_ PULONG            VirtualDevice
+    )
+{
+    PCHAR                   Buffer;
+    CHAR                    Path[MAXNAMELEN];
+    NTSTATUS                status;
+
+    status =3D RtlStringCbPrintfA(Path,
+                                sizeof(Path),
+                                "device/vbd/%s",
+                                DeviceId);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status =3D XENBUS_STORE(Read,
+                          &Adapter->StoreInterface,
+                          NULL,
+                          Path,
+                          "virtual-device",
+                          &Buffer);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    *VirtualDevice =3D strtoul(Buffer, NULL, 10);
+
+    XENBUS_STORE(Free,
+                 &Adapter->StoreInterface,
+                 Buffer);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
 BOOLEAN
 AdapterIsTargetEmulated(
     _In_ PXENVBD_ADAPTER    Adapter,
@@ -495,6 +539,7 @@ __AdapterEnumerate(
=20
     // add new targets
     for (Index =3D 0; Devices[Index]=2EBuffer !=3D NULL; ++Index) {
+        ULONG           VirtualDevice;
         NTSTATUS        status;
=20
         Device =3D &Devices[Index];
@@ -505,8 +550,15 @@ __AdapterEnumerate(
         if (__AdapterHiddenTarget(Adapter, Device->Buffer))
             continue;
=20
+        status =3D __AdapterGetVirtualDevice(Adapter,
+                                           Device->Buffer,
+                                           &VirtualDevice);
+        if (!NT_SUCCESS(status))
+            continue;
+
         status =3D TargetCreate(Adapter,
                               Device->Buffer,
+                              VirtualDevice,
                               &Target);
         if (status =3D=3D STATUS_RETRY)
             NeedReboot =3D TRUE;
diff --git a/src/xenvbd/target=2Ec b/src/xenvbd/target=2Ec
index cfbcb02=2E=2E9b7c72b 100644
--- a/src/xenvbd/target=2Ec
+++ b/src/xenvbd/target=2Ec
@@ -1475,11 +1475,9 @@ TargetD0ToD3(
=20
 static FORCEINLINE ULONG
 __ParseVbd(
-    _In_ PSTR   DeviceIdStr
+    _In_ ULONG  DeviceId
     )
 {
-    ULONG       DeviceId =3D strtoul(DeviceIdStr, NULL, 10);
-
     ASSERT3U((DeviceId & ~((1 << 29) - 1)), =3D=3D, 0);
=20
     if (DeviceId & (1 << 28))
@@ -1504,6 +1502,7 @@ NTSTATUS
 TargetCreate(
     _In_ PXENVBD_ADAPTER    Adapter,
     _In_ PSTR               DeviceId,
+    _In_ ULONG              VirtualDevice,
     _Outptr_ PXENVBD_TARGET *_Target
     )
 {
@@ -1511,7 +1510,7 @@ TargetCreate(
     PXENVBD_TARGET          Target;
     ULONG                   TargetId;
=20
-    TargetId =3D __ParseVbd(DeviceId);
+    TargetId =3D __ParseVbd(VirtualDevice);
     if (TargetId >=3D XENVBD_MAX_TARGETS)
         return STATUS_RETRY;
=20
diff --git a/src/xenvbd/target=2Eh b/src/xenvbd/target=2Eh
index 05447ab=2E=2Ec560e91 100644
--- a/src/xenvbd/target=2Eh
+++ b/src/xenvbd/target=2Eh
@@ -45,6 +45,7 @@ extern NTSTATUS
 TargetCreate(
     _In_ PXENVBD_ADAPTER    Adapter,
     _In_ PSTR               DeviceId,
+    _In_ ULONG              VirtualDevice,
     _Outptr_ PXENVBD_TARGET *_Target
     );
=20
--=20
2=2E56=2E0=2Ewindows=2E4



-- 
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates =
solutions

web: https://vates=2Etech
---=Part.37e.eae2148c8b2de585.1a19c209461.d8560939d1187862=---


