Skip to content

Add nested virtualization support for WSLC containers - #41257

Draft
Ben Hillis (benhillis) wants to merge 6 commits into
masterfrom
user/benhill/wslc-nested-virt
Draft

Add nested virtualization support for WSLC containers#41257
Ben Hillis (benhillis) wants to merge 6 commits into
masterfrom
user/benhill/wslc-nested-virt

Conversation

@benhillis

@benhillis Ben Hillis (benhillis) commented Aug 5, 2026

Copy link
Copy Markdown
Member

Summary

  • add an opt-in WSLC session feature flag for nested virtualization
  • expose virtualization extensions only when HCS reports support, otherwise fail session creation with a localized error
  • mount the kernel modules VHD through a dedicated guest protocol message and load the vendor-specific KVM module using guest CPUID
  • pass /dev/kvm into containers in nested-virtualization sessions
  • share nested virtualization capability detection with the existing WSL2 path

Validation

  • Ran unit tests and inspection that the config option worked as expected

Fixes #40736

@benhillis
Ben Hillis (benhillis) requested a review from a team as a code owner August 5, 2026 17:45
Copilot AI lite review requested due to automatic review settings August 5, 2026 17:45
@benhillis
Ben Hillis (benhillis) requested a review from a team as a code owner August 5, 2026 17:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds opt-in nested virtualization support for WSLC (wslc) container sessions by introducing a feature flag that enables virtualization extensions in the utility VM, mounting kernel modules via a dedicated guest protocol message, loading the appropriate KVM module in the guest, and exposing /dev/kvm inside containers.

Changes:

  • Add WslcFeatureFlagsNestedVirtualization / WSLC_SESSION_FEATURE_FLAG_NESTED_VIRTUALIZATION and wire it through service + SDK flag validation/mapping.
  • Gate ExposeVirtualizationExtensions on HCS nested-virt support, failing session creation with a localized user error when unsupported.
  • Add a new guest protocol message to mount the modules VHD and optionally load the vendor-specific KVM module; pass /dev/kvm into containers for nested-virt sessions.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/windows/wslcsession/WSLCVirtualMachine.h Adds MountModules helper declaration for the new modules-mount protocol.
src/windows/wslcsession/WSLCVirtualMachine.cpp Switches modules VHD mounting to MountModules and implements the new transaction/message.
src/windows/wslcsession/WSLCContainer.cpp Adds /dev/kvm device passthrough when nested virtualization is enabled for the session.
src/windows/WslcSDK/wslcsdk.h Exposes nested virtualization as an SDK session feature flag constant.
src/windows/WslcSDK/wslcsdk.cpp Updates SDK ↔ service flag mapping/validation to include nested virtualization.
src/windows/service/inc/WSLCShared.idl Adds WslcFeatureFlagsNestedVirtualization and updates the valid-flags mask.
src/windows/service/exe/WslCoreVm.cpp Reuses a shared HCS helper for nested-virt support detection in the WSL2 VM path.
src/windows/service/exe/HcsVirtualMachine.cpp Enables virtualization extensions when flagged, and rejects unsupported hosts with a localized user error.
src/windows/common/hcs.hpp Declares IsNestedVirtualizationSupported() for shared capability detection.
src/windows/common/hcs.cpp Implements IsNestedVirtualizationSupported() (Windows 11+ + HCS processor feature check).
src/shared/inc/lxinitshared.h Adds LxMessageWSLCMountModules and the WSLC_MOUNT_MODULES message struct; removes KernelModules flag from WSLC_MOUNT.
src/linux/init/WSLCInit.cpp Handles WSLC_MOUNT_MODULES to mount modules and optionally modprobe the vendor KVM module via CPUID.

Comment thread src/linux/init/WSLCInit.cpp Outdated
@benhillis
Ben Hillis (benhillis) marked this pull request as draft August 5, 2026 17:51
Copilot AI review requested due to automatic review settings August 5, 2026 18:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/windows/wslcsession/WSLCVirtualMachine.cpp:902

  • MountModules() discards the init-side error code by always throwing E_FAIL when response.Result != 0. Since WSLC_MOUNT_RESULT::Result already carries the HRESULT from the guest (wil::ResultFromCaughtException), callers lose the specific failure and only see a generic E_FAIL.
    THROW_HR_IF(E_FAIL, response.Result != 0);

Copilot AI review requested due to automatic review settings August 5, 2026 19:50
Comment thread src/linux/init/WSLCInit.cpp
Comment thread src/shared/inc/lxinitshared.h

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Ben Hillis and others added 4 commits August 10, 2026 14:04
Add WslcFeatureFlagsNestedVirtualization so a wslc session can request
virtualization extensions in its utility VM, exposing /dev/kvm to
containers (qemu-kvm, libvirt, Firecracker, Android emulators).

- Service enum bit 64 + C SDK flag 0x40 wired through FlagsTraits.
- HcsVirtualMachine sets ExposeVirtualizationExtensions when requested,
  skipping child perfmon on Windows 10 (Hyper-V rejects the combination).
- wslcsession passes /dev/kvm into the container.
- Guest init loads kvm_intel/kvm_amd (best-effort) only when the session
  requested nested virt, signalled via a new NestedVirtualization mount
  flag on the kernel-modules mount.

