Skip to content

Conversation

@balajimc55
Copy link
Collaborator

Implements #2028

This PR implements hardware timer virtualization for lower VTLs on TDX CVM usingL2-VM TSC deadline timer, an architectural capability provided by TDX module. This improves the CVM performance by eliminating guest exits to hypervisor for timer arming and expiry notifications for lower VTL's timer requirements.

The related changes in OHCL-kernel is implemented by microsoft/OHCL-Linux-Kernel#107

Background - TDX L2-VM TSC Deadline Timer

This allows VTL2 to set an execution deadline for lower VTLs. If the lower VTL is running when the deadline time arrives, it exits to VTL2 with exit reason VmxExitBasic::TIMER_EXPIRED.
If the TSC deadline is in the past during entry into lower VTL (i.e., TSC deadline value is lower than the current virtual TSC value), it will immediately exit back to VTL2 with exit reason VmxExitBasic::TIMER_EXPIRED.

The TSC deadline is set using TDG.VP.WR for TDVPS.TSC_DEADLINE[L2-VM Index].

Implementation

  • With these changes, openvmm evaluates earliest deadline across all lower VTLs and sets it in a tdx_vp_context ->tdx_l2_tsc_deadline_state that is shared with mshv_vtl driver.
  • During entry into lower VTL, mshv_vtl driver makes the TDG.VP.WR call to set the deadline when an update is needed.

Changes

  • Added HardwareIsolatedGuestTimer trait as an abstraction for managing lower VTL timer deadlines.
  • Moved current VmTime interface as default/fallback implementation into this trait.
  • Added TdxTscDeadlineService to implement the TDX specific timer virtualization.

@github-actions github-actions bot added the unsafe Related to unsafe code label Nov 23, 2025
@github-actions
Copy link

⚠️ Unsafe Code Detected

This PR modifies files containing unsafe Rust code. Extra scrutiny is required during review.

For more on why we check whole files, instead of just diffs, check out the Rustonomicon

@balajimc55 balajimc55 marked this pull request as ready for review November 24, 2025 08:24
@balajimc55 balajimc55 requested a review from a team as a code owner November 24, 2025 08:24
Copilot AI review requested due to automatic review settings November 24, 2025 08:24
Copy link
Contributor

Copilot AI left a comment

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 implements hardware timer virtualization for lower VTLs on TDX CVMs using the TDX L2-VM TSC deadline timer capability. This reduces guest exits to the hypervisor by handling timer operations directly in hardware, improving CVM performance.

Key changes:

  • Added HardwareIsolatedGuestTimer trait to abstract lower VTL timer deadline management
  • Implemented TdxTscDeadlineService for TDX-specific hardware timer virtualization
  • Refactored existing VmTime interface into the new trait as a fallback implementation

Reviewed changes

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

Show a summary per file
File Description
vm/x86/x86defs/src/vmx.rs Added TIMER_EXPIRED exit reason constant for TDX timer expiry
tmk/tmk_vmm/src/paravisor_vmm.rs Disabled lower VTL timer virtualization for TMK VMM
openhcl/virt_mshv_vtl/src/processor/tdx/mod.rs Implemented TDX TSC deadline timer service and integrated it into TDX backing
openhcl/virt_mshv_vtl/src/processor/snp/mod.rs Added timer interface delegation for SNP (using VmTime fallback)
openhcl/virt_mshv_vtl/src/processor/mod.rs Added timer deadline management methods to HardwareIsolatedBacking trait
openhcl/virt_mshv_vtl/src/processor/hardware_cvm/mod.rs Extracted timer management into new trait with VmTime fallback implementation
openhcl/virt_mshv_vtl/src/lib.rs Added configuration plumbing for lower VTL timer virtualization feature
openhcl/underhill_core/src/worker.rs Propagated timer virtualization configuration to partition parameters
openhcl/underhill_core/src/options.rs Added command-line option to disable lower VTL timer virtualization
openhcl/underhill_core/src/lib.rs Passed timer virtualization option to worker configuration
openhcl/hcl/src/protocol.rs Defined TDX L2 TSC deadline state structure in VP context
openhcl/hcl/src/ioctl/tdx.rs Added accessors for TDX L2 TSC deadline state
openhcl/hcl/src/ioctl.rs Added HCL capability check for lower VTL timer virtualization

Copy link
Member

@chris-oo chris-oo left a comment

Choose a reason for hiding this comment

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

looks reasonable but i want to also have @smalis-msft review. We also use this timer for VTL1 - have you tested that?

