Re: [PATCH v2] Drivers: hv: vmbus: add VTL2 redirect connection ID

Saurabh Singh Sengar <[email protected]> Tue, 21 Jul 2026 08:11:13 -0700
Newsgroups org.kernel.vger.linux-hyperv,org.kernel.vger.linux-kernel
Message-ID <al+MEexKix4eMlB2@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net>
On Fri, Jul 17, 2026 at 12:18:37AM +0000, Hardik Garg wrote:
> 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.
> 
> For a VTL2 kernel using VMBus protocol 5.0 or newer, the host
> may expect INITIATE_CONTACT on either the redirect connection ID or
> VMBUS_MESSAGE_CONNECTION_ID_4. There is no capability indication that
> identifies which ID is active, so the driver must determine it at runtime.
> 
> During VMBus negotiation, the redirect ID is tried first because it is
> used by VTL2 configurations with VMBus redirection enabled. If the
> redirect ID is unavailable, the host rejects it synchronously with
> HV_STATUS_INVALID_CONNECTION_ID, allowing fallback to the standard ID.
> 
> 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. Preserve the existing connection ID
> selection for older protocol versions or when running below VTL2.
> 
> Signed-off-by: Hardik Garg <[email protected]>
> ---
> 
> Notes (v2-changelog):
>     Changes in v2:
>     - Replace the connection ID array and loop with a single redirect
>       attempt, falling back to VMBUS_MESSAGE_CONNECTION_ID_4 only on
>       -ENXIO.
>     - Remove redundant connection-state and timeout checks and the
>       unreachable return after the loop.
>     - Simplify the commit message to describe runtime connection ID
>       selection without relay and message-port implementation details.
>     - Clarify the protocol 5.0 helper and VTL2 redirect comments, remove
>       redundant comments, and use an exact VTL2 check.
>     
>     Link to v1: https://lore.kernel.org/r/[email protected]
> 
>  drivers/hv/connection.c   | 47 +++++++++++++++++++++++----------------
>  drivers/hv/hyperv_vmbus.h |  2 ++
>  2 files changed, 30 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
> index b5b322ce16df4..0fd50d4cb5739 100644
> --- a/drivers/hv/connection.c
> +++ b/drivers/hv/connection.c
> @@ -72,7 +72,8 @@ 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)
> +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,20 +88,20 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
>  	msg->vmbus_version_requested = 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,
> -	 * 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
> -	 * tell the host explicitly that we still use VMBUS_MESSAGE_SINT(2) for
> -	 * compatibility.
> +	 * For VMBus protocol 5.0 (VERSION_WIN10_V5) and higher, use the
> +	 * caller-supplied connection_id for the Initiate Contact message so
> +	 * the caller can implement the required retry scheme. For subsequent
> +	 * messages, use the Message Connection ID field in the host-returned
> +	 * Version Response message. With VERSION_WIN10_V5 and higher, we don't
> +	 * use msg->interrupt_page, but tell the host explicitly that we still
> +	 * use VMBUS_MESSAGE_SINT(2) for compatibility.
>  	 *
>  	 * On old hosts, we should always use VMBUS_MESSAGE_CONNECTION_ID (1).
>  	 */
>  	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;
> @@ -165,6 +166,22 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
>  	return ret;
>  }
>  
> +int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
> +{
> +	int ret;
> +
> +	/* Try the redirect ID first for VTL2 with VMBus protocol 5.0+. */
> +	if (version >= VERSION_WIN10_V5 && ms_hyperv.vtl == 2) {
> +		ret = vmbus_try_connection_id(msginfo, version,
> +					      VMBUS_MESSAGE_CONNECTION_ID_REDIRECT);
> +		if (ret != -ENXIO)
> +			return ret;
> +	}
> +
> +	return vmbus_try_connection_id(msginfo, version,
> +				       VMBUS_MESSAGE_CONNECTION_ID_4);
> +}
> +
>  /*
>   * vmbus_connect - Sends a connect request on the partition service connection
>   */
> @@ -457,18 +474,10 @@ 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.
> -			 */
> +			/* Allow INITIATE_CONTACT to try another connection ID. */
>  			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 05a36854389af..87f8aca1a9fb5 100644
> --- a/drivers/hv/hyperv_vmbus.h
> +++ b/drivers/hv/hyperv_vmbus.h
> @@ -110,6 +110,8 @@ struct hv_input_post_message {
>  enum {
>  	VMBUS_MESSAGE_CONNECTION_ID	= 1,
>  	VMBUS_MESSAGE_CONNECTION_ID_4	= 4,
> +	/* VTL2 redirect connection ID for INITIATE_CONTACT. */
> +	VMBUS_MESSAGE_CONNECTION_ID_REDIRECT = 0x800074,
>  	VMBUS_MESSAGE_PORT_ID		= 1,
>  	VMBUS_EVENT_CONNECTION_ID	= 2,
>  	VMBUS_EVENT_PORT_ID		= 2,
> -- 
> 2.34.1

Reviewed-by: Saurabh Sengar <[email protected]>