Skip to content

CVM register validation - #3960

Merged
jennagoddard merged 6 commits into
microsoft:mainfrom
jennagoddard:next
Jul 22, 2026
Merged

CVM register validation#3960
jennagoddard merged 6 commits into
microsoft:mainfrom
jennagoddard:next

Conversation

@jennagoddard

Copy link
Copy Markdown
Contributor

Add per-register / per-MSR validation on the SetVpRegisters and WRMSR paths to help prevent invalid VMSA state which cause failures at VMRUN

Copilot AI review requested due to automatic review settings July 16, 2026 23:04
@jennagoddard
jennagoddard marked this pull request as ready for review July 16, 2026 23:05
@jennagoddard
jennagoddard requested a review from a team as a code owner July 16, 2026 23:05

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@github-actions

Copy link
Copy Markdown

@smalis-msft

Copy link
Copy Markdown
Contributor

Whats the reason for needing this validation? Are we seeing callers pass bad values in and we can't just fix the callers? Should we not respect their decision to crash themselves?

Comment thread vm/x86/x86defs/src/lib.rs
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Outdated
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs
Comment thread openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs
@jennagoddard

Copy link
Copy Markdown
Contributor Author

Whats the reason for needing this validation? Are we seeing callers pass bad values in and we can't just fix the callers? Should we not respect their decision to crash themselves?

The issue is that if the guest writes invalid values to its registers, the next time the hypervisor tries to run the VMSA VMRUN fails with an invalid VMSA error. This is particularly bad as the host cannot read the VMSA to see what is invalid, and the VP cannot run.

@smalis-msft

Copy link
Copy Markdown
Contributor

We should probably trace a warn on any of these invalid writes then

@jennagoddard

Copy link
Copy Markdown
Contributor Author

We should probably trace a warn on any of these invalid writes then

I thought about it but thought it might be too much given how many occur though we can use rate limiting. The error will cause the guest to see a #GP, which is the right place for the error to surface to a misbehaving guest

Copilot AI review requested due to automatic review settings July 17, 2026 22:28

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 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Outdated
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Outdated
@github-actions

Copy link
Copy Markdown

Copilot AI review requested due to automatic review settings July 21, 2026 17:52

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

Comments suppressed due to low confidence (1)

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

  • CR0 normalization here clears some reserved low bits, but it still allows architecturally-invalid state to slip through:
  • CR0 bits 63:32 are reserved and should be forced to 0 (or rejected).
  • CR0.ET (bit 4) is architecturally fixed to 1 on x86_64 (TDX path already forces this via value | X64_CR0_ET).
    Leaving either case unhandled can still result in bad guest state being committed via set_registers() and later failing at entry/run time.
            HvX64RegisterName::Cr0 | HvX64RegisterName::IntermediateCr0 => {
                let mut cr0 = reg.value.as_u64();
                cr0 &= !X64_CR0_RESERVED_BITS_MASK_LOW32;
                // Bit 6 must be zero; PG requires PE; NW requires CD.
                if cr0 & X64_CR0_RSVDZ1_MASK != 0

Comment thread openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs
Copilot AI review requested due to automatic review settings July 21, 2026 19:02
@github-actions

Copy link
Copy Markdown

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.

Comments suppressed due to low confidence (1)

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

  • CR0 validation/normalization only clears a subset of reserved bits in the low 32 bits, but it leaves any bits set in CR0[63:32] untouched. Those upper bits are architecturally reserved and can propagate into the backing state via registers.cr0 = reg.value.as_u64(), potentially reintroducing the invalid state this validation is trying to prevent. Consider clearing the upper 32 bits (or rejecting nonzero upper bits) during normalization.
            HvX64RegisterName::Cr0 | HvX64RegisterName::IntermediateCr0 => {
                let mut cr0 = reg.value.as_u64();
                cr0 &= !X64_CR0_RESERVED_BITS_MASK_LOW32;
                // Bit 6 must be zero; PG requires PE; NW requires CD.
                if cr0 & X64_CR0_RSVDZ1_MASK != 0
                    || (cr0 & X64_CR0_PG != 0 && cr0 & X64_CR0_PE == 0)
                    || (cr0 & X64_CR0_NW != 0 && cr0 & X64_CR0_CD == 0)
                {
                    return Err(HvError::InvalidRegisterValue);
                }
                reg.value = HvRegisterValue::from(cr0);
            }

Comment thread vm/x86/x86defs/src/lib.rs
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Outdated
@github-actions

Copy link
Copy Markdown

Comment thread openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs Outdated
Comment thread openhcl/virt_mshv_vtl/src/processor/snp/mod.rs Outdated
Comment on lines +143 to +146
const CVM_GUEST_VA_BITS_48: u32 = 48;
const CVM_GUEST_VA_BITS_57: u32 = 57;
const X64_CR0_RESERVED_BITS_MASK_LOW32: u64 = 0x1FFA_FF80;
const X64_CR0_RSVDZ1_MASK: u64 = 1 << 6;

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.

Should these be in x86defs?

Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Outdated
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Outdated
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Outdated
Copilot AI review requested due to automatic review settings July 21, 2026 22:25

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 3 comments.

Comment on lines +232 to +240
x86defs::X64_MSR_KERNEL_GS_BASE
| x86defs::X86X_MSR_LSTAR
| x86defs::X86X_MSR_CSTAR
| x86defs::X86X_MSR_SYSENTER_EIP
| x86defs::X86X_MSR_SYSENTER_ESP
| x86defs::X86X_MSR_INTERRUPT_SSP_TABLE_ADDR => {
if !is_canonical_address(value, CVM_GUEST_VA_BITS_57) {
return Err(MsrError::InvalidAccess);
}
Comment on lines +661 to +665
| HvX64RegisterName::InterruptSspTableAddr => {
if !is_canonical_address(reg.value.as_u64(), CVM_GUEST_VA_BITS_57) {
return Err(HvError::InvalidRegisterValue);
}
}
Comment thread openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs
@github-actions

Copy link
Copy Markdown

@jennagoddard
jennagoddard merged commit 9986629 into microsoft:main Jul 22, 2026
97 of 101 checks passed
@mebersol mebersol added the backport_1.8.2607 Change should be backported to the release/1.8.2607 branch label Jul 22, 2026
jennagoddard added a commit to jennagoddard/openvmm that referenced this pull request Jul 24, 2026
Add per-register / per-MSR validation on the SetVpRegisters and WRMSR
paths to help prevent invalid VMSA state which cause failures at VMRUN
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.

6 participants