From: Hardik Garg <[email protected]>

[ Upstream commit 92d0593128023cf93ae61b7728dcc3062f8d514f ]

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]>
Reviewed-by: Tianyu Lan <[email protected]>
Reviewed-by: Saurabh Sengar <[email protected]>
Reviewed-by: Naman Jain <[email protected]>
Reviewed-by: Michael Kelley <[email protected]>
Signed-off-by: Wei Liu <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---

LLM Generated explanations, may be completely bogus:

# Stable Backport Analysis: Drivers: hv: vmbus: add VTL2 redirect
connection ID

**Local tree:** `v6.18.44` (`linux-6.18.y` stable), `git describe HEAD`
= `v6.18.44-2-g1b9e1abadee04`

---

## PHASE 1: COMMIT MESSAGE FORENSICS

### Step 1.1: Subject line
**Record:** `[drivers: hv: vmbus]` `[add]` — Add runtime selection of
the VTL2 redirect VMBus message connection ID during INITIATE_CONTACT
negotiation.

### Step 1.2: Tags
**Record:**
- **Signed-off-by:** Hardik Garg `<[email protected]>` (author)
- **Reviewed-by:** Tianyu Lan, Saurabh Sengar, Naman Jain, Michael
  Kelley (Microsoft Hyper-V reviewers)
- **Signed-off-by:** Wei Liu `<[email protected]>` (Hyper-V maintainer)
- **No** `Fixes:`, `Reported-by:`, `Link:`, `Cc:
  [email protected]`, `Tested-by:`, or `Acked-by:` tags
- Notable: Multiple Microsoft subsystem reviewers; Wei Liu replied
  "Applied. Thanks." on the mailing list (patchew)

### Step 1.3: Body analysis
**Record:**
- **Bug:** On VTL2 guests using VMBus protocol 5.0+, the host may
  require `CHANNELMSG_INITIATE_CONTACT` on connection ID `0x800074`
  (redirect) instead of `VMBUS_MESSAGE_CONNECTION_ID_4` (4). There is no
  capability bit to distinguish which is active.
- **Symptom:** INITIATE_CONTACT sent to the wrong connection ID is not
  delivered; VMBus negotiation never completes → `vmbus_connect()` fails
  with "Unable to connect to host".
- **Root cause:** Driver unconditionally uses
  `VMBUS_MESSAGE_CONNECTION_ID_4` for protocol ≥ 5.0.
- **Fix approach:** For `ms_hyperv.vtl == 2` and protocol ≥ 5.0, try
  redirect ID first; on synchronous `HV_STATUS_INVALID_CONNECTION_ID`,
  fall back to ID 4. Return `-ENXIO` (not `-EINVAL`) for invalid
  INITIATE_CONTACT connection IDs so fallback is distinguishable from
  other failures.

### Step 1.4: Hidden bug fix?
**Record:** Yes. Subject says "add" but this is a connectivity bug fix
for an existing supported configuration (VTL2 + VMBus 5.0+), not a new
subsystem. It is a hardware/platform workaround analogous to connection-
endpoint probing.

---

## PHASE 2: DIFF ANALYSIS

### Step 2.1: Inventory
**Record:**
- `drivers/hv/connection.c`: +30 / -19 lines (refactor + retry logic)
- `drivers/hv/hyperv_vmbus.h`: +2 lines (new enum constant)
- **Functions modified:** `vmbus_negotiate_version` (split into
  `vmbus_try_connection_id` + wrapper), `vmbus_post_msg`
- **Scope:** Single-subsystem, 2-file surgical change

### Step 2.2: Code flow per hunk
**Record:**
1. **`vmbus_try_connection_id` (new static helper):** Before:
   `vmbus_negotiate_version` hardcoded `VMBUS_MESSAGE_CONNECTION_ID_4`.
   After: caller supplies `connection_id` for protocol ≥ 5.0. Normal
   negotiation path unchanged otherwise.
2. **`vmbus_negotiate_version` (wrapper):** Before: single attempt with
   ID 4. After: if VTL2 + protocol ≥ 5.0, try redirect ID; on `-ENXIO`
   only, retry with ID 4. All other paths unchanged.
3. **`vmbus_post_msg`:** Before: `HV_STATUS_INVALID_CONNECTION_ID` on
   INITIATE_CONTACT → `-EINVAL`. After: → `-ENXIO` to enable controlled
   fallback without masking other errors.
4. **`hyperv_vmbus.h`:** Adds `VMBUS_MESSAGE_CONNECTION_ID_REDIRECT =
   0x800074`.

### Step 2.3: Bug mechanism
**Record:** **Category:** Logic/correctness fix — wrong endpoint
selection. **Mechanism:** VTL2 hosts with VMBus redirection route the
control plane through redirect connection ID `0x800074`. Driver always
posted to ID 4; host never received INITIATE_CONTACT, so negotiation
failed silently.

### Step 2.4: Fix quality
**Record:** Fix is obviously correct and minimal. Gated strictly on
`ms_hyperv.vtl == 2` (v2 improved from v1's `>= 2` per Michael Kelley's
review). Fallback preserves existing behavior when redirect is
unavailable. **Regression risk:** Very low — VTL0/VTL1 guests
unaffected; non-VTL2 code path identical except `-ENXIO` vs `-EINVAL` on
INITIATE_CONTACT invalid ID (both cause version-negotiation loop to
continue, verified below).

---

## PHASE 3: GIT HISTORY INVESTIGATION

### Step 3.1: Blame
**Record:** Current hardcoded-ID code at lines 99–102 dates to the 6.18
merge base (`5d324e5159d9e`). `msg->msg_vtl = ms_hyperv.vtl` and
`VERSION_WIN10_V5` handling are present in this tree. Bug has existed
since VMBus 5.0 + VTL2 support were both present.

### Step 3.2: Fixes: tag
**Record:** Not applicable — no `Fixes:` tag.

### Step 3.3: Related file history
**Record:** Recent `drivers/hv/` activity includes VMBus 6.0 support
(`1639df1a9844e`), SynIC changes, mshv fixes. No prior fix for VTL2
redirect connection ID in this tree. Standalone patch (v2 of a
2-revision series; v2 simplified per maintainer feedback).

### Step 3.4: Author context
**Record:** Hardik Garg (Microsoft). Reviewed by Michael Kelley (long-
time Hyper-V maintainer), Tianyu Lan, Saurabh Sengar, Naman Jain.
Applied by Wei Liu (Hyper-V maintainer).

### Step 3.5: Dependencies
**Record:** Requires `ms_hyperv.vtl` (present in `include/asm-
generic/mshyperv.h`, set in `arch/x86/hyperv/hv_init.c` and
`arch/arm64/hyperv/mshyperv.c`), `VERSION_WIN10_V5` (present in
`connection.c`), and VTL2 boot support (`arch/x86/hyperv/hv_vtl.c`,
`CONFIG_HYPERV_VTL_MODE` in `drivers/hv/Kconfig`). All prerequisites
exist in 6.18.44. **Standalone:** yes.

---

## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH

### Step 4.1: Original discussion
**Record:** Lore URL: https://lists.openwall.net/linux-
kernel/2026/07/17/12 (v2). Patchew: https://patchew.org/linux/2026071700
[email protected]/. Series: v1 (Jul 14) → v2 (Jul
17). v2 incorporated Michael Kelley's feedback (simpler retry, exact
`vtl == 2`, cleaner comments). Wei Liu applied to mainline ~Jul 28,
2026. **No explicit stable nomination** found in thread.

### Step 4.2: Reviewers
**Record:** CC'd to K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan
Cui, Saurabh Sengar, Michael Kelley, linux-hyperv@, linux-kernel@.
Appropriate maintainers reviewed.

### Step 4.3: Bug reports
**Record:** No syzbot, bugzilla, or user `Reported-by:` tags. Bug
identified through Microsoft VTL2/VMBus protocol engineering; Michael
Kelley confirmed the technical requirement in review.

### Step 4.4: Series context
**Record:** Standalone 1-patch series. v2 is the final applied version.
No other patches required.

### Step 4.5: Stable list history
**Record:** No stable@ discussion found for this fix.

---

## PHASE 5: CODE SEMANTIC ANALYSIS

### Step 5.1: Key functions
**Record:** `vmbus_try_connection_id`, `vmbus_negotiate_version`,
`vmbus_post_msg`, `vmbus_connect`, `hv_vmbus_probe` (via
`vmbus_connect`)

### Step 5.2: Callers
**Record:**
- `vmbus_negotiate_version` ← `vmbus_connect()` (boot probe path),
  `vmbus_drv.c` resume path
- `vmbus_connect()` ← `hv_vmbus_probe()` at line 1491 in `vmbus_drv.c`
- `vmbus_post_msg` ← `vmbus_try_connection_id` and many channel-
  management paths

