* [PATCH] Drivers: hv: vmbus: add VTL2 redirect connection ID
@ 2026-07-14 21:38 Hardik Garg
0 siblings, 0 replies; only message in thread
From: Hardik Garg @ 2026-07-14 21:38 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
linux-hyperv, linux-kernel
VMBus sends CHANNELMSG_INITIATE_CONTACT through a Hyper-V message
connection ID. Older protocol versions use VMBUS_MESSAGE_CONNECTION_ID,
while protocol version 5.0 and newer normally use
VMBUS_MESSAGE_CONNECTION_ID_4.
When the Linux VMBus driver runs at VTL2, the VMBus control plane may
be reached through a VMBus relay instead of the standard host endpoint.
In that setup the relay listens on the redirect message connection ID,
and an Initiate Contact message sent to the standard ID is not delivered
to the control plane.
The connection ID selects the Hyper-V message port used to reach the
VMBus control plane. If Linux uses the wrong port, the host does not
receive the Initiate Contact message.
For Linux running at VTL2 with VMBus protocol 5.0 or newer, try the
redirect connection ID first. In VTL2, the redirect connection ID is the
VMBus relay endpoint. If the relay is present, it accepts Initiate
Contact and completes the normal version-response handshake. Systems
without the relay reject the redirect ID synchronously with
HV_STATUS_INVALID_CONNECTION_ID, allowing fallback to
VMBUS_MESSAGE_CONNECTION_ID_4.
Return a distinct error for an invalid Initiate Contact connection ID so
this fallback does not mask other post-message failures or
protocol-version rejections. For older protocol versions, and for Linux
below VTL2, keep the existing connection ID selection.
Signed-off-by: Hardik Garg <hargar@linux.microsoft.com>
---
drivers/hv/connection.c | 76 ++++++++++++++++++++++++++++++++++++++++-------
drivers/hv/hyperv_vmbus.h | 2 ++
2 files changed, 67 insertions(+), 11 deletions(-)
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 1fe3573ae52a4..eb871f87a819d 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -71,7 +71,19 @@ module_param(max_version, uint, S_IRUGO);
MODULE_PARM_DESC(max_version,
"Maximal VMBus protocol version which can be negotiated");
-int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
+/* Connection IDs to try for VTL2 VMBus protocol 5.0 and newer. */
+static const u32 connection_ids[] = {
+ VMBUS_MESSAGE_CONNECTION_ID_REDIRECT,
+ VMBUS_MESSAGE_CONNECTION_ID_4,
+};
+
+/*
+ * Send one CHANNELMSG_INITIATE_CONTACT attempt.
+ * The caller supplies the message connection ID and owns retry/fallback
+ * policy.
+ */
+static int vmbus_try_connection_id(struct vmbus_channel_msginfo *msginfo,
+ u32 version, u32 connection_id)
{
int ret = 0;
struct vmbus_channel_initiate_contact *msg;
@@ -87,7 +99,7 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
/*
* VMBus protocol 5.0 (VERSION_WIN10_V5) and higher require that we must
- * use VMBUS_MESSAGE_CONNECTION_ID_4 for the Initiate Contact Message,
+ * use connection_id for the Initiate Contact Message,
* and for subsequent messages, we must use the Message Connection ID
* field in the host-returned Version Response Message. And, with
* VERSION_WIN10_V5 and higher, we don't use msg->interrupt_page, but we
@@ -99,7 +111,7 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
if (version >= VERSION_WIN10_V5) {
msg->msg_sint = VMBUS_MESSAGE_SINT;
msg->msg_vtl = ms_hyperv.vtl;
- vmbus_connection.msg_conn_id = VMBUS_MESSAGE_CONNECTION_ID_4;
+ vmbus_connection.msg_conn_id = connection_id;
} else {
msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
vmbus_connection.msg_conn_id = VMBUS_MESSAGE_CONNECTION_ID;
@@ -161,6 +173,51 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
return ret;
}
+/*
+ * Negotiate the given VMBus protocol version with the host.
+ * Protocol-specific connection ID policy is handled here so the single-try
+ * helper stays simple.
+ */
+int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
+{
+ int ret;
+ size_t j;
+
+ /*
+ * The redirect ID is not a speculative endpoint. If the VMBus relay is
+ * present, it accepts INITIATE_CONTACT and completes the normal version
+ * response. Systems without the relay reject the ID synchronously, so
+ * negotiation falls back to VMBUS_MESSAGE_CONNECTION_ID_4.
+ */
+ if (version >= VERSION_WIN10_V5 && ms_hyperv.vtl >= 2) {
+ for (j = 0; j < ARRAY_SIZE(connection_ids); j++) {
+ ret = vmbus_try_connection_id(msginfo, version,
+ connection_ids[j]);
+ if (vmbus_connection.conn_state == CONNECTED)
+ return 0;
+
+ if (ret == -ETIMEDOUT)
+ return ret;
+
+ if (connection_ids[j] ==
+ VMBUS_MESSAGE_CONNECTION_ID_REDIRECT &&
+ ret == -ENXIO)
+ continue;
+
+ return ret;
+ }
+ return ret;
+ }
+
+ /*
+ * Non-redirect path. Protocol 5.0+ below VTL2 uses the standard
+ * v5 connection ID; pre-v5 ignores the supplied ID and uses the
+ * legacy connection ID.
+ */
+ return vmbus_try_connection_id(msginfo, version,
+ VMBUS_MESSAGE_CONNECTION_ID_4);
+}
+
/*
* vmbus_connect - Sends a connect request on the partition service connection
*/
@@ -455,17 +507,14 @@ int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep)
switch (ret) {
case HV_STATUS_INVALID_CONNECTION_ID:
/*
- * See vmbus_negotiate_version(): VMBus protocol 5.0
- * and higher require that we must use
- * VMBUS_MESSAGE_CONNECTION_ID_4 for the Initiate
- * Contact message, but on old hosts that only
- * support VMBus protocol 4.0 or lower, here we get
- * HV_STATUS_INVALID_CONNECTION_ID and we should
- * return an error immediately without retrying.
+ * Let negotiation distinguish an unusable
+ * endpoint from other failures.
+ *
+ * Other messages keep retry behavior.
*/
hdr = buffer;
if (hdr->msgtype == CHANNELMSG_INITIATE_CONTACT)
- return -EINVAL;
+ return -ENXIO;
/*
* We could get this if we send messages too
* frequently.
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 49a72a4f3f6a7..951bdebdc0526 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -109,6 +109,8 @@ struct hv_input_post_message {
enum {
VMBUS_MESSAGE_CONNECTION_ID = 1,
VMBUS_MESSAGE_CONNECTION_ID_4 = 4,
+ /* VMBus relay port used for INITIATE_CONTACT probing. */
+ VMBUS_MESSAGE_CONNECTION_ID_REDIRECT = 0x800074,
VMBUS_MESSAGE_PORT_ID = 1,
VMBUS_EVENT_CONNECTION_ID = 2,
VMBUS_EVENT_PORT_ID = 2,
--
2.34.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-14 21:38 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14 21:38 [PATCH] Drivers: hv: vmbus: add VTL2 redirect connection ID Hardik Garg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox