[PATCH v15 17/23] KVM: selftests: Set entry point for TDX guest code
From: Lisa Wang
Date: Thu Oct 01 2026 - 15:42:13 EST
From: Sagi Shahar <sagis@xxxxxxxxxx>
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 <sagis@xxxxxxxxxx>
Signed-off-by: Lisa Wang <wyihan@xxxxxxxxxx>
Reviewed-by: Xiaoyao Li <xiaoyao.li@xxxxxxxxx>
Reviewed-by: Binbin Wu <binbin.wu@xxxxxxxxxxxxxxx>
---
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 72497724a2ee..f36cddbd045c 100644
--- a/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
+++ b/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
@@ -71,5 +71,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 2d2160d68b9b..b4b76dc505ae 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -846,9 +846,13 @@ void vcpu_arch_set_entry_point(struct kvm_vcpu *vcpu, void *guest_code)
{
struct kvm_regs regs;
- vcpu_regs_get(vcpu, ®s);
- regs.rip = (unsigned long) guest_code;
- vcpu_regs_set(vcpu, ®s);
+ if (is_tdx_vm(vcpu->vm)) {
+ tdx_vcpu_set_entry_point(vcpu, guest_code);
+ } else {
+ vcpu_regs_get(vcpu, ®s);
+ regs.rip = (unsigned long)guest_code;
+ vcpu_regs_set(vcpu, ®s);
+ }
}
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 270a4ee1b7eb..5f10a7c1455d 100644
--- a/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c
+++ b/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c
@@ -102,6 +102,16 @@ void tdx_vcpu_load_boot_parameters(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
"ESP GVA must be within 32-bit address space for 32-bit boot code");
}
+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 =
+ ¶ms->per_vcpu[vcpu->id];
+
+ vcpu_params->guest_code = (u64)guest_code;
+}
+
static const struct kvm_tdx_capabilities *tdx_read_capabilities(struct kvm_vm *vm)
{
static struct kvm_tdx_capabilities *tdx_cap;
--
2.56.0.rc1.315.gc6ed9934b7-goog