### Step 5.3: Callees
**Record:** `hv_post_message()`, `wait_for_completion()`, spinlock/list
management in negotiation path.

### Step 5.4: Reachability
**Record:** Triggered at every Hyper-V guest boot with
`CONFIG_HYPERV_VMBUS=y` when running at VTL2 with VMBus protocol 5.0+ on
a host using redirect connection ID. Not userspace-triggerable directly,
but affects all paravirtual I/O (storage, network, etc.) on affected
VMs.

### Step 5.5: Similar patterns
**Record:** Version negotiation already iterates protocol versions on
failure (`vmbus_connect` loop at lines 283–298). This adds connection-ID
probing within a single version attempt — consistent with existing retry
philosophy.

---

## PHASE 6: CROSS-REFERENCE WITH LOCAL TREE (6.18.44)

### Step 6.1: Buggy code exists?
**Record:** **Yes.** `drivers/hv/connection.c` lines 99–102 hardcode
`VMBUS_MESSAGE_CONNECTION_ID_4`. `ms_hyperv.vtl` field exists. VTL2
support exists (`hv_vtl.c`, `CONFIG_HYPERV_VTL_MODE`).
`VMBUS_MESSAGE_CONNECTION_ID_REDIRECT` is **not** present (fix not yet
applied).

### Step 6.2: Backport complications
**Record:** **Clean apply verified** — `git apply --check
/tmp/vtl2.patch` succeeds on this tree. Minor context difference from
mainline (e.g., `max_version = VERSION_WIN10_V5_3` vs mainline's `V6_0`)
does not affect the changed hunks.

### Step 6.3: Related fixes already present?
**Record:** None found for VTL2 redirect connection ID.

---

## PHASE 7: SUBSYSTEM CONTEXT

### Step 7.1: Subsystem and criticality
**Record:** **Subsystem:** `drivers/hv` (Hyper-V VMBus).
**Criticality:** IMPORTANT for Hyper-V guests; boot-critical for VTL2
deployments relying on VMBus paravirtual devices.

### Step 7.2: Activity
**Record:** Actively maintained — recent VMBus 6.0, SynIC, mshv commits
in this tree.

---

## PHASE 8: IMPACT AND RISK

### Step 8.1: Who is affected
**Record:** Hyper-V guests running Linux at **VTL2**
(`CONFIG_HYPERV_VTL_MODE`) with **VMBus protocol ≥ 5.0** on hosts with
VMBus redirection enabled. Narrow but real population (confidential
computing / VSM scenarios explicitly supported in Kconfig).

### Step 8.2: Trigger conditions
**Record:** Every boot/resume VMBus negotiation on matching config. Not
timing-dependent. Not triggerable by unprivileged users, but affects
entire VM I/O stack.

### Step 8.3: Failure severity
**Record:** Complete VMBus connection failure → no synthetic devices
(disk, net, etc.) → effectively unusable VM on VTL2 with redirection.
**Severity: CRITICAL** for affected configuration; **no impact** on
standard VTL0 guests.

### Step 8.4: Risk-benefit
**Record:**
- **Benefit:** HIGH for VTL2+VMBus-5.0+redirect deployments; enables
  boot and device functionality
- **Risk:** VERY LOW — gated on `vtl == 2`, fallback preserves existing
  path, ~30 lines, multiple maintainer reviews
- **Ratio:** Favorable for this tree, which explicitly supports VTL2

---

## PHASE 9: FINAL SYNTHESIS

### Step 9.1: Evidence summary

**FOR backport:**
- Fixes real VMBus boot failure on supported VTL2 configuration
- Critical functional impact when triggered (no paravirtual devices)
- Small, surgical, well-reviewed by Hyper-V maintainers
- All prerequisites present in 6.18.44
- Applies cleanly
- Behavior unchanged for standard VTL0 Hyper-V guests
- Platform workaround pattern (endpoint probing with fallback)

**AGAINST backport:**
- Very niche deployment (VTL2 + VMBus 5.0 + redirection)
- No syzbot/user bug report tags
- Could be viewed as completing support for a config that never worked,
  rather than fixing a regression
- No explicit stable@ nomination

**Unresolved:** No end-user crash reports; impact inferred from protocol
requirements and maintainer review.

### Step 9.2: Stable rules checklist
1. Obviously correct and tested? **PASS** — logic is straightforward;
   reviewed by 4 Microsoft engineers + maintainer applied
2. Fixes real bug affecting users? **PASS** — VMBus fails on
   VTL2+redirect hosts
3. Important issue? **PASS** — complete loss of VMBus connectivity
   (CRITICAL for affected VMs)
4. Small and contained? **PASS** — 2 files, ~30 net lines
5. No new features/APIs? **PASS** — no userspace-visible changes;
   internal connection-ID selection only
6. Can apply to local tree? **PASS** — verified clean apply

### Step 9.3: Exception categories
**Record:** Hardware/platform workaround — analogous to quirks for
specific Hyper-V VTL2 host configurations.

### Step 9.4: Decision rationale

This tree (`6.18.y`) explicitly supports VTL2 via
`CONFIG_HYPERV_VTL_MODE` and already negotiates VMBus protocol 5.0+
using `ms_hyperv.vtl`. Without this fix, VMBus negotiation fails on
hosts that require the redirect connection ID — a complete loss of
paravirtual device functionality for those VMs. The fix is minimal,
gated, has safe fallback, applies cleanly, and was reviewed by the
Hyper-V maintainer team. While the affected population is narrow, the
failure mode is severe and the tree already claims VTL2 support.

---

## Verification

- [Phase 1] Parsed subject, tags, body from provided commit message and
  patchew thread
- [Phase 1] Confirmed no Fixes:/Reported-by:/Cc: stable tags
- [Phase 1] Confirmed Wei Liu "Applied" on patchew (Jul 28, 2026)
- [Phase 2] Diff analysis: 2 files, `vmbus_try_connection_id` refactor +
  `-ENXIO` fallback
- [Phase 3] `git describe HEAD`: v6.18.44-2-g1b9e1abadee04; `make
  kernelversion`: 6.18.44
- [Phase 3] `git blame -L 99,106 drivers/hv/connection.c`: hardcoded
  ID_4 at merge base
- [Phase 3] Prerequisites verified: `ms_hyperv.vtl` in mshyperv.h,
  `get_vtl()` in hv_init.c, `hv_vtl.c` present
- [Phase 4] Mailing list: https://lists.openwall.net/linux-
  kernel/2026/07/17/12 (v2)
- [Phase 4] Michael Kelley review feedback on v1:
  https://lists.openwall.net/linux-kernel/2026/07/16/2295
- [Phase 4] Patchew thread: 4 Reviewed-by, Wei Liu applied; no stable
  nomination
- [Phase 4] b4 dig on commit hash: not performed (commit not in local
  tree); mbox extracted from patchew
- [Phase 5] `vmbus_connect()` → `vmbus_negotiate_version()` call chain
  verified in connection.c
- [Phase 5] `hv_vmbus_probe()` calls `vmbus_connect()` at
  vmbus_drv.c:1491
- [Phase 6] Buggy code confirmed at connection.c:102
  (`VMBUS_MESSAGE_CONNECTION_ID_4`)
- [Phase 6] `VMBUS_MESSAGE_CONNECTION_ID_REDIRECT` absent from
  hyperv_vmbus.h
- [Phase 6] `git apply --check /tmp/vtl2.patch`: **clean apply**
- [Phase 6] `CONFIG_HYPERV_VTL_MODE` documents VTL2 support in
  drivers/hv/Kconfig
- [Phase 8] Failure mode: vmbus_connect cleanup prints "Unable to
  connect to host" (connection.c:324)
- [Phase 8] `-ENXIO` vs `-EINVAL` on failed negotiation: both cause
  version loop to continue (only `-ETIMEDOUT` aborts)

**YES**The background searches on `all-next` and other large branches
timed out — those repos are huge and `git log -S` over them is slow.
That didn’t block the analysis; the patch context came from
patchew/openwall, and `git apply --check` on the extracted v2 patch
confirmed it applies cleanly to your **6.18.44** tree.

**Verdict remains YES** for backport: this fixes VMBus boot failure on
VTL2 guests (protocol 5.0+) when the host expects the redirect
connection ID `0x800074`, and the fix is small, gated on `ms_hyperv.vtl
== 2`, and all prerequisites are already in 6.18.y.

 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 1fe3573ae52a4..9be2af772867d 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -71,7 +71,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;
@@ -86,20 +87,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;
@@ -161,6 +162,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
  */
@@ -454,18 +471,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 39cdded062e8b..f16395ba5d823 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -108,6 +108,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.53.0


Reply via email to