[PATCH v15 20/23] KVM: selftests: Add a helper to issue TDVMCALLs from the TDX vm

From: Lisa Wang

Date: Thu Oct 01 2026 - 15:43:46 EST


From: Erdem Aktas <erdemaktas@xxxxxxxxxx>

TDX VMs need to notify the host, e.g. ucall. Add tdvmcall() to allow VMs
to issue TDG.VP.VMCALL with a single function call instead of
open-coding TDVMCALL registers setup at every call site.

The helper makes standard GHCI TDVMCALLs: the caller passes the GHCI
sub-function and up to four arguments and returns the TDVMCALL status
from R10.

Co-developed-by: Sagi Shahar <sagis@xxxxxxxxxx>
Signed-off-by: Sagi Shahar <sagis@xxxxxxxxxx>
Co-developed-by: Lisa Wang <wyihan@xxxxxxxxxx>
Signed-off-by: Lisa Wang <wyihan@xxxxxxxxxx>
Signed-off-by: Erdem Aktas <erdemaktas@xxxxxxxxxx>
Reviewed-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
tools/testing/selftests/kvm/include/x86/tdx/tdx.h | 9 ++++++
tools/testing/selftests/kvm/lib/x86/tdx/tdx.S | 39 +++++++++++++++++++++++
3 files changed, 49 insertions(+)

diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 9464168e361a..495de8ef8166 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -34,6 +34,7 @@ LIBKVM_x86 += lib/x86/tdx/tdx_util.c
LIBKVM_x86 += lib/x86/ucall.c
LIBKVM_x86 += lib/x86/vmx.c
LIBKVM_x86 += lib/x86/tdx/td_boot.S
+LIBKVM_x86 += lib/x86/tdx/tdx.S

LIBKVM_arm64 += lib/arm64/gic.c
LIBKVM_arm64 += lib/arm64/gic_v3.c
diff --git a/tools/testing/selftests/kvm/include/x86/tdx/tdx.h b/tools/testing/selftests/kvm/include/x86/tdx/tdx.h
new file mode 100644
index 000000000000..d41a1efc8a63
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/x86/tdx/tdx.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef SELFTEST_KVM_TDX_TDX_H
+#define SELFTEST_KVM_TDX_TDX_H
+
+#include <linux/types.h>
+
+u64 __tdvmcall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15);
+
+#endif /* SELFTEST_KVM_TDX_TDX_H */
diff --git a/tools/testing/selftests/kvm/lib/x86/tdx/tdx.S b/tools/testing/selftests/kvm/lib/x86/tdx/tdx.S
new file mode 100644
index 000000000000..e3f0f7f2232b
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/x86/tdx/tdx.S
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+.globl __tdvmcall
+/*
+ * u64 __tdvmcall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15)
+ */
+__tdvmcall:
+ push %r12
+ push %r13
+ push %r14
+ push %r15
+
+ /*
+ * Map C ABI fast arguments to TDX GHCI payload registers
+ * RDI=fn, RSI=r12, RDX=r13, RCX=r14, R8=r15
+ */
+ mov %rdi, %r11
+ mov %rsi, %r12
+ mov %rdx, %r13
+ mov %rcx, %r14
+ mov %r8, %r15
+
+ mov $0, %rax /* TDCALL leaf 0: TDG.VP.VMCALL */
+ mov $0xFC00, %rcx /* Expose R10-R15 */
+ mov $0, %r10 /* Standard GHCI call */
+
+ /* TDCALL instruction */
+ .byte 0x66, 0x0f, 0x01, 0xcc
+
+ /* Extract status */
+ mov %r10, %rax
+
+ pop %r15
+ pop %r14
+ pop %r13
+ pop %r12
+ ret
+
+.section .note.GNU-stack,"",%progbits

--
2.56.0.rc1.315.gc6ed9934b7-goog