Skip to content

cvm guest vsm: implement missing register handling - #4161

Open
sluck-msft wants to merge 3 commits into
microsoft:mainfrom
sluck-msft:guestvsm/missing-regs
Open

cvm guest vsm: implement missing register handling#4161
sluck-msft wants to merge 3 commits into
microsoft:mainfrom
sluck-msft:guestvsm/missing-regs

Conversation

@sluck-msft

@sluck-msft sluck-msft commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Adds handling for several VSM-related synthetic registers that were previously unimplemented (or incompletely implemented) for hardware-isolated CVMs, so that a guest VSM (VTL 1) running inside a CVM can query partition/VP VSM state. Also fixes a bug in HvEnableVpVtl when the caller targets itself via HV_VP_INDEX_SELF.

Tested: via private updates to opentmk, booting partner VHD

Fixes #3797, fixes #3798

@sluck-msft
sluck-msft requested a review from a team as a code owner August 4, 2026 23:13
Copilot AI lite review requested due to automatic review settings August 4, 2026 23:13

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

Implements missing Hyper-V VSM synthetic register handling for hardware-isolated CVMs so a guest VSM (VTL1) can query partition/VP VSM state, and fixes HvEnableVpVtl handling when the target VP is specified as HV_VP_INDEX_SELF.

Changes:

  • Add VsmPartitionConfig, VsmPartitionStatus, and VsmVpStatus synthetic register handling for hardware-isolated CVMs, plus extend VsmCapabilities reporting.
  • Fix HvEnableVpVtl to correctly resolve HV_VP_INDEX_SELF to the current VP index before indexing/dispatch.
  • Extend CPUID privilege exposure for CVMs to advertise VP register access and add small utilities for VtlSet.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
vm/hv1/hv1_structs/src/vtl_array.rs Adds VtlSet::with_vtl and From<VtlSet> for u16 for easier VTL-set bitfield construction.
openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Implements CVM-specific synthetic VSM register reads and fixes HV_VP_INDEX_SELF handling in HvEnableVpVtl.
openhcl/virt_mshv_vtl/src/lib.rs Tracks whether the partition has VSM privilege and adds per-VP MBEC state tracking.
openhcl/virt_mshv_vtl/src/cvm_cpuid/tdx.rs Advertises access_vp_registers in the CVM CPUID privilege leaf for TDX.
openhcl/virt_mshv_vtl/src/cvm_cpuid/snp.rs Advertises access_vp_registers in the CVM CPUID privilege leaf for SNP.

Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs
}
Ok(())
}
HvX64RegisterName::VsmPartitionStatus | HvX64RegisterName::VsmCapabilities => {
Comment on lines +226 to +230
impl From<VtlSet> for u16 {
fn from(set: VtlSet) -> Self {
set.bits.into_inner()
}
}
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

@smalis-msft Steven Malis (smalis-msft) added the backport_1.8.2607 Change should be backported to the release/1.8.2607 branch label Aug 5, 2026
Comment thread openhcl/virt_mshv_vtl/src/lib.rs
vtl0_exit_pending_event: Option<hvdef::HvX64PendingExceptionEvent>,
reg_intercept: SecureRegisterInterceptState,
/// Whether Mode-Based Execution Control is enabled on this VP.
vp_mbec_enabled: bool,

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.

Is this different from CvmVtl1State's mbec_enabled?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

CvmVtl1State is per-partition, no? This one is per-vp and controlled by a different register. Although, this is making me think I'm missing some validation later on in consuming this variable, so I should look into that.

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.

It is per partition but I believe we're enforcing that every VP must match already, see my other comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Actually I think it can be different on initialization. Mbec enabled can be false for the vp and true for the partition. But when it's configured for the vp, the new mbec enabled value should be the same as on the partition.

// the hypervisor behavior, but for all intents and purposes only VTL 1
// will be able to set this on VTL 0, so only a single VTL can have
// this configured anyway.
if let Some(vtl1_state) = self.backing.cvm_state_mut().vtl1.as_mut() {

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.

I don't think this is necessary, since we know that every vp must match the original vtl1 config, checked 10 lines above.

Copilot AI review requested due to automatic review settings August 12, 2026 22:38

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 5 out of 5 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

vm/hv1/hv1_structs/src/vtl_array.rs:230

  • New VtlSet::with_vtl() and From<VtlSet> for u16 are introduced but not covered by the existing unit tests in this module. Adding a small test helps ensure the builder-style API and bit conversion stay consistent with Vtl bit positions.
impl From<VtlSet> for u16 {
    fn from(set: VtlSet) -> Self {
        set.bits.into_inner()
    }
}

openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs:2203

  • cvm_cpuid_result() no longer clears HV_CPUID_FUNCTION_MS_HV_FEATURES privileges when guest VSM is revoked. After revoke_guest_vsm() transitions to GuestVsmState::NotPlatformSupported, the guest can still observe access_vsm/access_vp_registers set in the features CPUID leaf, which regresses the previous behavior and makes revocation incomplete.
            CpuidFunction(hvdef::HV_CPUID_FUNCTION_MS_HV_ENLIGHTENMENT_INFORMATION) => {
                // If VSM has been revoked (or just isn't available) then don't
                // recommend the use of TLB flush hypercalls. They are only needed
                // for synchronization between VTLs, and the non-hypercall direct
                // path is always more efficient.
                if matches!(
                    *self.cvm_partition().guest_vsm.read(),
                    GuestVsmState::NotPlatformSupported
                ) {
                    [eax, ebx, ecx, edx] =
                        hvdef::HvEnlightenmentInformation::from_cpuid([eax, ebx, ecx, edx])
                            .with_use_hypercall_for_remote_flush_and_local_flush_entire(false)
                            .into_cpuid();
                }
            }

            _ => {}

Comment thread openhcl/virt_mshv_vtl/src/lib.rs
Copilot AI review requested due to automatic review settings August 12, 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 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (1)

openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs:383

  • VsmVpStatus is implemented in get_vp_register(), but validate_register_access() doesn’t apply the same access_vsm_privilege() gate as the other VSM-related registers. As a result, a VTL0 caller without access_vsm privilege can still read VsmVpStatus (while VsmPartitionStatus/VsmCapabilities are denied), which looks like an unintended access-control inconsistency.
            HvX64RegisterName::VsmPartitionStatus | HvX64RegisterName::VsmCapabilities => {

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

Labels

backport_1.8.2607 Change should be backported to the release/1.8.2607 branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cvm guest vsm: allow HV_VP_INDEX_SELF for EnableVpVtl cvm guest vsm: implement get register for vsmpartitionstatus and vsmvpstatus

5 participants