Linux-HyperV List
 help / color / mirror / Atom feed
* [PATCH v2 0/6] Remove support for Windows Server 2012/2012R2 & Win8/Win8.1 versions of Hyper-V
@ 2026-08-05 20:37 Michael Kelley
  2026-08-05 20:37 ` [PATCH v2 1/6] Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version " Michael Kelley
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Michael Kelley @ 2026-08-05 20:37 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli, linux-hyperv; +Cc: linux-kernel

Linux code for running as a Hyper-V guest includes special cases for
running on Hyper-V in WS2012/2012R2 and Windows 8/8.1. These versions
were initially released 14 years ago, and official support ended in 2023
(unless a customer has contracted for extended security updates). Given
the release of subsequent versions with improved functionality, there's
no need to continue to support the latest Linux kernels on these versions
of Hyper-V. If someone is running Linux on one of these older Hyper-V
versions and doesn't want to upgrade, they can continue to do so as
presumably they don't want upgrade the Linux version either.

Simplify Linux code by removing special cases for running on these
old versions of Hyper-V. This includes removing the negotiation of the
VMBus protocol versions for WS2012/Win8, and the special case code based
on those VMBus protocol versions. Changes are in the core VMBus code and
several drivers for synthetic VMBus devices.

Some VMBus drivers have device-specific protocols with the Hyper-V host.
Further simplify the code by removing the use of protocol versions that
are specific to WS2012/Win8 and earlier.

Finally, the WS2012/Win8 versions of Hyper-V were the last to use
messages to deliver synthetic timer interrupts. Starting in WS2016/Win10,
stimer interrupts are delivered to their own assigned interrupt vector
(called "Direct Mode"). So remove the code for handling timer interrupts
delivered as messages. This removal has a broader benefit in removing
a key blocker to disentangling VMBus code (which handles the messages)
and stimer code, as they should be independent of each other. The
final disentangling will come as a follow-on patch set.

Testing:
* VM on local Hyper-V on up-to-date Windows 11
* Added temp debug code to suppress Direct Mode enumeration. Fallback
  to LAPIC timer worked as expected (x86/x64 only)
* Used hv_vmbus.max_version=0x30000 on the kernel boot line to simulate
  running on WS2012/Win8 Hyper-V and see the new error message output
  when VMBus can't connect
* Azure VM DC16eds v6: TDX CoCo VM with HvLite paravisor
* Azure VM DC16ads v6: SEV-SNP VM with an older paravisor
* Azure VM D16alds_v7: normal AMD x86 VM with HvLite paravisor
* Azure VM D16plds v6: normal ARM64 VM with MSFT Cobalt processor
* Not tested running in VTL2

There's no specific urgency to removing the special case code for
WS2012/Win8, so if the broader Linux kernel community surfaces
a reason why this clean-up should not be done now, we can wait.
But I think we want to eventually stop carrying around this extra
baggage, and based on discussions with the Hyper-V team within
Microsoft, we're past the point that it has any value.

Michael Kelley (6):
  Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version of
    Hyper-V
  hv_sock: Remove check for old Hyper-V hosts
  hv_netvsc: Remove GPADL teardown special case for old Hyper-V hosts
  drm_hyperv: Remove support for synth video protocol of old Hyper-V
    hosts
  scsi: storvsc: Remove support for storvsc protocol of old Hyper-V
    hosts
  clocksource: hyper-v: Remove support for stimer interrupts in message
    mode

 arch/x86/hyperv/hv_init.c                 |  17 +--
 arch/x86/kernel/cpu/mshyperv.c            |   4 +-
 drivers/clocksource/hyperv_timer.c        | 150 +++-------------------
 drivers/gpu/drm/hyperv/hyperv_drm.h       |   1 -
 drivers/gpu/drm/hyperv/hyperv_drm_proto.c |  44 ++-----
 drivers/hv/channel_mgmt.c                 |   8 +-
 drivers/hv/connection.c                   |  11 +-
 drivers/hv/hv.c                           |   4 -
 drivers/hv/hv_balloon.c                   |  36 +++---
 drivers/hv/hv_snapshot.c                  |   5 -
 drivers/hv/vmbus_drv.c                    |  10 +-
 drivers/net/hyperv/netvsc.c               |  20 +--
 drivers/scsi/storvsc_drv.c                |  53 ++------
 include/clocksource/hyperv_timer.h        |   6 -
 include/linux/hyperv.h                    |   5 +-
 net/vmw_vsock/hyperv_transport.c          |   3 -
 16 files changed, 82 insertions(+), 295 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/6] Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version of Hyper-V
  2026-08-05 20:37 [PATCH v2 0/6] Remove support for Windows Server 2012/2012R2 & Win8/Win8.1 versions of Hyper-V Michael Kelley
@ 2026-08-05 20:37 ` Michael Kelley
  2026-08-05 20:58   ` sashiko-bot
  2026-08-05 20:37 ` [PATCH v2 2/6] hv_sock: Remove check for old Hyper-V hosts Michael Kelley
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Michael Kelley @ 2026-08-05 20:37 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli, linux-hyperv; +Cc: linux-kernel

Linux code for running as a Hyper-V guest includes special cases for
running on Hyper-V in WS2012/2012R2 and Windows 8/8.1. These versions
were initially released 14 years ago, and official support ended in 2023
(unless a customer has contracted for extended security updates). Given
the release of subsequent versions with improved functionality, there's
no need to continue to support the latest Linux kernels on these versions
of Hyper-V. If someone is running Linux on one of these older Hyper-V
versions and doesn't want to upgrade, they can continue to do so as
presumably they don't want upgrade the Linux version either.

Simplify Linux code by removing special cases for running on these
old versions of Hyper-V. Remove the negotiation of the VMBus protocol
versions for WS2012/Win8, and remove special case code based on those
VMBus protocol versions. Also update the balloon and snapshot drivers
to no longer negotiate driver-specific protocol versions for these
older Hyper-V versions, and remove any related special cases.

Signed-off-by: Michael Kelley <mhklinux@outlook.com>
---
Changes in v2:
* Added error message in vmbus_connect() to indicate that running on
  an older version of Hyper-V is a possible cause of being unable to
  negotiate a compatible VMBus version [Hamza Mahfooz]
* Added a check in vmbus_initiate_unload() to catch the CONNECTING
  state. This case was previously implicitly caught by the VMBus protocol
  version check that has been removed. [Sashiko]

 drivers/hv/channel_mgmt.c |  8 +++-----
 drivers/hv/connection.c   | 11 +++++++----
 drivers/hv/hv_balloon.c   | 36 +++++++++++++++---------------------
 drivers/hv/hv_snapshot.c  |  5 -----
 include/linux/hyperv.h    |  5 ++---
 5 files changed, 27 insertions(+), 38 deletions(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 89d214dda360..a044fd3b3c4e 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -929,12 +929,10 @@ static void vmbus_unload_response(struct vmbus_channel_message_header *hdr)
 void vmbus_initiate_unload(bool crash)
 {
 	struct vmbus_channel_message_header hdr;
+	enum vmbus_connect_state old_state;
 
-	if (xchg(&vmbus_connection.conn_state, DISCONNECTED) == DISCONNECTED)
-		return;
-
-	/* Pre-Win2012R2 hosts don't support reconnect */
-	if (vmbus_proto_version < VERSION_WIN8_1)
+	old_state = xchg(&vmbus_connection.conn_state, DISCONNECTED);
+	if (old_state == DISCONNECTED || old_state == CONNECTING)
 		return;
 
 	reinit_completion(&vmbus_connection.unload_event);
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 0fd50d4cb573..1ab3581b096a 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -47,7 +47,9 @@ EXPORT_SYMBOL_GPL(vmbus_proto_version);
 
 /*
  * Table of VMBus versions listed from newest to oldest.
- * VERSION_WIN7 and VERSION_WS2008 are no longer supported in
+ * VERSION_WIN7,VERSION_WS2008, VERSION_WIN8 (which is
+ * Windows Server 2012) and VERSION_WIN8_1 (which is
+ * Windows Server 2012 R2) are no longer supported in
  * Linux guests and are not listed.
  */
 static __u32 vmbus_versions[] = {
@@ -57,9 +59,7 @@ static __u32 vmbus_versions[] = {
 	VERSION_WIN10_V5_1,
 	VERSION_WIN10_V5,
 	VERSION_WIN10_V4_1,
-	VERSION_WIN10,
-	VERSION_WIN8_1,
-	VERSION_WIN8
+	VERSION_WIN10
 };
 
 /*
@@ -304,6 +304,9 @@ int vmbus_connect(void)
 	for (i = 0; ; i++) {
 		if (i == ARRAY_SIZE(vmbus_versions)) {
 			ret = -EDOM;
+			pr_err("Hyper-V host does not support VMBus version %d.%d or higher;\n\
+		 the host may be an older version no longer supported by Linux\n",
+				vmbus_versions[i-1] >> 16, vmbus_versions[i-1] & 0xFFFF);
 			goto cleanup;
 		}
 
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 42ce27be344d..9cba97e81111 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -58,6 +58,10 @@
 #define DYNMEM_MAJOR_VERSION(Version) ((__u32)(Version) >> 16)
 #define DYNMEM_MINOR_VERSION(Version) ((__u32)(Version) & 0xff)
 
+/*
+ * VERSION_1 and VERSION_2 are retained for the historical record,
+ * but are no longer supported in Linux guests.
+ */
 enum {
 	DYNMEM_PROTOCOL_VERSION_1 = DYNMEM_MAKE_VERSION(0, 3),
 	DYNMEM_PROTOCOL_VERSION_2 = DYNMEM_MAKE_VERSION(1, 0),
@@ -65,9 +69,7 @@ enum {
 
 	DYNMEM_PROTOCOL_VERSION_WIN7 = DYNMEM_PROTOCOL_VERSION_1,
 	DYNMEM_PROTOCOL_VERSION_WIN8 = DYNMEM_PROTOCOL_VERSION_2,
-	DYNMEM_PROTOCOL_VERSION_WIN10 = DYNMEM_PROTOCOL_VERSION_3,
-
-	DYNMEM_PROTOCOL_VERSION_CURRENT = DYNMEM_PROTOCOL_VERSION_WIN10
+	DYNMEM_PROTOCOL_VERSION_WIN10 = DYNMEM_PROTOCOL_VERSION_3
 };
 
 /*
@@ -1434,19 +1436,9 @@ static void version_resp(struct hv_dynmem_device *dm,
 	version_req.version.version = dm->next_version;
 	dm->version = version_req.version.version;
 
-	/*
-	 * Set the next version to try in case current version fails.
-	 * Win7 protocol ought to be the last one to try.
-	 */
-	switch (version_req.version.version) {
-	case DYNMEM_PROTOCOL_VERSION_WIN8:
-		dm->next_version = DYNMEM_PROTOCOL_VERSION_WIN7;
-		version_req.is_last_attempt = 0;
-		break;
-	default:
-		dm->next_version = 0;
-		version_req.is_last_attempt = 1;
-	}
+	/* Set the next version to try in case current version fails. */
+	dm->next_version = 0;
+	version_req.is_last_attempt = 1;
 
 	ret = vmbus_sendpacket(dm->dev->channel, &version_req,
 				sizeof(struct dm_version_request),
@@ -1735,16 +1727,18 @@ static int balloon_connect_vsp(struct hv_device *dev)
 
 	/*
 	 * Initiate the hand shake with the host and negotiate
-	 * a version that the host can support. We start with the
-	 * highest version number and go down if the host cannot
-	 * support it.
+	 * a version that the host can support. The mechanism is in place
+	 * to start with the highest version number and go down if the host
+	 * cannot support it. But currently we only try the WIN10 version
+	 * since support for older Hyper-V versions has been removed from
+	 * Linux.
 	 */
 	memset(&version_req, 0, sizeof(struct dm_version_request));
 	version_req.hdr.type = DM_VERSION_REQUEST;
 	version_req.hdr.size = sizeof(struct dm_version_request);
 	version_req.hdr.trans_id = atomic_inc_return(&trans_id);
 	version_req.version.version = DYNMEM_PROTOCOL_VERSION_WIN10;
-	version_req.is_last_attempt = 0;
+	version_req.is_last_attempt = 1;
 	dm_device.version = version_req.version.version;
 
 	ret = vmbus_sendpacket(dev->channel, &version_req,
@@ -1964,7 +1958,7 @@ static int balloon_probe(struct hv_device *dev,
 #endif
 	dm_device.dev = dev;
 	dm_device.state = DM_INITIALIZING;
-	dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN8;
+	dm_device.next_version = 0;
 	init_completion(&dm_device.host_event);
 	init_completion(&dm_device.config_event);
 	INIT_LIST_HEAD(&dm_device.ha_region_list);
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
index 506871aeacf0..847dc69e8250 100644
--- a/drivers/hv/hv_snapshot.c
+++ b/drivers/hv/hv_snapshot.c
@@ -372,11 +372,6 @@ static void vss_on_reset(void)
 int
 hv_vss_init(struct hv_util_service *srv)
 {
-	if (vmbus_proto_version < VERSION_WIN8_1) {
-		pr_warn("Integration service 'Backup (volume snapshot)'"
-			" not supported on this host version.\n");
-		return -ENOTSUPP;
-	}
 	recv_buffer = srv->recv_buffer;
 	vss_transaction.recv_channel = srv->channel;
 	vss_transaction.recv_channel->max_pkt_size = VSS_MAX_PKT_SIZE;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index a2b484679eb4..9652083b6798 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -260,9 +260,8 @@ static inline u32 hv_get_avail_to_write_percent(
  * 5 . 2  (Windows Server 2019, RS5)
  * 5 . 3  (Windows Server 2022)
  *
- * The WS2008 and WIN7 versions are listed here for
- * completeness but are no longer supported in the
- * Linux kernel.
+ * The WS2008, WIN7, WIN8, and WIN8_1 versions are listed here for
+ * completeness but are no longer supported in the Linux kernel.
  */
 
 #define VMBUS_MAKE_VERSION(MAJ, MIN)	((((u32)MAJ) << 16) | (MIN))
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/6] hv_sock: Remove check for old Hyper-V hosts
  2026-08-05 20:37 [PATCH v2 0/6] Remove support for Windows Server 2012/2012R2 & Win8/Win8.1 versions of Hyper-V Michael Kelley
  2026-08-05 20:37 ` [PATCH v2 1/6] Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version " Michael Kelley
@ 2026-08-05 20:37 ` Michael Kelley
  2026-08-05 20:37 ` [PATCH v2 3/6] hv_netvsc: Remove GPADL teardown special case " Michael Kelley
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Michael Kelley @ 2026-08-05 20:37 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli, linux-hyperv; +Cc: linux-kernel

With the overall removal of Linux support for running on Hyper-V
hosts earlier than WS2016 and Windows 10, the check for such versions
during hv_sock initialization is no longer necessary. Remove the
check.

Signed-off-by: Michael Kelley <mhklinux@outlook.com>
---
No changes in v2.

 net/vmw_vsock/hyperv_transport.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
index 5405c2680dec..855b15971c35 100644
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -961,9 +961,6 @@ static int __init hvs_init(void)
 {
 	int ret;
 
-	if (vmbus_proto_version < VERSION_WIN10)
-		return -ENODEV;
-
 	ret = vmbus_driver_register(&hvs_drv);
 	if (ret != 0)
 		return ret;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/6] hv_netvsc: Remove GPADL teardown special case for old Hyper-V hosts
  2026-08-05 20:37 [PATCH v2 0/6] Remove support for Windows Server 2012/2012R2 & Win8/Win8.1 versions of Hyper-V Michael Kelley
  2026-08-05 20:37 ` [PATCH v2 1/6] Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version " Michael Kelley
  2026-08-05 20:37 ` [PATCH v2 2/6] hv_sock: Remove check for old Hyper-V hosts Michael Kelley
@ 2026-08-05 20:37 ` Michael Kelley
  2026-08-05 21:01   ` sashiko-bot
  2026-08-05 20:37 ` [PATCH v2 4/6] drm_hyperv: Remove support for synth video protocol of " Michael Kelley
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Michael Kelley @ 2026-08-05 20:37 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli, linux-hyperv; +Cc: linux-kernel

With the overall removal of Linux support for running on Hyper-V
hosts earlier than WS2016 and Windows 10, the special case handling of
GPADL teardown is no longer necessary. Remove it.

Signed-off-by: Michael Kelley <mhklinux@outlook.com>
---
No changes in v2.

 drivers/net/hyperv/netvsc.c | 20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 4d319c50955e..4295b96b4312 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -695,17 +695,8 @@ void netvsc_device_remove(struct hv_device *device)
 		= rtnl_dereference(net_device_ctx->nvdev);
 	int i;
 
-	/*
-	 * Revoke receive buffer. If host is pre-Win2016 then tear down
-	 * receive buffer GPADL. Do the same for send buffer.
-	 */
 	netvsc_revoke_recv_buf(device, net_device, ndev);
-	if (vmbus_proto_version < VERSION_WIN10)
-		netvsc_teardown_recv_gpadl(device, net_device, ndev);
-
 	netvsc_revoke_send_buf(device, net_device, ndev);
-	if (vmbus_proto_version < VERSION_WIN10)
-		netvsc_teardown_send_gpadl(device, net_device, ndev);
 
 	RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
 
@@ -733,14 +724,9 @@ void netvsc_device_remove(struct hv_device *device)
 	/* Now, we can close the channel safely */
 	vmbus_close(device->channel);
 
-	/*
-	 * If host is Win2016 or higher then we do the GPADL tear down
-	 * here after VMBus is closed.
-	*/
-	if (vmbus_proto_version >= VERSION_WIN10) {
-		netvsc_teardown_recv_gpadl(device, net_device, ndev);
-		netvsc_teardown_send_gpadl(device, net_device, ndev);
-	}
+	/* Must do the GPADL teardown after channel is closed */
+	netvsc_teardown_recv_gpadl(device, net_device, ndev);
+	netvsc_teardown_send_gpadl(device, net_device, ndev);
 
 	/* Release all resources */
 	free_netvsc_device_rcu(net_device);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/6] drm_hyperv: Remove support for synth video protocol of old Hyper-V hosts
  2026-08-05 20:37 [PATCH v2 0/6] Remove support for Windows Server 2012/2012R2 & Win8/Win8.1 versions of Hyper-V Michael Kelley
                   ` (2 preceding siblings ...)
  2026-08-05 20:37 ` [PATCH v2 3/6] hv_netvsc: Remove GPADL teardown special case " Michael Kelley
@ 2026-08-05 20:37 ` Michael Kelley
  2026-08-05 20:48   ` sashiko-bot
  2026-08-05 20:37 ` [PATCH v2 5/6] scsi: storvsc: Remove support for storvsc " Michael Kelley
  2026-08-05 20:37 ` [PATCH v2 6/6] clocksource: hyper-v: Remove support for stimer interrupts in message mode Michael Kelley
  5 siblings, 1 reply; 11+ messages in thread
From: Michael Kelley @ 2026-08-05 20:37 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli, linux-hyperv; +Cc: linux-kernel

With the overall removal of Linux support for running on Hyper-V
hosts earlier than WS2016 and Windows 10, it's no longer necessary
to support older synthetic video protocols. Remove the support.

Signed-off-by: Michael Kelley <mhklinux@outlook.com>
---
Changes in v2:
* Removed now unused function hv_drm_version_ge() and field
  synthvid_version. While it's posssible that these might be needed
  again if a new synthetic frame buffer protocol version is introduced,
  my sense is that this is not an area of active development on the
  Hyper-V side, so a new protocol version is less likely. The
  function/field can be added back when/if needed. [Sashiko]

 drivers/gpu/drm/hyperv/hyperv_drm.h       |  1 -
 drivers/gpu/drm/hyperv/hyperv_drm_proto.c | 44 ++++++-----------------
 2 files changed, 10 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/hyperv/hyperv_drm.h b/drivers/gpu/drm/hyperv/hyperv_drm.h
index 78136ec2c2f4..29e6f54af15f 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm.h
+++ b/drivers/gpu/drm/hyperv/hyperv_drm.h
@@ -29,7 +29,6 @@ struct hv_drm_device {
 	unsigned long fb_base;
 	unsigned long fb_size;
 	struct completion wait;
-	u32 synthvid_version;
 	u32 mmio_megabytes;
 	bool dirt_needed;
 
diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
index f0ef627b4898..1d09bba1efdd 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
+++ b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
@@ -17,7 +17,7 @@
 #define SYNTHVID_VER_GET_MAJOR(ver) (ver & 0x0000ffff)
 #define SYNTHVID_VER_GET_MINOR(ver) ((ver & 0xffff0000) >> 16)
 
-/* Support for VERSION_WIN7 is removed. #define is retained for reference. */
+/* Support for WIN7 and WIN8 is removed. #define's retained for reference. */
 #define SYNTHVID_VERSION_WIN7 SYNTHVID_VERSION(3, 0)
 #define SYNTHVID_VERSION_WIN8 SYNTHVID_VERSION(3, 2)
 #define SYNTHVID_VERSION_WIN10 SYNTHVID_VERSION(3, 5)
@@ -181,16 +181,6 @@ struct synthvid_msg {
 	};
 } __packed;
 
-static inline bool hv_drm_version_ge(u32 ver1, u32 ver2)
-{
-	if (SYNTHVID_VER_GET_MAJOR(ver1) > SYNTHVID_VER_GET_MAJOR(ver2) ||
-	    (SYNTHVID_VER_GET_MAJOR(ver1) == SYNTHVID_VER_GET_MAJOR(ver2) &&
-	     SYNTHVID_VER_GET_MINOR(ver1) >= SYNTHVID_VER_GET_MINOR(ver2)))
-		return true;
-
-	return false;
-}
-
 static inline int hv_drm_sendpacket(struct hv_device *hdev, struct synthvid_msg *msg)
 {
 	static atomic64_t request_id = ATOMIC64_INIT(0);
@@ -236,7 +226,6 @@ static int hv_drm_negotiate_version(struct hv_device *hdev, u32 ver)
 		return -ENODEV;
 	}
 
-	hv->synthvid_version = ver;
 	drm_info(dev, "Synthvid Version major %d, minor %d\n",
 		 SYNTHVID_VER_GET_MAJOR(ver), SYNTHVID_VER_GET_MINOR(ver));
 
@@ -557,23 +546,12 @@ int hv_drm_connect_vsp(struct hv_device *hdev)
 		return ret;
 	}
 
-	/* Negotiate the protocol version with host */
-	switch (vmbus_proto_version) {
-	case VERSION_WIN10:
-	case VERSION_WIN10_V5:
-		ret = hv_drm_negotiate_version(hdev, SYNTHVID_VERSION_WIN10);
-		if (!ret)
-			break;
-		fallthrough;
-	case VERSION_WIN8:
-	case VERSION_WIN8_1:
-		ret = hv_drm_negotiate_version(hdev, SYNTHVID_VERSION_WIN8);
-		break;
-	default:
-		ret = hv_drm_negotiate_version(hdev, SYNTHVID_VERSION_WIN10);
-		break;
-	}
-
+	/*
+	 * Negotiate the protocol version with host. Since support for hosts
+	 * older than WIN10 has been removed from Linux, only negotiate the
+	 * WIN10 version.
+	 */
+	ret = hv_drm_negotiate_version(hdev, SYNTHVID_VERSION_WIN10);
 	if (ret) {
 		drm_err(dev, "Synthetic video device version not accepted %d\n", ret);
 		goto error;
@@ -581,11 +559,9 @@ int hv_drm_connect_vsp(struct hv_device *hdev)
 
 	hv->screen_depth = SYNTHVID_DEPTH_WIN8;
 
-	if (hv_drm_version_ge(hv->synthvid_version, SYNTHVID_VERSION_WIN10)) {
-		ret = hv_drm_get_supported_resolution(hdev);
-		if (ret)
-			drm_err(dev, "Failed to get supported resolution from host, use default\n");
-	}
+	ret = hv_drm_get_supported_resolution(hdev);
+	if (ret)
+		drm_err(dev, "Failed to get supported resolution from host, use default\n");
 
 	if (!hv->screen_width_max) {
 		hv->screen_width_max = SYNTHVID_WIDTH_WIN8;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/6] scsi: storvsc: Remove support for storvsc protocol of old Hyper-V hosts
  2026-08-05 20:37 [PATCH v2 0/6] Remove support for Windows Server 2012/2012R2 & Win8/Win8.1 versions of Hyper-V Michael Kelley
                   ` (3 preceding siblings ...)
  2026-08-05 20:37 ` [PATCH v2 4/6] drm_hyperv: Remove support for synth video protocol of " Michael Kelley
@ 2026-08-05 20:37 ` Michael Kelley
  2026-08-05 20:37 ` [PATCH v2 6/6] clocksource: hyper-v: Remove support for stimer interrupts in message mode Michael Kelley
  5 siblings, 0 replies; 11+ messages in thread
From: Michael Kelley @ 2026-08-05 20:37 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli, linux-hyperv; +Cc: linux-kernel

With the overall removal of Linux support for running on Hyper-V
hosts earlier than WS2016 and Windows 10, it's no longer necessary
to support older storvsc protocols. Remove the support and associated
special case code. However, support for the protocol for Windows
Server 2012R2 and Win8.1 (protocol version 6.0) is *not* removed
because it is activiely used by HvLite in the paravisor for Azure VMs.

Signed-off-by: Michael Kelley <mhklinux@outlook.com>
---
No changes in v2.

 drivers/scsi/storvsc_drv.c | 53 +++++++-------------------------------
 1 file changed, 10 insertions(+), 43 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 571ea549152b..095fce47c5f1 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -47,9 +47,15 @@
  * V1 RC < 2008/1/31: 1.0
  * V1 RC > 2008/1/31:  2.0
  * Win7: 4.2
- * Win8: 5.1
- * Win8.1: 6.0
- * Win10: 6.2
+ * Win8/WS2012: 5.1
+ * Win8.1/WS2012R2: 6.0 (also for HvLite paravisor in Azure)
+ * Win10/WS2016: 6.2
+ *
+ * Protocol versions earlier than Win8.1 are no longer supported since
+ * Win8.1/WS2012R2 and earlier hosts are no longer supported by Linux.
+ * But protocol version 6.0 is retained since it is used by the HvLite
+ * paravisor in Azure. The #define's for the earlier versions remain
+ * for the historical record.
  */
 
 #define VMSTOR_PROTO_VERSION(MAJOR_, MINOR_)	((((MAJOR_) & 0xff) << 8) | \
@@ -218,7 +224,6 @@ struct vmscsi_request {
 static const int protocol_version[] = {
 		VMSTOR_PROTO_VERSION_WIN10,
 		VMSTOR_PROTO_VERSION_WIN8_1,
-		VMSTOR_PROTO_VERSION_WIN8,
 };
 
 
@@ -1601,13 +1606,12 @@ static int storvsc_sdev_configure(struct scsi_device *sdevice,
 	sdevice->no_write_same = 1;
 
 	/*
-	 * If the host is WIN8 or WIN8 R2, claim conformance to SPC-3
+	 * If the host is WIN8 R2, claim conformance to SPC-3
 	 * if the device is a MSFT virtual device.  If the host is
 	 * WIN10 or newer, allow write_same.
 	 */
 	if (!strncmp(sdevice->vendor, "Msft", 4)) {
 		switch (vmstor_proto_version) {
-		case VMSTOR_PROTO_VERSION_WIN8:
 		case VMSTOR_PROTO_VERSION_WIN8_1:
 			sdevice->scsi_level = SCSI_SPC_3;
 			break;
@@ -1703,28 +1707,6 @@ static enum scsi_timeout_action storvsc_eh_timed_out(struct scsi_cmnd *scmnd)
 	return SCSI_EH_RESET_TIMER;
 }
 
-static bool storvsc_scsi_cmd_ok(struct scsi_cmnd *scmnd)
-{
-	bool allowed = true;
-	u8 scsi_op = scmnd->cmnd[0];
-
-	switch (scsi_op) {
-	/* the host does not handle WRITE_SAME, log accident usage */
-	case WRITE_SAME:
-	/*
-	 * smartd sends this command and the host does not handle
-	 * this. So, don't send it.
-	 */
-	case SET_WINDOW:
-		set_host_byte(scmnd, DID_ERROR);
-		allowed = false;
-		break;
-	default:
-		break;
-	}
-	return allowed;
-}
-
 static enum scsi_qc_status storvsc_queuecommand(struct Scsi_Host *host,
 						struct scsi_cmnd *scmnd)
 {
@@ -1738,21 +1720,6 @@ static enum scsi_qc_status storvsc_queuecommand(struct Scsi_Host *host,
 	u32 payload_sz;
 	u32 length;
 
-	if (vmstor_proto_version <= VMSTOR_PROTO_VERSION_WIN8) {
-		/*
-		 * On legacy hosts filter unimplemented commands.
-		 * Future hosts are expected to correctly handle
-		 * unsupported commands. Furthermore, it is
-		 * possible that some of the currently
-		 * unsupported commands maybe supported in
-		 * future versions of the host.
-		 */
-		if (!storvsc_scsi_cmd_ok(scmnd)) {
-			scsi_done(scmnd);
-			return 0;
-		}
-	}
-
 	/* Setup the cmd request */
 	cmd_request->cmd = scmnd;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 6/6] clocksource: hyper-v: Remove support for stimer interrupts in message mode
  2026-08-05 20:37 [PATCH v2 0/6] Remove support for Windows Server 2012/2012R2 & Win8/Win8.1 versions of Hyper-V Michael Kelley
                   ` (4 preceding siblings ...)
  2026-08-05 20:37 ` [PATCH v2 5/6] scsi: storvsc: Remove support for storvsc " Michael Kelley
@ 2026-08-05 20:37 ` Michael Kelley
  2026-08-05 21:04   ` sashiko-bot
  5 siblings, 1 reply; 11+ messages in thread
From: Michael Kelley @ 2026-08-05 20:37 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, longli, linux-hyperv; +Cc: linux-kernel

In Hyper-V versions prior to WS2016/Win10, Hyper-V synthetic timers
interrupt the guest by delivering a message that is initially handled
by the Linux VMBus driver. Starting with WS2016/Win10, Hyper-V can
deliver stimer interrupts directly to an assigned interrupt vector
without involving the VMBus driver. This is called "Direct Mode".

With the overall removal of Linux support for running on Hyper-V
hosts earlier than WS2016 and Windows 10, it's no longer necessary
to support the legacy message-based delivery. Remove that delivery
mechanism and always use Direct Mode. If for some reason, the
Hyper-V host does not enumerate Direct Mode, output an error
message but continue to run using the LAPIC timer instead of an
stimer.

With these changes, the VMBus driver no longer calls the stimer
interrupt service routine. This removal has a broader benefit in
unblocking the disentangling of VMBus code and stimer code, as
they should be independent of each other. The final disentangling
will come as a follow-on patch set.

Signed-off-by: Michael Kelley <mhklinux@outlook.com>
---
No changes in v2.

 arch/x86/hyperv/hv_init.c          |  17 ++--
 arch/x86/kernel/cpu/mshyperv.c     |   4 +-
 drivers/clocksource/hyperv_timer.c | 150 ++++-------------------------
 drivers/hv/hv.c                    |   4 -
 drivers/hv/vmbus_drv.c             |  10 +-
 include/clocksource/hyperv_timer.h |   6 --
 6 files changed, 32 insertions(+), 159 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 55a8b6de2865..0b4a1c0b0b16 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -171,8 +171,7 @@ static int hv_cpu_init(unsigned int cpu)
 	}
 
 	/* Allow Hyper-V stimer vector to be injected from Hypervisor. */
-	if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE)
-		apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, true);
+	apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, true);
 
 	return hyperv_init_ghcb();
 }
@@ -281,8 +280,7 @@ static int hv_cpu_die(unsigned int cpu)
 		*ghcb_va = NULL;
 	}
 
-	if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE)
-		apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, false);
+	apic_update_vector(cpu, HYPERV_STIMER0_VECTOR, false);
 
 	hv_common_cpu_die(cpu);
 
@@ -425,15 +423,18 @@ static void (* __initdata old_setup_percpu_clockev)(void);
 
 static void __init hv_stimer_setup_percpu_clockev(void)
 {
+	int ret;
+
 	/*
-	 * Ignore any errors in setting up stimer clockevents
+	 * Continue afters errors in setting up stimer clockevents
 	 * as we can run with the LAPIC timer as a fallback.
 	 */
-	(void)hv_stimer_alloc(false);
+	ret = hv_stimer_alloc(false);
+	if (ret)
+		pr_warn("stimer setup failed with error %d\n", ret);
 
 	/*
-	 * Still register the LAPIC timer, because the direct-mode STIMER is
-	 * not supported by old versions of Hyper-V. This also allows users
+	 * Still register the LAPIC timer to allows users
 	 * to switch to LAPIC timer via /sys, if they want to.
 	 */
 	if (old_setup_percpu_clockev)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 185d4f677ec0..f62319b73c20 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -716,9 +716,7 @@ static void __init ms_hyperv_init_platform(void)
 	}
 
 	/* Install system interrupt handler for stimer0 */
-	if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) {
-		sysvec_install(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0);
-	}
+	sysvec_install(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0);
 
 # ifdef CONFIG_SMP
 	smp_ops.smp_prepare_boot_cpu = hv_smp_prepare_boot_cpu;
diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index df567795d175..dddfff458ebf 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -31,44 +31,20 @@ static struct clock_event_device __percpu *hv_clock_event;
 /* Note: offset can hold negative values after hibernation. */
 static u64 hv_sched_clock_offset __read_mostly;
 
-/*
- * If false, we're using the old mechanism for stimer0 interrupts
- * where it sends a VMbus message when it expires. The old
- * mechanism is used when running on older versions of Hyper-V
- * that don't support Direct Mode. While Hyper-V provides
- * four stimer's per CPU, Linux uses only stimer0.
- *
- * Because Direct Mode does not require processing a VMbus
- * message, stimer interrupts can be enabled earlier in the
- * process of booting a CPU, and consistent with when timer
- * interrupts are enabled for other clocksource drivers.
- * However, for legacy versions of Hyper-V when Direct Mode
- * is not enabled, setting up stimer interrupts must be
- * delayed until VMbus is initialized and can process the
- * interrupt message.
- */
-static bool direct_mode_enabled;
-
 static int stimer0_irq = -1;
-static int stimer0_message_sint;
 static __maybe_unused DEFINE_PER_CPU(long, stimer0_evt);
 
-/*
- * Common code for stimer0 interrupts coming via Direct Mode or
- * as a VMbus message.
- */
-void hv_stimer0_isr(void)
+static void hv_stimer0_isr(void)
 {
 	struct clock_event_device *ce;
 
 	ce = this_cpu_ptr(hv_clock_event);
 	ce->event_handler(ce);
 }
-EXPORT_SYMBOL_GPL(hv_stimer0_isr);
 
 /*
  * stimer0 interrupt handler for architectures that support
- * per-cpu interrupts, which also implies Direct Mode.
+ * per-cpu interrupts
  */
 static irqreturn_t __maybe_unused hv_stimer0_percpu_isr(int irq, void *dev_id)
 {
@@ -91,7 +67,7 @@ static int hv_ce_shutdown(struct clock_event_device *evt)
 {
 	hv_set_msr(HV_MSR_STIMER0_COUNT, 0);
 	hv_set_msr(HV_MSR_STIMER0_CONFIG, 0);
-	if (direct_mode_enabled && stimer0_irq >= 0)
+	if (stimer0_irq >= 0)
 		disable_percpu_irq(stimer0_irq);
 
 	return 0;
@@ -104,23 +80,16 @@ static int hv_ce_set_oneshot(struct clock_event_device *evt)
 	timer_cfg.as_uint64 = 0;
 	timer_cfg.enable = 1;
 	timer_cfg.auto_enable = 1;
-	if (direct_mode_enabled) {
-		/*
-		 * When it expires, the timer will directly interrupt
-		 * on the specified hardware vector/IRQ.
-		 */
-		timer_cfg.direct_mode = 1;
-		timer_cfg.apic_vector = HYPERV_STIMER0_VECTOR;
-		if (stimer0_irq >= 0)
-			enable_percpu_irq(stimer0_irq, IRQ_TYPE_NONE);
-	} else {
-		/*
-		 * When it expires, the timer will generate a VMbus message,
-		 * to be handled by the normal VMbus interrupt handler.
-		 */
-		timer_cfg.direct_mode = 0;
-		timer_cfg.sintx = stimer0_message_sint;
-	}
+
+	/*
+	 * When it expires, the timer will directly interrupt
+	 * on the specified hardware vector/IRQ.
+	 */
+	timer_cfg.direct_mode = 1;
+	timer_cfg.apic_vector = HYPERV_STIMER0_VECTOR;
+	if (stimer0_irq >= 0)
+		enable_percpu_irq(stimer0_irq, IRQ_TYPE_NONE);
+
 	hv_set_msr(HV_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);
 	return 0;
 }
@@ -175,25 +144,8 @@ int hv_stimer_cleanup(unsigned int cpu)
 	if (!hv_clock_event)
 		return 0;
 
-	/*
-	 * In the legacy case where Direct Mode is not enabled
-	 * (which can only be on x86/64), stimer cleanup happens
-	 * relatively early in the CPU offlining process. We
-	 * must unbind the stimer-based clockevent device so
-	 * that the LAPIC timer can take over until clockevents
-	 * are no longer needed in the offlining process. Note
-	 * that clockevents_unbind_device() eventually calls
-	 * hv_ce_shutdown().
-	 *
-	 * The unbind should not be done when Direct Mode is
-	 * enabled because we may be on an architecture where
-	 * there are no other clockevent devices to fallback to.
-	 */
 	ce = per_cpu_ptr(hv_clock_event, cpu);
-	if (direct_mode_enabled)
-		hv_ce_shutdown(ce);
-	else
-		clockevents_unbind_device(ce, cpu);
+	hv_ce_shutdown(ce);
 
 	return 0;
 }
@@ -268,23 +220,14 @@ int hv_stimer_alloc(bool have_percpu_irqs)
 	 * Hyper-V on x86.  In that case, return as error as Linux will use a
 	 * clockevent based on emulated LAPIC timer hardware.
 	 */
-	if (!(ms_hyperv.features & HV_MSR_SYNTIMER_AVAILABLE))
+	if (!(ms_hyperv.features & HV_MSR_SYNTIMER_AVAILABLE) ||
+	    !(ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE))
 		return -EINVAL;
 
 	hv_clock_event = alloc_percpu(struct clock_event_device);
 	if (!hv_clock_event)
 		return -ENOMEM;
 
-	direct_mode_enabled = ms_hyperv.misc_features &
-			HV_STIMER_DIRECT_MODE_AVAILABLE;
-
-	/*
-	 * If Direct Mode isn't enabled, the remainder of the initialization
-	 * is done later by hv_stimer_legacy_init()
-	 */
-	if (!direct_mode_enabled)
-		return 0;
-
 	if (have_percpu_irqs) {
 		ret = hv_setup_stimer0_irq();
 		if (ret)
@@ -293,11 +236,6 @@ int hv_stimer_alloc(bool have_percpu_irqs)
 		hv_setup_stimer0_handler(hv_stimer0_isr);
 	}
 
-	/*
-	 * Since we are in Direct Mode, stimer initialization
-	 * can be done now with a CPUHP value in the same range
-	 * as other clockevent devices.
-	 */
 	ret = cpuhp_setup_state(CPUHP_AP_HYPERV_TIMER_STARTING,
 			"clockevents/hyperv/stimer:starting",
 			hv_stimer_init, hv_stimer_cleanup);
@@ -314,67 +252,19 @@ int hv_stimer_alloc(bool have_percpu_irqs)
 }
 EXPORT_SYMBOL_GPL(hv_stimer_alloc);
 
-/*
- * hv_stimer_legacy_init -- Called from the VMbus driver to handle
- * the case when Direct Mode is not enabled, and the stimer
- * must be initialized late in the CPU onlining process.
- *
- */
-void hv_stimer_legacy_init(unsigned int cpu, int sint)
-{
-	if (direct_mode_enabled)
-		return;
-
-	/*
-	 * This function gets called by each vCPU, so setting the
-	 * global stimer_message_sint value each time is conceptually
-	 * not ideal, but the value passed in is always the same and
-	 * it avoids introducing yet another interface into this
-	 * clocksource driver just to set the sint in the legacy case.
-	 */
-	stimer0_message_sint = sint;
-	(void)hv_stimer_init(cpu);
-}
-EXPORT_SYMBOL_GPL(hv_stimer_legacy_init);
-
-/*
- * hv_stimer_legacy_cleanup -- Called from the VMbus driver to
- * handle the case when Direct Mode is not enabled, and the
- * stimer must be cleaned up early in the CPU offlining
- * process.
- */
-void hv_stimer_legacy_cleanup(unsigned int cpu)
-{
-	if (direct_mode_enabled)
-		return;
-	(void)hv_stimer_cleanup(cpu);
-}
-EXPORT_SYMBOL_GPL(hv_stimer_legacy_cleanup);
-
 /*
  * Do a global cleanup of clockevents for the cases of kexec and
  * vmbus exit
  */
 void hv_stimer_global_cleanup(void)
 {
-	int	cpu;
-
-	/*
-	 * hv_stime_legacy_cleanup() will stop the stimer if Direct
-	 * Mode is not enabled, and fallback to the LAPIC timer.
-	 */
-	for_each_present_cpu(cpu) {
-		hv_stimer_legacy_cleanup(cpu);
-	}
-
 	if (!hv_clock_event)
 		return;
 
-	if (direct_mode_enabled) {
-		cpuhp_remove_state(CPUHP_AP_HYPERV_TIMER_STARTING);
-		hv_remove_stimer0_irq();
-		stimer0_irq = -1;
-	}
+	cpuhp_remove_state(CPUHP_AP_HYPERV_TIMER_STARTING);
+	hv_remove_stimer0_irq();
+	stimer0_irq = -1;
+
 	free_percpu(hv_clock_event);
 	hv_clock_event = NULL;
 
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index ef4b1b03395d..fe50090dcc01 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -399,8 +399,6 @@ int hv_synic_init(unsigned int cpu)
 	else
 		hv_hyp_synic_enable_interrupts();
 
-	hv_stimer_legacy_init(cpu, VMBUS_MESSAGE_SINT);
-
 	return 0;
 }
 
@@ -630,8 +628,6 @@ int hv_synic_cleanup(unsigned int cpu)
 		return -EBUSY;
 
 always_cleanup:
-	hv_stimer_legacy_cleanup(cpu);
-
 	/*
 	 * First, disable the event and message pages
 	 * used for communicating with the host, and then
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 6824bd7cb3c4..e19ec73b0187 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1320,14 +1320,8 @@ static void vmbus_message_sched(struct hv_per_cpu_context *hv_cpu, void *message
 	msg = (struct hv_message *)message_page_addr + VMBUS_MESSAGE_SINT;
 
 	/* Check if there are actual msgs to be processed */
-	if (msg->header.message_type != HVMSG_NONE) {
-		if (msg->header.message_type == HVMSG_TIMER_EXPIRED) {
-			hv_stimer0_isr();
-			vmbus_signal_eom(msg, HVMSG_TIMER_EXPIRED);
-		} else {
-			tasklet_schedule(&hv_cpu->msg_dpc);
-		}
-	}
+	if (msg->header.message_type != HVMSG_NONE)
+		tasklet_schedule(&hv_cpu->msg_dpc);
 }
 
 static void __vmbus_isr(void)
diff --git a/include/clocksource/hyperv_timer.h b/include/clocksource/hyperv_timer.h
index d48dd4176fd3..8d3befb7e667 100644
--- a/include/clocksource/hyperv_timer.h
+++ b/include/clocksource/hyperv_timer.h
@@ -27,10 +27,7 @@
 /* Routines called by the VMbus driver */
 extern int hv_stimer_alloc(bool have_percpu_irqs);
 extern int hv_stimer_cleanup(unsigned int cpu);
-extern void hv_stimer_legacy_init(unsigned int cpu, int sint);
-extern void hv_stimer_legacy_cleanup(unsigned int cpu);
 extern void hv_stimer_global_cleanup(void);
-extern void hv_stimer0_isr(void);
 
 extern void hv_init_clocksource(void);
 extern void hv_remap_tsc_clocksource(void);
@@ -107,10 +104,7 @@ hv_read_tsc_page_tsc(const struct ms_hyperv_tsc_page *tsc_pg, u64 *cur_tsc, u64
 }
 
 static inline int hv_stimer_cleanup(unsigned int cpu) { return 0; }
-static inline void hv_stimer_legacy_init(unsigned int cpu, int sint) {}
-static inline void hv_stimer_legacy_cleanup(unsigned int cpu) {}
 static inline void hv_stimer_global_cleanup(void) {}
