Linux-HyperV List
 help / color / mirror / Atom feed
From: Hardik Garg <hargar@linux.microsoft.com>
To: Michael Kelley <mhklinux@outlook.com>,
	"K. Y. Srinivasan" <kys@microsoft.com>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	Wei Liu <wei.liu@kernel.org>, Dexuan Cui <decui@microsoft.com>,
	"linux-hyperv@vger.kernel.org" <linux-hyperv@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] Drivers: hv: vmbus: add VTL2 redirect connection ID
Date: Thu, 16 Jul 2026 15:04:30 -0700	[thread overview]
Message-ID: <b5f8567e-3ce8-4d62-ae91-7479ba00ce07@linux.microsoft.com> (raw)
In-Reply-To: <SN6PR02MB415769F6F2645260C8D5778CD4C72@SN6PR02MB4157.namprd02.prod.outlook.com>


On 7/16/2026 10:03 AM, Michael Kelley wrote:
> From: Hardik Garg <hargar@linux.microsoft.com> Sent: Tuesday, July 14, 2026 2:39 PM
>> 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.
> This is a judgment call, but to me the previous two paragraphs are
> explaining VTL2 implementation details that aren't necessary for
> understanding this patch. Yes, in earlier discussions I asked questions
> about "why" all this funky behavior with connection IDs, but that's
> just me as a former Microsoft insider. :-)  Details about VMBus relays and
> message ports are fairly obscure for people in the general Linux community.
> It would be sufficient for the commit message to simply state that VTL2
> may respond on either of two connection IDs. There's no separate indication
> of which one will respond in a given VM, so it is necessary to try at runtime
> to see which one works.

Good point, I will remove the extra details in v2.

>
>> 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.
> Is there a reason for trying the REDIRECT connection ID first? Or
> is the ordering of trying arbitrary? If the REDIRECT connection
> ID must be tried first, state that as a VTL2 requirement.

I will add it as a VTL2 requirement. Redirect Id is used first as it
is the configured VMBus control-plane endpoint when VTL2 redirection
is enabled. 

>
>> 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,
>> +};
> Using an array of connection IDs to iterate through matches the
> design of how multiple VMBus protocols versions are tried. But with
> only two entries in the array, this feels a bit over-engineered unless
> there is reason to expect that more connection ID values are coming
> in the reasonably near future. Absent an array, the code in the
> vmbus_negotiate_version() could just hard code to test the redirect
> connection ID first if running at VTL2, and if that fails with -ENXIO,
> fall through to the normal case. 


I used the array to accommodate new connection-ids in the future but I agree
that we don't need it currently. I will simplify it in v2.

>> +
>> +/*
>> + * 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,
> This wording of this comment now feels a bit awkward. How about:
>
> "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
> necessary retry scheme. For subsequent messages, use the Message Connection ID
> field in the host-returned Version Response Message."
>
> followed by the rest of the existing text.

Will update the comment in V2

>
>
>>  	 * 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
> What is a "speculative endpoint"?  And per my comment above, I'd drop
> discussion of VMBus relay, and just phrase things in terms of trying the
> REDIRECT connection ID, and if that doesn't work, then try the normal one. 
I will simplify the comment in V2
>  
>
>> +	 * 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;
>> +	}
> Per my earlier comment about not having an array of connection IDs, this
> code could be as simple as:
>
> 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;
> }
I will update this part as per the earlier feedback.
>> +
>> +	/*
>> +	 * 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

Thank you for the review, Michael.


Thanks,

Hardik


      reply	other threads:[~2026-07-16 22:04 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14 21:38 [PATCH] Drivers: hv: vmbus: add VTL2 redirect connection ID Hardik Garg
2026-07-16 15:21 ` Saurabh Singh Sengar
2026-07-16 20:53   ` Hardik Garg
2026-07-16 17:03 ` Michael Kelley
2026-07-16 22:04   ` Hardik Garg [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b5f8567e-3ce8-4d62-ae91-7479ba00ce07@linux.microsoft.com \
    --to=hargar@linux.microsoft.com \
    --cc=decui@microsoft.com \
    --cc=haiyangz@microsoft.com \
    --cc=kys@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhklinux@outlook.com \
    --cc=wei.liu@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox