From: Sean Christopherson <seanjc@google.com>
To: Peter Fang <peter.fang@intel.com>
Cc: Xiaoyao Li <xiaoyao.li@intel.com>, Lisa Wang <wyihan@google.com>,
Andrew Jones <ajones@ventanamicro.com>,
Ackerley Tng <ackerleytng@google.com>,
Binbin Wu <binbin.wu@linux.intel.com>,
Chao Gao <chao.gao@intel.com>,
Chenyi Qiang <chenyi.qiang@intel.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
Erdem Aktas <erdemaktas@google.com>,
Ira Weiny <ira.weiny@intel.com>,
Isaku Yamahata <isaku.yamahata@intel.com>,
Kiryl Shutsemau <kas@kernel.org>,
linux-kselftest@vger.kernel.org,
Paolo Bonzini <pbonzini@redhat.com>,
"Pratik R. Sampat" <pratikrajesh.sampat@amd.com>,
Reinette Chatre <reinette.chatre@intel.com>,
Rick Edgecombe <rick.p.edgecombe@intel.com>,
Roger Wang <runanwang@google.com>,
Ryan Afranji <afranji@google.com>,
Sagi Shahar <sagis@google.com>, Shuah Khan <shuah@kernel.org>,
Oliver Upton <oupton@kernel.org>,
Jeremiah McReynolds <jmcrey@google.com>,
kvm@vger.kernel.org, linux-coco@lists.linux.dev,
linux-kernel@vger.kernel.org, x86@kernel.org
Subject: Re: [PATCH v14 21/22] KVM: selftests: Add ucall support for TDX
Date: Fri, 28 Aug 2026 07:18:47 -0700 [thread overview]
Message-ID: <apGYxwdCSuC-X732@google.com> (raw)
In-Reply-To: <20260828042044.GG33657@pedri>
[-- Attachment #1: Type: text/plain, Size: 3227 bytes --]
On Thu, Aug 27, 2026, Peter Fang wrote:
> On Fri, Aug 28, 2026 at 10:31:14AM +0800, Xiaoyao Li wrote:
> > >
> > > Hmm... This makes me wonder if vm->arch.s_bit below could be replaced
> > > with the same architectural approach. GPAW is available through
> > > TDG.VP.INFO or the initial RBX value. This does require a bit more
> > > plumbing though.
> >
> > I'm afraid not. Because below is host code, and vm->arch.s_bit is not used
> > in guest code.
> >
> > Or are suggesting something like dropping the
> >
> > if (is_tdx_vm(vm)) {
> > ucall_mmio_gpa = UCALL_MMIO_GPA | vm->arch.s_bit;
> > sync_global_to_guest(vm, ucall_mmio_gpa);
> > }
> >
> > entirely and use below hardcoded value instead in guest code?
> >
> > UCALL_MMIO_GPA | 1 << (GPAW - 1)
>
> Yeah this is what I meant. Just drop sync_global_to_guest() entirely and
> do things like a normal TDX guest would.
Blech. Every time I come back to this series we're still discussing ucall crud,
and "doing thing like a normal TDX guest". Selftests aren't normal guests.
I know I suggested using the HPET base, but I only did so very begrudgingly as I
couldn't come up with a better alternative to emulated MMIO, and the end result
is quite gross. Not only does the code ignore @mmio_gpa but still obviously use
emulated MMIO, it requires synchronizing data to the guest because KVM disallows
"private" MMIO.
void ucall_arch_init(struct kvm_vm *vm, gpa_t mmio_gpa)
{
vm_type = vm->type;
sync_global_to_guest(vm, vm_type);
if (is_tdx_vm(vm)) {
ucall_mmio_gpa = UCALL_MMIO_GPA | vm->arch.s_bit;
sync_global_to_guest(vm, ucall_mmio_gpa);
}
}
Retrieving GPA via TDG.VP.INFO isn't any better, it's still an absurd amount of
"work" for something that should be trivial.
Can't we just abuse TDVMCALL_REPORT_FATAL_ERROR? AFAICT, there's no restriction
on the data payload, and there's enough space to all but guarantee we'll never get
a false positive.
Pulling in Xiaoyao's idea about using CPUID...
> > +void ucall_arch_init(struct kvm_vm *vm, gpa_t mmio_gpa)
> > +{
> > + vm_type = vm->type;
> > + sync_global_to_guest(vm, vm_type);
>
> It works and it looks simple. But we have the architectural approach to
> test if a guest is TD guest, by checking the CPUID 0x21.
>
> Since checking CPUID 0x21 is not complex, and as a bonus it can help
> test if TDX module behaves correctly for CPUID leaf 0x21, I think we
> should switch to use CPUID 0x21 to check if it is TDX VM in guest code?
Absolutely not. It will require at least one an extra VM-Exit for TDX and non-TDX
guests alike, and thanks to Intel's wonderful CPUID behavior of having unsupported
leaves return the last supported leaf, the guest would have to check CPUID.0x0 and
then CPUID.0x21 on modern hardware, i.e. would incur two extra VM-Exits. I don't
care about the performance, but from a debug perspective that's going to be awful,
as what should be a super simple operation will be polluted with unwanted data.
Stop trying to reinvent the wheel and just use a virtual function table.
I've verified the attached patches don't break non-TDX selftests, someone just
needs to test the TDX changes.
[-- Attachment #2: 0001-KVM-selftests-Add-support-for-per-VM-ucall-ops-on-x8.patch --]
[-- Type: text/x-diff, Size: 2865 bytes --]
From 659487e0a9862900b052836229e3ac366c602f59 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <seanjc@google.com>
Date: Fri, 28 Aug 2026 06:46:51 -0700
Subject: [PATCH 1/3] KVM: selftests: Add support for per-VM ucall ops on x86
Add a layer of indirection to x86's ucall infrastructure to allow wiring up
a different set of {do,get}_ucall() operations for TDX VMs. TDX can't use
port I/O (at least, not robustly), as the TDX ABI doesn't allow the guest
to share arbitrary register state with the host on a PIO exit, and the PIO
data payload is limited to 4 bytes, i.e. would potentially truncate the
address of the per-ucall structure.
No functional change intended, as the ops are still hardwirte to the common
x86 ucall functions.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
.../testing/selftests/kvm/include/x86/ucall.h | 6 +----
tools/testing/selftests/kvm/lib/x86/ucall.c | 27 +++++++++++++++++--
2 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/x86/ucall.h b/tools/testing/selftests/kvm/include/x86/ucall.h
index 0e4950041e3e..3639f03a4da9 100644
--- a/tools/testing/selftests/kvm/include/x86/ucall.h
+++ b/tools/testing/selftests/kvm/include/x86/ucall.h
@@ -2,12 +2,8 @@
#ifndef SELFTEST_KVM_UCALL_H
#define SELFTEST_KVM_UCALL_H
-#include "kvm_util.h"
+#include "linux/kvm.h"
#define UCALL_EXIT_REASON KVM_EXIT_IO
-static inline void ucall_arch_init(struct kvm_vm *vm, gpa_t mmio_gpa)
-{
-}
-
#endif
diff --git a/tools/testing/selftests/kvm/lib/x86/ucall.c b/tools/testing/selftests/kvm/lib/x86/ucall.c
index e7dd5791959b..444d0f0ba138 100644
--- a/tools/testing/selftests/kvm/lib/x86/ucall.c
+++ b/tools/testing/selftests/kvm/lib/x86/ucall.c
@@ -8,7 +8,7 @@
#define UCALL_PIO_PORT ((u16)0x1000)
-void ucall_arch_do_ucall(gva_t uc)
+static void ucall_x86_do_ucall(gva_t uc)
{
/*
* FIXME: Revert this hack (the entire commit that added it) once nVMX
@@ -42,7 +42,7 @@ void ucall_arch_do_ucall(gva_t uc)
HORRIFIC_L2_UCALL_CLOBBER_HACK);
}
-void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu)
+static void *ucall_x86_get_ucall(struct kvm_vcpu *vcpu)
{
struct kvm_run *run = vcpu->run;
@@ -54,3 +54,26 @@ void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu)
}
return NULL;
}
+
+static struct {
+ void (*do_ucall)(gva_t uc);
+ void *(*get_ucall)(struct kvm_vcpu *vcpu);
+} ucall_x86_ops = {
+ .do_ucall = ucall_x86_do_ucall,
+ .get_ucall = ucall_x86_get_ucall,
+};
+
+void ucall_arch_init(struct kvm_vm *vm, gpa_t mmio_gpa)
+{
+ sync_global_to_guest(vm, ucall_x86_ops);
+}
+
+void ucall_arch_do_ucall(gva_t uc)
+{
+ return ucall_x86_ops.do_ucall(uc);
+}
+
+void *ucall_arch_get_ucall(struct kvm_vcpu *vcpu)
+{
+ return ucall_x86_ops.get_ucall(vcpu);
+}
base-commit: 8ab7454faa8be2d6c1fc29c857b9f9611ddb174b
--
2.55.0.897.gb25b4bd76c-goog
[-- Attachment #3: 0002-KVM-selftests-Add-support-for-TDX-ucalls-via-TDVMCAL.patch --]
[-- Type: text/x-diff, Size: 3671 bytes --]
From 60f3e988c65048c63217ec157e9ec228a4c484b7 Mon Sep 17 00:00:00 2001
From: Sean Christopherson <seanjc@google.com>
Date: Fri, 28 Aug 2026 06:52:56 -0700
Subject: [PATCH 2/3] KVM: selftests: Add support for TDX ucalls, via
TDVMCALL_REPORT_FATAL_ERROR
Add support for doing ucalls on TDX by abusing TDVMCALL_REPORT_FATAL_ERROR
to pass the address of the payload to the host. The "fatal error" TDVMCALL
is perfectly suited for passing information to host userspace, is both the
TDX Module and KVM allow the guest to pass (almost) all registers to the
host, i.e. provide enough of a data payload to make a collision with a real
fatal error practically impossible.
TDX can't use port I/O, as the TDX ABI doesn't allow the guest to share
arbitrary register state with the host on a port I/O exit, and the port I/O
data payload is limited to 4 bytes, i.e. would potentially truncate the
ucall address.
Alternatively, TDX could use MMIO, but using a magic emulated MMIO address
is fragile (see the TODO in __vm_create()), especially for TDX since TDX
doesn't support read-only memslots, i.e. doesn't have line of sight towards
addressing the TODO. E.g. TDX could hardcode the address to something that
is all but guaranteed to be unused on x86, e.g. the I/O APIC base address
or the HPET address, but that doesn't truly address the fragility concerns,
and it's ugly because ucall_arch_init() would completely ignore the passed
in @mmio_gpa despite obviously utilizing emulated MMIO.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
.../selftests/kvm/include/x86/tdx/tdx.h | 7 +++++
tools/testing/selftests/kvm/lib/x86/ucall.c | 27 ++++++++++++++++++-
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/include/x86/tdx/tdx.h b/tools/testing/selftests/kvm/include/x86/tdx/tdx.h
index 6355a30bb47f..6582e6c99697 100644
--- a/tools/testing/selftests/kvm/include/x86/tdx/tdx.h
+++ b/tools/testing/selftests/kvm/include/x86/tdx/tdx.h
@@ -4,6 +4,13 @@
#include <linux/types.h>
+/* TDX hypercall Leaf IDs */
+#define TDVMCALL_GET_TD_VM_CALL_INFO 0x10000
+#define TDVMCALL_MAP_GPA 0x10001
+#define TDVMCALL_GET_QUOTE 0x10002
+#define TDVMCALL_REPORT_FATAL_ERROR 0x10003
+#define TDVMCALL_SETUP_EVENT_NOTIFY_INTERRUPT 0x10004
+
#define TDG_VP_VMCALL_VE_REQUEST_MMIO 48
#define TDVMCALL_MMIO_WRITE 1
diff --git a/tools/testing/selftests/kvm/lib/x86/ucall.c b/tools/testing/selftests/kvm/lib/x86/ucall.c
index 444d0f0ba138..93686e1dd3f3 100644
--- a/tools/testing/selftests/kvm/lib/x86/ucall.c
+++ b/tools/testing/selftests/kvm/lib/x86/ucall.c
@@ -5,8 +5,28 @@
* Copyright (C) 2018, Red Hat, Inc.
*/
#include "kvm_util.h"
+#include "tdx/tdx.h"
+#include "tdx/tdx_util.h"
-#define UCALL_PIO_PORT ((u16)0x1000)
+#define UCALL_PIO_PORT ((u16)0x1000)
+#define UCALL_TDX_MAGIC 0xabacadabaULL
+
+static void ucall_tdx_do_ucall(gva_t uc)
+{
+ __tdcall(TDVMCALL_REPORT_FATAL_ERROR, UCALL_TDX_MAGIC, uc, 0, 0);
+}
+
+static void *ucall_tdx_get_ucall(struct kvm_vcpu *vcpu)
+{
+ struct kvm_run *run = vcpu->run;
+
+ if (run->exit_reason == KVM_EXIT_SYSTEM_EVENT &&
+ run->system_event.type == KVM_SYSTEM_EVENT_TDX_FATAL &&
+ run->system_event.data[12] == UCALL_TDX_MAGIC)
+ return (void *)(run->system_event.data[13]);
+
+ return NULL;
+}
static void ucall_x86_do_ucall(gva_t uc)
{
@@ -65,6 +85,11 @@ static struct {
void ucall_arch_init(struct kvm_vm *vm, gpa_t mmio_gpa)
{
+ if (is_tdx_vm(vm)) {
+ ucall_x86_ops.do_ucall = ucall_tdx_do_ucall;
+ ucall_x86_ops.get_ucall = ucall_tdx_get_ucall;
+ }
+
sync_global_to_guest(vm, ucall_x86_ops);
}
--
2.55.0.897.gb25b4bd76c-goog
next prev parent reply other threads:[~2026-08-28 14:18 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-22 23:13 [PATCH v14 00/22] TDX KVM selftests Lisa Wang
2026-07-22 23:13 ` [PATCH v14 01/22] KVM: selftests: Add macros to simplify creating VM shapes for non-default types Lisa Wang
2026-08-19 7:44 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 02/22] KVM: selftests: Update kvm_init_vm_address_properties() for TDX Lisa Wang
2026-08-13 23:17 ` Edgecombe, Rick P
2026-07-22 23:13 ` [PATCH v14 03/22] KVM: selftests: Initialize the TDX VM Lisa Wang
2026-07-23 8:44 ` Xiaoyao Li
2026-08-13 23:41 ` Edgecombe, Rick P
2026-08-15 9:17 ` Xiaoyao Li
2026-08-13 23:41 ` Edgecombe, Rick P
2026-08-14 21:18 ` Peter Fang
2026-08-20 8:46 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 04/22] KVM: selftests: TDX: Use KVM_TDX_CAPABILITIES to validate TDs' attribute configuration Lisa Wang
2026-08-13 23:45 ` Edgecombe, Rick P
2026-07-22 23:13 ` [PATCH v14 05/22] KVM: selftests: Expose segment definitions to assembly files Lisa Wang
2026-08-13 23:50 ` Edgecombe, Rick P
2026-07-22 23:13 ` [PATCH v14 06/22] tools: include: Add kbuild.h for assembly structure offsets Lisa Wang
2026-07-22 23:13 ` [PATCH v14 07/22] KVM: selftests: Introduce structures for TDX guest boot parameters Lisa Wang
2026-07-22 23:13 ` [PATCH v14 08/22] KVM: selftests: Add TDX boot code Lisa Wang
2026-07-23 11:17 ` Xiaoyao Li
2026-08-21 5:16 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 09/22] KVM: selftests: Expose functions to get default sregs values Lisa Wang
2026-07-23 10:19 ` Xiaoyao Li
2026-08-14 0:44 ` Edgecombe, Rick P
2026-08-14 2:36 ` Xiaoyao Li
2026-08-14 15:14 ` Edgecombe, Rick P
2026-07-22 23:13 ` [PATCH v14 10/22] KVM: selftests: Set up TDX boot code region Lisa Wang
2026-07-23 10:24 ` Xiaoyao Li
2026-08-24 19:27 ` Peter Fang
2026-08-24 20:00 ` Sean Christopherson
2026-08-26 8:31 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 11/22] KVM: selftests: Set up TDX boot parameters region Lisa Wang
2026-07-23 10:34 ` Xiaoyao Li
2026-08-11 6:32 ` Binbin Wu
2026-08-25 8:14 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 12/22] KVM: selftests: Require guest_memfd for TDX VMs Lisa Wang
2026-08-11 7:43 ` Binbin Wu
2026-08-14 7:42 ` Xiaoyao Li
2026-07-22 23:13 ` [PATCH v14 13/22] KVM: selftests: Support guest_memfd in-place conversion Lisa Wang
2026-08-18 8:17 ` Xiaoyao Li
2026-08-25 21:53 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 14/22] KVM: selftests: Expose function to allocate vCPU stack Lisa Wang
2026-08-14 8:10 ` Xiaoyao Li
2026-07-22 23:13 ` [PATCH v14 15/22] KVM: selftests: Call KVM_TDX_INIT_VCPU when creating a new TDX vcpu Lisa Wang
2026-08-14 8:32 ` Xiaoyao Li
2026-08-18 8:58 ` Binbin Wu
2026-08-26 21:22 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 16/22] KVM: selftests: Load per-vCPU guest stack in TDX boot parameters Lisa Wang
2026-08-14 8:39 ` Xiaoyao Li
2026-08-26 22:17 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 17/22] KVM: selftests: Set entry point for TDX guest code Lisa Wang
2026-08-14 8:43 ` Xiaoyao Li
2026-08-18 9:04 ` Binbin Wu
2026-07-22 23:13 ` [PATCH v14 18/22] KVM: selftests: Add helpers to init TDX memory and finalize VM Lisa Wang
2026-08-17 6:47 ` Xiaoyao Li
2026-08-17 13:52 ` Ackerley Tng
2026-08-18 7:33 ` Xiaoyao Li
2026-07-22 23:13 ` [PATCH v14 19/22] KVM: selftests: Finalize TD memory as part of kvm_arch_vm_finalize_vcpus Lisa Wang
2026-08-17 7:04 ` Xiaoyao Li
2026-08-27 7:51 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 20/22] KVM: selftests: Implement MMIO WRITE for the TDX VM Lisa Wang
2026-07-28 22:56 ` Ackerley Tng
2026-08-17 8:56 ` Xiaoyao Li
2026-08-27 9:19 ` Peter Fang
2026-07-22 23:13 ` [PATCH v14 21/22] KVM: selftests: Add ucall support for TDX Lisa Wang
2026-08-17 8:38 ` Xiaoyao Li
2026-08-28 2:06 ` Peter Fang
2026-08-28 2:31 ` Xiaoyao Li
2026-08-28 4:20 ` Peter Fang
2026-08-28 14:18 ` Sean Christopherson [this message]
2026-07-22 23:13 ` [PATCH v14 22/22] KVM: selftests: Add TDX lifecycle test Lisa Wang
2026-08-17 9:04 ` Xiaoyao Li
2026-08-28 4:33 ` Peter Fang
2026-08-13 22:47 ` [PATCH v14 00/22] TDX KVM selftests Edgecombe, Rick P
2026-08-13 23:05 ` Edgecombe, Rick P
2026-08-17 4:19 ` Ackerley Tng
2026-08-17 17:54 ` Edgecombe, Rick P
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=apGYxwdCSuC-X732@google.com \
--to=seanjc@google.com \
--cc=ackerleytng@google.com \
--cc=afranji@google.com \
--cc=ajones@ventanamicro.com \
--cc=binbin.wu@linux.intel.com \
--cc=chao.gao@intel.com \
--cc=chenyi.qiang@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=erdemaktas@google.com \
--cc=ira.weiny@intel.com \
--cc=isaku.yamahata@intel.com \
--cc=jmcrey@google.com \
--cc=kas@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=oupton@kernel.org \
--cc=pbonzini@redhat.com \
--cc=peter.fang@intel.com \
--cc=pratikrajesh.sampat@amd.com \
--cc=reinette.chatre@intel.com \
--cc=rick.p.edgecombe@intel.com \
--cc=runanwang@google.com \
--cc=sagis@google.com \
--cc=shuah@kernel.org \
--cc=wyihan@google.com \
--cc=x86@kernel.org \
--cc=xiaoyao.li@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).