-static inline void hv_stimer0_isr(void) {}
 
 #endif /* CONFIG_HYPERV_TIMER */
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 4/6] drm_hyperv: Remove support for synth video protocol of old Hyper-V hosts
  2026-08-05 20:37 ` [PATCH v2 4/6] drm_hyperv: Remove support for synth video protocol of " Michael Kelley
@ 2026-08-05 20:48   ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-05 20:48 UTC (permalink / raw)
  To: Michael Kelley; +Cc: linux-hyperv

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing `reinit_completion()` and lack of transaction ID or message type verification causes data races and state machine corruption when VMBus requests time out and receive late responses.
--

--- Patch [4]: [PATCH v2 4/6] drm_hyperv: Remove support for synth video protocol of old Hyper-V hosts ---
commit d7a97b3cab0a3a58ec215d4c2c173f39a5e2648a
Author: Michael Kelley <mhkelley58@gmail.com>

drm_hyperv: Remove support for synth video protocol of old Hyper-V hosts

This commit removes support for synthetic video protocols from Hyper-V
hosts older than Windows 10. It replaces the version negotiation loop
with a single negotiation for the WIN10 version.

> diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
> index f0ef627b4898a..1d09bba1efdd8 100644
> --- a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
> +++ b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c
[ ... ]
> @@ -581,11 +559,9 @@ int hv_drm_connect_vsp(struct hv_device *hdev)
>  
>  	hv->screen_depth = SYNTHVID_DEPTH_WIN8;
>  
> -	if (hv_drm_version_ge(hv->synthvid_version, SYNTHVID_VERSION_WIN10)) {
> -		ret = hv_drm_get_supported_resolution(hdev);
> -		if (ret)
> -			drm_err(dev, "Failed to get supported resolution from host, use default\n");
> -	}
> +	ret = hv_drm_get_supported_resolution(hdev);
> +	if (ret)
> +		drm_err(dev, "Failed to get supported resolution from host, use default\n");

[Severity: High]
This is a pre-existing issue, but if hv_drm_get_supported_resolution() times
out here, is it safe to proceed and ignore the error?

hv_drm_get_supported_resolution() issues a request via hv->init_buf and waits
using wait_for_completion_timeout(&hv->wait, ...). If a timeout occurs, the
error is logged but the driver initialization continues.

Later, if another VMBus request is made using the same shared hv->init_buf
(such as in hv_drm_update_vram_location()), a concurrently arriving late
response to the original resolution query could cause a data race:

hv_drm_receive_sub() would overwrite hv->init_buf via memcpy() while the new
request is being built, corrupting the outgoing message. It also signals
complete(&hv->wait), which could prematurely wake up the new request's wait
loop, falsely accepting the old response since transaction IDs aren't verified.

Does the driver need to reinitialize completions or discard late responses
after a timeout to prevent this state machine corruption?

>  
>  	if (!hv->screen_width_max) {
>  		hv->screen_width_max = SYNTHVID_WIDTH_WIN8;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260805203751.2678-1-mhklinux@outlook.com?part=4

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 1/6] Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version of Hyper-V
  2026-08-05 20:37 ` [PATCH v2 1/6] Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version " Michael Kelley
@ 2026-08-05 20:58   ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-05 20:58 UTC (permalink / raw)
  To: Michael Kelley; +Cc: linux-hyperv

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

New issues:
- [Low] Unreachable version negotiation fallback logic left in hv_balloon.c.
- [Low] Embedded newline and multi-line string literal continuation breaks kernel log formatting.
- [Low] The patch series missed removing legacy VMBus version checks for VERSION_WIN8 and VERSION_WIN8_1 in other Hyper-V subsystem drivers.

Pre-existing issues:
- [High] The error path in vmbus_connect() and vmbus_exit() bypasses sending the VMBus disconnect message, risking guest memory corruption.
- [High] The error paths in balloon_probe() and balloon_resume() fail to cancel scheduled work items, leading to use-after-free.
--

--- Patch [1]: [PATCH v2 1/6] Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version of Hyper-V ---
commit 764adf4bdf08e43be943c35b8558657a532f1362
Author: Michael Kelley <mhkelley58@gmail.com>
Subject: Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version of Hyper-V

This commit simplifies Linux code by removing special cases and VMBus
protocol version negotiations for running on older versions of Hyper-V
(WS2012/2012R2 and Windows 8/8.1), as their official support ended.

Note: The format of this report is altered due to recitation restrictions.
The original patch code is not quoted directly, but rather a free-form summary
of the issues is provided without inline quoting.