pub struct tdx_l2_tsc_deadline_state {
/// Timer deadline value in absolute virtual TSC units for this processor.
pub deadline: u64,
/// Indicates if the `mshv_vtl` driver should issue a `TDG.VP.WR` call to update the
Copy link
Member

Choose a reason for hiding this comment

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

i assume here a value of 1 - can we be specific what value is expected here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done


/// Returns true if `ref_time` is before `ref_time_last`.
///
/// Note that this is a relative comparison in the 64-bit space and is not
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure i understand the implications of this comment? or how this check cannot be transitive?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess it's because we wrap? That should be clarified.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done, clarified the comment.

fn clear_deadline(&self, vp: &mut UhProcessor<'_, T>);
}

/// Interface for managing lower VTL timer deadlines via `VmTime`.
Copy link
Member

Choose a reason for hiding this comment

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

nit: use doc links with "[VmTime]" since we're referring to an actual type here (or refer to the right type in the doc comment)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@github-actions
Copy link

private_dma_client: Arc<dyn DmaClient>,
hide_isolation: bool,
proxy_interrupt_redirect: bool,
lower_vtl_timer_virt: bool,
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to keep this field around? I think we could get rid of it and use other signals, like if some options are Some, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

Like what if this was only in BackingSharedParams instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We could, but it is also needed later in BackingPrivate::new() where it initializes the per-VP context needed for by this feature.

Copy link
Contributor

Choose a reason for hiding this comment

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

It could be put in BackingParams too. Or we could take my other idea of unconditionally storing a VmTimeGuestTimer somewhere and having TdxBackedShared just hold an Option<TdxTscDeadlineService> instead of doing a trait object. But I think I'd prefer to keep PartitionState holding only things that are needed at runtime, whereas this is only needed at construction.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. Moved this to BackingSharedParams
Added a method in the trait to signal if hardware virtualized timer is in use; let me know if this approach works.

On the suggestion of unconditionally storing a VmTimeGuestTimer object:
since VmTimeGuestTimer is only for managing lower vtl timers, when lower_vtl_timer_virt is supported, the backing is not going to need the VmTimeGuestTimer object.
So i felt the trait object might be more appropriate here. Also the above changes should hopefully address the concern around keeping only runtime stuff in the partition state.
But let me know if you strongly favor - unconditionally storing a VmTimeGuestTimer object, I can implement that instead.

@github-actions
Copy link

github-actions bot commented Dec 3, 2025

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

@balajimc55
Copy link
Collaborator Author

looks reasonable but i want to also have @smalis-msft review. We also use this timer for VTL1 - have you tested that?

@chris-oo Yes, we validated with VTL1 enabled on Windows guest and we don't see any issues. Performance improvements are consistent with expectation.

@github-actions
Copy link

github-actions bot commented Dec 5, 2025

@babayet2 babayet2 added the release-ci-required Add to a PR to trigger PR gates in release mode label Dec 11, 2025
@github-actions
Copy link

@github-actions
Copy link

@github-actions
Copy link

@balajimc55 balajimc55 marked this pull request as draft December 11, 2025 09:52
@balajimc55 balajimc55 marked this pull request as ready for review December 12, 2025 12:03
smalis-msft
smalis-msft previously approved these changes Dec 12, 2025
Copy link
Contributor

@smalis-msft smalis-msft left a comment

Choose a reason for hiding this comment

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

LGTM but waiting for Chris before merging

chris-oo
chris-oo previously approved these changes Dec 13, 2025
@balajimc55 balajimc55 dismissed stale reviews from chris-oo and smalis-msft via 29f4f46 December 15, 2025 22:40
@smalis-msft smalis-msft merged commit 01987f4 into microsoft:main Dec 16, 2025
56 checks passed
balajimc55 added a commit to balajimc55/openvmm that referenced this pull request Dec 16, 2025
Implements microsoft#2028

This PR implements hardware timer virtualization for lower VTLs on TDX
CVM usingL2-VM TSC deadline timer, an architectural capability provided
by TDX module. This improves the CVM performance by eliminating guest
exits to hypervisor for timer arming and expiry notifications for lower
VTL's timer requirements.

The related changes in OHCL-kernel is implemented by
microsoft/OHCL-Linux-Kernel#107

This allows VTL2 to set an execution deadline for lower VTLs. If the
lower VTL is running when the deadline time arrives, it exits to VTL2
with exit reason `VmxExitBasic::TIMER_EXPIRED`.
If the TSC deadline is in the past during entry into lower VTL (i.e.,
TSC deadline value is lower than the current virtual TSC value), it will
immediately exit back to VTL2 with exit reason
`VmxExitBasic::TIMER_EXPIRED`.

The TSC deadline is set using `TDG.VP.WR` for `TDVPS.TSC_DEADLINE[L2-VM
Index]`.

- With these changes, openvmm evaluates earliest deadline across all
lower VTLs and sets it in a `tdx_vp_context ->tdx_l2_tsc_deadline_state
` that is shared with `mshv_vtl` driver.
- During entry into lower VTL, `mshv_vtl` driver makes the `TDG.VP.WR`
call to set the deadline when an update is needed.

- Added `HardwareIsolatedGuestTimer` trait as an abstraction for
managing lower VTL timer deadlines.
- Moved current `VmTime` interface as default/fallback implementation
into this trait.
- Added `TdxTscDeadlineService` to implement the TDX specific timer
virtualization.
smalis-msft pushed a commit that referenced this pull request Dec 16, 2025
Clean cherry-pick of PR #2483 to support timer virtualization for lower
VTLs.
Issue - #2028
@benhillis
Copy link
Member

Backported to release/1.7.2511 in #2570

@benhillis benhillis added backported_1.7.2511 PR that has been backported to release/1.7.2511 and removed backport_1.7.2511 labels Dec 17, 2025
@benhillis
Copy link
Member

Backported to release/1.7.2511 in #2570

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

Labels

backported_1.7.2511 PR that has been backported to release/1.7.2511 release-ci-required Add to a PR to trigger PR gates in release mode unsafe Related to unsafe code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants