On 7/23/2026 7:13 AM, Lisa Wang wrote:
From: Sagi Shahar <[email protected]>

Since the rip register is inaccessible for TDX VMs, we need a different
way to set the guest entry point for TDX VMs. This is done by writing
the guest code address to a predefined location in the guest memory and
loading it into rip as part of the TDX boot code.

Signed-off-by: Sagi Shahar <[email protected]>
Signed-off-by: Lisa Wang <[email protected]>

Reviewed-by: Xiaoyao Li <[email protected]>

---
  tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h |  1 +
  tools/testing/selftests/kvm/lib/x86/processor.c        | 10 +++++++---
  tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c     | 10 ++++++++++
  3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h 
b/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
index 93ce6e1ad2c8..307e2c0bc9c9 100644
--- a/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
+++ b/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
@@ -70,5 +70,6 @@ void tdx_vm_setup_boot_code_region(struct kvm_vm *vm);
  void tdx_vm_setup_boot_parameters_region(struct kvm_vm *vm, u32 
nr_runnable_vcpus);
  void tdx_vm_load_common_boot_parameters(struct kvm_vm *vm);
  void tdx_vcpu_load_boot_parameters(struct kvm_vm *vm, struct kvm_vcpu *vcpu);
+void tdx_vcpu_set_entry_point(struct kvm_vcpu *vcpu, void *guest_code);
#endif /* SELFTESTS_TDX_TDX_UTIL_H */
diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c 
b/tools/testing/selftests/kvm/lib/x86/processor.c
index 5e415c6577b8..4b97a9a1bb5e 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -808,9 +808,13 @@ void vcpu_arch_set_entry_point(struct kvm_vcpu *vcpu, void 
*guest_code)
  {
        struct kvm_regs regs;
- vcpu_regs_get(vcpu, &regs);
-       regs.rip = (unsigned long) guest_code;
-       vcpu_regs_set(vcpu, &regs);
+       if (is_tdx_vm(vcpu->vm)) {
+               tdx_vcpu_set_entry_point(vcpu, guest_code);
+       } else {
+               vcpu_regs_get(vcpu, &regs);
+               regs.rip = (unsigned long)guest_code;
+               vcpu_regs_set(vcpu, &regs);
+       }
  }
gva_t kvm_allocate_vcpu_stack(struct kvm_vm *vm)
diff --git a/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c 
b/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c
index 3c3ac6c7ce40..be63d8652a02 100644
--- a/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c
+++ b/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c
@@ -114,6 +114,16 @@ void tdx_vcpu_load_boot_parameters(struct kvm_vm *vm, 
struct kvm_vcpu *vcpu)
        vcpu_params->esp_gva = kvm_allocate_vcpu_stack(vm);
  }
+void tdx_vcpu_set_entry_point(struct kvm_vcpu *vcpu, void *guest_code)
+{
+       struct td_boot_parameters *params =
+               addr_gpa2hva(vcpu->vm, TD_BOOT_PARAMETERS_GPA);
+       struct td_per_vcpu_parameters *vcpu_params =
+               &params->per_vcpu[vcpu->id];
+
+       vcpu_params->guest_code = (u64)guest_code;
+}
+
  static struct kvm_tdx_capabilities *tdx_read_capabilities(struct kvm_vm *vm)
  {
        static struct kvm_tdx_capabilities *tdx_cap;



Reply via email to