[Severity: Low]
In drivers/hv/hv_balloon.c, within the version_resp() function, the patch
hardcodes dm->next_version to 0. Is it necessary to leave the check "if
(dm->next_version == 0) goto version_error;" and the subsequent version
request packet sending logic intact? Since the downgrade path is removed, this
makes the remainder of the function mathematically unreachable dead code.

[Severity: Low]
In drivers/hv/connection.c, within the vmbus_connect() function, the patch
adds a pr_err() call for unsupported VMBus versions. Does the embedded
newline and multi-line string literal continuation break kernel log
formatting? This can cause the second line to lack a severity prefix and
interleave with other logs.

[Severity: High]
This is a pre-existing issue, but in drivers/hv/connection.c during the
vmbus_connect() error path (cleanup label), the vmbus_connection.conn_state
is explicitly set to DISCONNECTED before calling vmbus_disconnect(). 

In drivers/hv/channel_mgmt.c:vmbus_initiate_unload(), the code returns early
if the old state is DISCONNECTED or CONNECTING, thereby skipping the vital
UNLOAD message.

Can this bypass of the VMBus disconnect message cause guest memory corruption?
Since vmbus_disconnect() frees int_page and monitor_pages without the host
being notified of the teardown, the host might continue to DMA incoming
messages to these freed guest physical pages.