Fixes #40736

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Share HCS nested virtualization capability detection with WSL2 and fail WSLC session creation when the requested capability is unavailable. Add a dedicated kernel modules mount message and select the appropriate KVM module from the guest CPU vendor.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0553ee36-2b3e-48a0-b2db-e8c6362c6f2b
Use an explicit I/O error when modprobe fails instead of throwing from a potentially stale errno value.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0553ee36-2b3e-48a0-b2db-e8c6362c6f2b
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0553ee36-2b3e-48a0-b2db-e8c6362c6f2b
Copilot AI review requested due to automatic review settings August 10, 2026 21:14
@benhillis
Ben Hillis (benhillis) force-pushed the user/benhill/wslc-nested-virt branch from a212e54 to 1398e2f Compare August 10, 2026 21:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/linux/init/WSLCInit.cpp:712

  • LoadKvmModule() unconditionally throws ENOTSUP on non-x86_64 builds. Since MountModules passes LoadKvm based only on the feature flag, enabling nested virtualization would cause session initialization to fail on non-x86_64 guests (e.g., ARM64) even if HCS exposes virtualization extensions. Consider either supporting the appropriate KVM module(s) for non-x86_64 kernels or gating LoadKvm/feature enablement by guest architecture and returning a user-friendly error.
#else

    THROW_ERRNO(ENOTSUP);

#endif

src/windows/wslcsession/WSLCVirtualMachine.cpp:1000

  • MountModules() currently throws a generic E_FAIL whenever the guest reports a non-zero Result. Since the guest side sets Result via wil::ResultFromCaughtException(), this masks the underlying HRESULT (e.g., ENOTSUP mapped to HRESULT_FROM_WIN32). Propagating the guest HRESULT would make failures significantly easier to diagnose than a blanket E_FAIL.
    WSL_LOG(
        "WSLCMountModules",
        TraceLoggingValue(Source, "Source"),
        TraceLoggingValue(LoadKvm, "LoadKvm"),
        TraceLoggingValue(response.Result, "Result"));

    THROW_HR_IF(E_FAIL, response.Result != 0);
}

Comment thread src/linux/init/WSLCInit.cpp Outdated
module = "kvm_amd";
}

THROW_ERRNO_IF(ENOTSUP, module == nullptr);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An error message that includes vendor might be useful.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/windows/service/exe/HcsVirtualMachine.cpp:157

  • No automated test exercises this new feature branch: the only test change moves the invalid-feature mask to 0x80, whereas the analogous GPU feature has enabled/disabled session and container coverage in WSLCTests.cpp:4001-4061 plus SDK tests. Add capability-aware coverage for the unsupported localized failure and, on a supported host, session creation and /dev/kvm access inside a container so regressions in the HCS, guest-protocol, module-loading, and device-mapping path are detected.
    if (FeatureEnabled(WslcFeatureFlagsNestedVirtualization))
    {
        THROW_HR_WITH_USER_ERROR_IF(
            HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED),
            wsl::shared::Localization::MessageNestedVirtualizationNotSupported(),
            !hcs::IsNestedVirtualizationSupported());

src/windows/WslcSDK/wslcsdk.h:119

  • The new public session capability is reachable only from the C API. The C#/C++ projections expose SessionSettings through winrt/wslcsdk.idl, which has only EnableGpu and no raw feature-flags property, even though doc/docs/api-reference/index.md:12 states that all projections provide the same underlying capabilities. Add an EnableNestedVirtualization property through the WinRT IDL and implementation, with corresponding projection tests and API-reference updates, so those consumers can opt in too.
    WSLC_SESSION_FEATURE_FLAG_NESTED_VIRTUALIZATION = 0x00000040

Expose nested virtualization through the WinRT projections and add policy enforcement for WSLC sessions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0553ee36-2b3e-48a0-b2db-e8c6362c6f2b
Copilot AI review requested due to automatic review settings August 10, 2026 23:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/windows/WslcSDK/wslcsdk.h:119

  • The new public C SDK flag is missing from the C API reference: doc/docs/api-reference/c/enumerations/wslcsessionfeatureflags.md still lists only NONE and ENABLE_GPU, and the feature-flags setter page only demonstrates GPU. Please update those C reference pages as was done for the C#/C++ surfaces so C consumers can discover and use this flag.
    WSLC_SESSION_FEATURE_FLAG_NESTED_VIRTUALIZATION = 0x00000040

src/windows/wslcsession/WSLCContainer.cpp:1943

  • There is no automated test for the feature's main container contract: the added tests only cover the WinRT property and policy rejection, while this path that injects /dev/kvm (and the companion module-loading path) is unexercised. Please add a supported-host/conditionally skipped E2E test that verifies /dev/kvm is usable in nested-virtualization sessions and absent from ordinary sessions; the existing GPU E2E coverage in test/windows/WSLCTests.cpp:4116-4135 provides a similar pattern.
        request.HostConfig.Devices->push_back({"/dev/kvm", "/dev/kvm", "rwm"});

Document the C API flag, preserve guest mount errors, and add capability-aware container coverage for KVM access.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0553ee36-2b3e-48a0-b2db-e8c6362c6f2b
Copilot AI review requested due to automatic review settings August 11, 2026 00:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add nested virtualization support for wslc containers

3 participants