Skip to content

CVM register validation#3960

Open
jennagoddard wants to merge 6 commits into
microsoft:mainfrom
jennagoddard:next
Open

CVM register validation#3960
jennagoddard wants to merge 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

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.

5 participants