-
Notifications
You must be signed in to change notification settings - Fork 19
Merge tag 'rolling-lts/hcl-main/6.12.52.4' into project/hcl-dev/6.12 #112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
TD partitioning provides a timer service for L1 (VTL2) guest to set a preemption timer for L2 (VTL0) vCPUs. Add members for a new timer service to the tdx_vp_context struct for the L1 (VTL2) userspace to pass a timeout value down to the L1 (VTL2) kernel. Signed-off-by: Isaku Yamahata <[email protected]>
Refactor __tdcall() for a dedicated wrapper for TDG.VP.WR() operation. This prepares for additional calls of TDG.VP.WR() cleanly while avoiding repeated open-coding. No functional change intended. Signed-off-by: Isaku Yamahata <[email protected]>
Program the TD partitioning TSC deadline timer service for L2 (VTL0) vCPUs when the L1 (VTL2) userspace requests. Then, the TDX module sets preemption timer for L2 vCPU. If the timer expires, the L2 (VTL0) vCPU exits with a VMX preemption timer exit reason. The mshv_vtl driver then exits to the userspace, and the userspace is notified of the exit. The TDX module does not clear TDVPS deadline on a preemption timer exit. Disarm the TSC deadline explicitly on the preemption timer exit. Otherwise the following TDG.VP.ENTER() immediately exits without executing the L2 guest. Reported-by: Dexuan Cui <[email protected]> Signed-off-by: Isaku Yamahata <[email protected]>
As the tdcall is slow, cache the previously written TSC deadline value and skip unnecessary tdg.vp.wr(TSC deadline) if the value doesn't change. This is also a preparation for hlt emulation case that requires the previously written TSC deadline value. Signed-off-by: Isaku Yamahata <[email protected]>
The TDX timer service sets a preemption timer for the L2 (VTL0) vCPU. tdg.vp.enter() exits with preemption timer exit reason on timer expiry. The HLT emulation path needs extra change where the L1 (VTL2) kernel issues TDG.VP.VMCALL(HLT) because the host (L0) VMM doesn't know the L2 deadline timer value. When the L1 kernel issues TDG.VP.VMCALL(HLT), start per-CPU hrtimer to wake up from the L0 HLT emulation by L1 getting timer interrupt. Cancel the hrtimer after it returns from the L0 VMM. Signed-off-by: Isaku Yamahata <[email protected]>
On timer expiry path, it unconditionally issues tdg.vp.wr(TSC deadline = disarm). The following tdg.vp.enter() execution path may overwrite tdg.vp.wr(new TSC deadline). Delete the duplicated tdg.vp.wr() call as optimization. Signed-off-by: Isaku Yamahata <[email protected]>
Add an extension for the TDX timer service, so that the userspace can query the feature before use. Signed-off-by: Isaku Yamahata <[email protected]>
…akeup AP callback") The commit df21bf3 ("arch/x86: Provide the CPU number in the wakeup AP callback") changed the signature of struct apic::wakeup_secondary_cpu(), but it did not update numachip_wakeup_secondary(). Update it to fix the compile error. arch/x86/kernel/apic/apic_numachip.c:228:43: error: initialization of 'int (*)(u32, long unsigned int, unsigned int)' {aka 'int (*)(unsigned int, long unsigned int, unsigned int)'} from incompatible pointer type 'int (*)(u32, long unsigned int)' {aka 'int (*)(unsigned int, long unsigned int)'} [-Wincompatible-pointer-types] 228 | .wakeup_secondary_cpu = numachip_wakeup_secondary, | ^~~~~~~~~~~~~~~~~~~~~~~~~ Fixes: df21bf3 ("arch/x86: Provide the CPU number in the wakeup AP callback") Signed-off-by: Isaku Yamahata <[email protected]>
TDX module supports timer service for L1. When L1 writes tdcs value with TDG.VP.WR(TSC DEADLINE), tdg.vp.enter() exits with timer preemption when deadline expires. (Not injecting timer interrupt to L2 guest). Update tdx vp context shared between L1 kernel and L1 userspace so that openvmm can use TDX timer service. Unless the userspace uses it, the L1 OHCL kernel behavior keeps the same behavior as before.
Add ifdef and define to fix arm64 build.
drivers/hv/mshv_vtl_main.c: In function ‘mshv_tdx_setup_halt_timer’:
drivers/hv/mshv_vtl_main.c:1163:15: error: implicit declaration of function ‘rdtsc’ [-Werror=implicit-function-declaration]
1163 | now = rdtsc();
| ^~~~~
drivers/hv/mshv_vtl_main.c:1170:73: error: ‘tsc_khz’ undeclared (first use in this function)
1170 | time = mul_u64_u64_div_u64(deadline - now, 1000 * 1000, tsc_khz);
| ^~~~~~~
drivers/hv/mshv_vtl_main.c:1170:73: note: each undeclared identifier is reported only once for each function it appears in
drivers/hv/mshv_vtl_main.c: In function ‘mshv_vtl_switch_to_vtl0_irqoff’:
drivers/hv/mshv_vtl_main.c:1242:49: error: ‘MSHV_VTL_RUN_FLAG_HALTED’ undeclared (first use in this function)
1242 | armed = mshv_tdx_halt_timer_pre(flags & MSHV_VTL_RUN_FLAG_HALTED);
| ^~~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
Fixes: fc1601f ("mshv_vtl/tdx: Arm per-cpu timer to wake up from L0 HLT emulation")
Signed-off-by: Isaku Yamahata <[email protected]>
In case of !CONFIG_INTEL_TDX_GUEST, gcc complains as "parameter name omitted". Add missing parameter names. Fixes: 151bf98 ("mshv_vtl/tdx: Handle some APIC functionality in kernel") Signed-off-by: Isaku Yamahata <[email protected]>
Move up one of define(CONFIG_X86_64) && defined(CONFIG_INTEL_TDX_GUEST) for consistency. Fixes: 1bf0706 ("mshv_vtl/tdx: Set TSC deadline if userspace requests") Signed-off-by: Isaku Yamahata <[email protected]>
Fix arm64 build failure caused by this PR #107 build failure: drivers/hv/mshv_vtl_main.c: In function ‘mshv_tdx_setup_halt_timer’: drivers/hv/mshv_vtl_main.c:1163:15: error: implicit declaration of function ‘rdtsc’ [-Werror=implicit-function-declaration] 1163 | now = rdtsc(); | ^~~~~ drivers/hv/mshv_vtl_main.c:1170:73: error: ‘tsc_khz’ undeclared (first use in this function) 1170 | time = mul_u64_u64_div_u64(deadline - now, 1000 * 1000, tsc_khz); | ^~~~~~~ drivers/hv/mshv_vtl_main.c:1170:73: note: each undeclared identifier is reported only once for each function it appears in drivers/hv/mshv_vtl_main.c: In function ‘mshv_vtl_switch_to_vtl0_irqoff’: drivers/hv/mshv_vtl_main.c:1242:49: error: ‘MSHV_VTL_RUN_FLAG_HALTED’ undeclared (first use in this function) 1242 | armed = mshv_tdx_halt_timer_pre(flags & MSHV_VTL_RUN_FLAG_HALTED); | ^~~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors
…rted Returning -EOPNOTSUPP is a fatal error. It means that The driver doesn't know the feature. Not that the feature is not supported due to the runtime platform reason. Return 0 for MSHV_CAP_LOWER_VTL_TIMER_VIRT on non-TDX platform, which is safer. Fixes: 3528fd7 ("drivers: hv: mshv_vtl: Advertise TDX timer service extension") Signed-off-by: Isaku Yamahata <[email protected]>
…feature unsupported Returning -EOPNOTSUPP is a fatal error. It means that the driver doesn't know the feature. Not that the feature is not supported due to the runtime platform reason. Return 0 for MSHV_CAP_LOWER_VTL_TIMER_VIRT on non-TDX platform, which is safer. Fixes: 3528fd7: 3528fd7 ("drivers: hv: mshv_vtl: Advertise TDX timer service extension")
Signed-off-by: Hardik Garg <[email protected]>
There was a problem hiding this 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 merges TDX (Trust Domain Extensions) timer virtualization support from the product/hcl-main/6.12 branch, specifically adding L2 VM TSC deadline timer management for CVM (Confidential VM) workloads running under TDX isolation.
Key changes include:
- Addition of TSC deadline timer support for L2 VMs in TDX partitioning architecture
- Implementation of halt timer emulation to handle timer interrupts during HLT operations
- Extension of capability checks to support lower VTL timer virtualization
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| include/uapi/linux/mshv.h | Adds new capability flag MSHV_CAP_LOWER_VTL_TIMER_VIRT for timer virtualization support |
| drivers/hv/mshv_vtl_main.c | Implements TSC deadline timer handling, halt timer setup/cancellation, helper functions for timer conversion, and capability checks for TDX timer virtualization |
| drivers/hv/mshv_vtl.h | Adds tdx_l2_tsc_deadline structure to track timer deadline values and update flags, with corresponding padding adjustments to maintain alignment |
| arch/x86/kernel/apic/apic_numachip.c | Updates numachip_wakeup_secondary function signature to include cpu parameter for API compatibility |
| MSFT-Merge/config.json | Updates branch reference from product/underhill-dev/6.12 to product/underhill-main/6.12 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /* | ||
| * Userspace sets this bit for the kernel to issue TDG.VP.WR(TSC_DEADLINE) | ||
| * when it changed deadline. | ||
| * The kernel clears this bits on TDG.VP.WR(TSC_DEADLINE). |
Copilot
AI
Dec 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grammatical error: 'bits' should be singular 'bit' since only one bit (BIT(0)) is being cleared.
| * The kernel clears this bits on TDG.VP.WR(TSC_DEADLINE). | |
| * The kernel clears this bit on TDG.VP.WR(TSC_DEADLINE). |
| if (time < 0) | ||
| time = KTIME_MAX; |
Copilot
AI
Dec 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comparison if (time < 0) is checking a signed value (ktime_t is s64), but time is always non-negative at this point. When deadline > now, time is assigned a result from mul_u64_u64_div_u64 which returns u64, a non-negative value. When deadline <= now, time is initialized to 0. This condition will never be true and represents unreachable code.
| if (time < 0) | |
| time = KTIME_MAX; |
| } | ||
|
|
||
| static int numachip_wakeup_secondary(u32 phys_apicid, unsigned long start_rip) | ||
| static int numachip_wakeup_secondary(u32 phys_apicid, unsigned long start_rip, unsigned int cpu) |
Copilot
AI
Dec 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter cpu is added to the function signature but is not used in the function body. If this parameter is required for API compatibility, consider adding a comment explaining why it's unused, or use the __maybe_unused attribute to document the intentional non-use.
| static int numachip_wakeup_secondary(u32 phys_apicid, unsigned long start_rip, unsigned int cpu) | |
| static int numachip_wakeup_secondary(u32 phys_apicid, unsigned long start_rip, unsigned int __maybe_unused cpu) |
There was a problem hiding this comment.
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.
Mirror the CVM TDX changes from product/hcl-main/6.12 branch.
Buddy build for this update: https://msazure.visualstudio.com/LSG-linux/_build/results?buildId=146743117&view=results
Signed-off-by: Hardik Garg [email protected]