[Severity: High]
This is a pre-existing issue, but in drivers/hv/hv_balloon.c:balloon_probe(),
if the kthread_run() fails, the probe function jumps to the probe_error label.
This cleans up the VMBus channel but fails to call cancel_work_sync(). 

Since the host can send a DM_BALLOON_REQUEST which queues balloon_wrk right
after balloon_connect_vsp() finishes, can these orphaned background work
items execute later and dereference the freed device, leading to a
use-after-free?

[Severity: Low]
The patch series removed legacy VMBus version checks in the core, but did it
miss removing them in other Hyper-V subsystem drivers? 

Drivers like drivers/gpu/drm/hyperv/hyperv_drm_proto.c (in
hv_drm_connect_vsp()) and drivers/scsi/storvsc_drv.c (in
storvsc_sdev_configure()) still contain switch cases for VERSION_WIN8 and
VERSION_WIN8_1 (or VMSTOR_PROTO_VERSION_WIN8). Since vmbus_connect() now
rejects hosts not supporting at least VERSION_WIN10, isn't this leftover
dead code?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260805203751.2678-1-mhklinux@outlook.com?part=1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/6] hv_netvsc: Remove GPADL teardown special case for old Hyper-V hosts
  2026-08-05 20:37 ` [PATCH v2 3/6] hv_netvsc: Remove GPADL teardown special case " Michael Kelley
@ 2026-08-05 21:01   ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-05 21:01 UTC (permalink / raw)
  To: Michael Kelley; +Cc: linux-hyperv

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [Critical] vmbus_teardown_gpadl masks vmbus_post_msg failures, leading to Use-After-Free/Memory Corruption in guest.
- [High] Missing synchronization between `netvsc_device_remove` and concurrent TX path, leading to use-after-free or NULL pointer dereference in the VMBus ring buffer.
--

--- Patch [3]: [PATCH v2 3/6] hv_netvsc: Remove GPADL teardown special case for old Hyper-V hosts ---
commit 25bcea31eec6bb56b8730b7c31834e06d41d6a61
Author: Michael Kelley <mhkelley58@gmail.com>

hv_netvsc: Remove GPADL teardown special case for old Hyper-V hosts

This commit removes the special case handling of GPADL teardown for
Hyper-V hosts earlier than Windows Server 2016 and Windows 10. The
receive and send GPADL teardowns are now always performed after the
VMBus channel is closed.

> diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
> index 4d319c50955ed..4295b96b43127 100644
> --- a/drivers/net/hyperv/netvsc.c
> +++ b/drivers/net/hyperv/netvsc.c
> @@ -695,17 +695,8 @@ void netvsc_device_remove(struct hv_device *device)
>  		= rtnl_dereference(net_device_ctx->nvdev);
>  	int i;
>  
> -	/*
> -	 * Revoke receive buffer. If host is pre-Win2016 then tear down
> -	 * receive buffer GPADL. Do the same for send buffer.
> -	 */
>  	netvsc_revoke_recv_buf(device, net_device, ndev);
> -	if (vmbus_proto_version < VERSION_WIN10)
> -		netvsc_teardown_recv_gpadl(device, net_device, ndev);
> -
>  	netvsc_revoke_send_buf(device, net_device, ndev);
> -	if (vmbus_proto_version < VERSION_WIN10)
> -		netvsc_teardown_send_gpadl(device, net_device, ndev);
>  
>  	RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
>  

[ ... ]

> @@ -733,14 +724,9 @@ void netvsc_device_remove(struct hv_device *device)
>  	/* Now, we can close the channel safely */
>  	vmbus_close(device->channel);

[Severity: High]
This isn't a bug introduced by this patch, but is it possible for a 
concurrent TX path to race here and cause a use-after-free or NULL 
pointer dereference?

In drivers/net/hyperv/netvsc_drv.c:netvsc_remove(), 
rndis_filter_device_remove() is called before unregister_netdevice(),
which stops the TX queues:

netvsc_remove() {
	if (nvdev)
		rndis_filter_device_remove(dev, nvdev);
	
	unregister_netdevice(net);
}

When netvsc_device_remove() (called from rndis_filter_device_remove) 
clears the net_device_ctx->nvdev pointer and immediately calls 
vmbus_close(), it doesn't wait for concurrent RCU readers like 
netvsc_start_xmit() to finish.

If a concurrent TX thread has already read the pointer, couldn't it
proceed to write to the VMBus ring buffer, which has just been freed
and unmapped by vmbus_close()?

> -	/*
> -	 * If host is Win2016 or higher then we do the GPADL tear down
> -	 * here after VMBus is closed.
> -	*/
> -	if (vmbus_proto_version >= VERSION_WIN10) {
> -		netvsc_teardown_recv_gpadl(device, net_device, ndev);
> -		netvsc_teardown_send_gpadl(device, net_device, ndev);
> -	}
> +	/* Must do the GPADL teardown after channel is closed */
> +	netvsc_teardown_recv_gpadl(device, net_device, ndev);

[Severity: Critical]
This is a pre-existing issue, but does this teardown sequence handle 
vmbus_post_msg() failures correctly?

Looking at drivers/hv/channel.c:vmbus_teardown_gpadl(), it appears to
mask the failure code for non-confidential VMs:

vmbus_teardown_gpadl() {
post_msg_err:
	/* ... */
	if (gpadl->decrypted)
		ret = set_memory_encrypted((unsigned long)gpadl->buffer,
					PFN_UP(gpadl->size));
	else
		ret = 0;
}

If vmbus_post_msg() fails (e.g., returning -ENOBUFS), this overwrites 
the error with 0. The caller, netvsc_teardown_recv_gpadl(), assumes 
a return value of 0 means the host successfully tore down the GPADL:

netvsc_teardown_recv_gpadl() {
	if (net_device->recv_buf_gpadl_handle.gpadl_handle) {
		ret = vmbus_teardown_gpadl(device->channel,
					   &net_device->recv_buf_gpadl_handle);
		/* If we failed here, we might as well return and have a leak
		 * rather than continue and a bugchk
		 */
		if (ret != 0) { ... }
	}
}

Since vmbus_teardown_gpadl() silently returns 0 on failure, the network
driver will proceed to free the receive/send buffers.

Could the host still consider these buffers active and overwrite the newly
freed memory with incoming network packets, leading to guest memory 
corruption?

> +	netvsc_teardown_send_gpadl(device, net_device, ndev);
>  
>  	/* Release all resources */
>  	free_netvsc_device_rcu(net_device);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260805203751.2678-1-mhklinux@outlook.com?part=3

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 6/6] clocksource: hyper-v: Remove support for stimer interrupts in message mode
  2026-08-05 20:37 ` [PATCH v2 6/6] clocksource: hyper-v: Remove support for stimer interrupts in message mode Michael Kelley
@ 2026-08-05 21:04   ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-08-05 21:04 UTC (permalink / raw)
  To: Michael Kelley; +Cc: linux-hyperv

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Use-After-Free of per-CPU clockevent devices during module unload or kexec.
--

--- Patch [6]: [PATCH v2 6/6] clocksource: hyper-v: Remove support for stimer interrupts in message mode ---
Note: The format of this report is altered and does not contain diff quotes due to recitation restrictions.

commit d696e5fb31caa79d07059889453363cd5e4a9522
Author: Michael Kelley <mhkelley58@gmail.com>

clocksource: hyper-v: Remove support for stimer interrupts in message mode

This commit removes the legacy message-based delivery mechanism for Hyper-V
synthetic timers, making Direct Mode the only supported mechanism. The VMBus
driver no longer processes stimer interrupts, decoupling the two subsystems.

[Severity: High]
This is a pre-existing issue, but by removing the legacy teardown path, we
might be unconditionally exposing a use-after-free during module unload or
kexec.

Looking at hv_stimer_cleanup() in drivers/clocksource/hyperv_timer.c, the
code intentionally skips calling clockevents_unbind_device(), leaving the
clockevents registered in the core subsystem's linked list.

Then, in hv_stimer_global_cleanup() in the same file, the code unconditionally
frees the active hv_clock_event per-CPU memory via free_percpu(hv_clock_event)
while the structures are still registered in the clockevents core.

Can this result in dangling pointers in the core timekeeping lists? When the
hv_vmbus module is unloaded (vmbus_exit) or during a kexec, 
hv_stimer_global_cleanup() uses cpuhp_remove_state() to stop the timers. This
invokes hv_stimer_cleanup() on all online CPUs, which fails to unbind the
devices, and then the structures are freed.

Any subsequent traversal of the clockevent_devices list (such as servicing a
tick, reading /proc/timer_list, or adding another timer) could dereference
this freed memory. Should clockevents_unbind_device() be called before we free
the percpu data?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260805203751.2678-1-mhklinux@outlook.com?part=6

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-08-05 21:04 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05 20:37 [PATCH v2 0/6] Remove support for Windows Server 2012/2012R2 & Win8/Win8.1 versions of Hyper-V Michael Kelley
2026-08-05 20:37 ` [PATCH v2 1/6] Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version " Michael Kelley
2026-08-05 20:58   ` sashiko-bot
2026-08-05 20:37 ` [PATCH v2 2/6] hv_sock: Remove check for old Hyper-V hosts Michael Kelley
2026-08-05 20:37 ` [PATCH v2 3/6] hv_netvsc: Remove GPADL teardown special case " Michael Kelley
2026-08-05 21:01   ` sashiko-bot
2026-08-05 20:37 ` [PATCH v2 4/6] drm_hyperv: Remove support for synth video protocol of " Michael Kelley
2026-08-05 20:48   ` sashiko-bot
2026-08-05 20:37 ` [PATCH v2 5/6] scsi: storvsc: Remove support for storvsc " Michael Kelley
2026-08-05 20:37 ` [PATCH v2 6/6] clocksource: hyper-v: Remove support for stimer interrupts in message mode Michael Kelley
2026-08-05 21:04   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox