* [PATCH v2 0/1] TDX attestation support
@ 2025-04-16 5:54 Binbin Wu
2025-04-16 5:54 ` [PATCH v2 1/1] KVM: TDX: Handle TDG.VP.VMCALL<GetQuote> Binbin Wu
0 siblings, 1 reply; 3+ messages in thread
From: Binbin Wu @ 2025-04-16 5:54 UTC (permalink / raw)
To: pbonzini, seanjc, kvm
Cc: rick.p.edgecombe, kai.huang, adrian.hunter, reinette.chatre,
xiaoyao.li, tony.lindgren, isaku.yamahata, yan.y.zhao, chao.gao,
mikko.ylinen, linux-kernel, binbin.wu
Hi,
Paolo mentioned possibly wanting to include attestation in the initial TDX
support. Please consider it with that as the tentative plan. If it is not
included in the initial support, it would require an opt-in when the
support is added.
Notable changes since v1 [0]
============================
- KVM only checks the SHARED bit of the GPA from TDX guests and drops it
before exiting to userspace to avoid bleeding the SHARED bit into its
exit ABI [1]. Other sanity checks are skipped.
- Dropped the patch for TDG.VP.VMCALL<SetupEventNotifyInterrupt>, which has
no users.
- Use number 40 for KVM_EXIT_TDX_GET_QUOTE since this could probably win the
race upstream with AMD's SNP certificate-fetching patch [2].
Overview
========
TDX Guest-Host Communication Interface (GHCI) [3] spec defines two
TDVMCALLs for TDX attestation mechanism.
- TDG.VP.VMCALL<GetQuote>
GetQuote is a doorbell-like interface used by TDX guests to request VMM
to generate a TD-Quote signed by a service hosting TD-Quoting Enclave
operating on the host.
- TDG.VP.VMCALL<SetupEventNotifyInterrupt>
SetupEventNotifyInterrupt can be used by TDX guests to specify an
interrupt vector as an event-notify vector for GetQuote operation, which
may take several seconds. If a TDX guest has setup the event-notify
vector, the host VMM injects an interrupt with the specified vector to
the TDX guest on completion of the operation.
TDG.VP.VMCALL<SetupEventNotifyInterrupt> is optional and is not used by TDX
guests, this patch series adds only the support for TDG.VP.VMCALL<GetQuote>
to enable TDX attestation on KVM side. KVM forwards the requests to
userspace VMM. Instead of using a single KVM_EXIT_TDX, it's preferred that
each TDVMCALL that KVM wants to forward needs a dedicated KVM_EXIT_<reason>
and associated struct in the exit union [4]. The TDVMCALLs supported in [5]
reuse the existing KVM exit reasons. For TDX attestation support, add a TDX
specific KVM exit reasons based on the discussion in the PUCK meeting on
2025.02.19 [6]. After returning from userspace, KVM sets the return code
specified by userspace before resuming the vCPU.
Base of this series
===================
This series is based on kvm/next or kvm-coco-queue with the commit:
- 'fd02aa45bda6' ("Merge branch 'kvm-tdx-initial' into HEAD").
Repos
=====
The full KVM branch is here:
https://github.com/intel/tdx/tree/tdx_kvm_dev-2025-04-15
A matching QEMU is here:
https://github.com/intel-staging/qemu-tdx/tree/tdx-qemu-wip-2025-04-15
It requires TDX module 1.5.06.00.0744 [7], or later.
A working edk2 commit is 95d8a1c ("UnitTestFrameworkPkg: Use TianoCore
mirror of subhook submodule").
Testing
=======
This patch series has been tested as part of the development branch for the
TDX base series. The testing consisted of TDX kvm-unit-tests and booting a
Linux TD, and TDX enhanced KVM selftests. It also passed the TDX related
test cases defined in the LKVS test suite as described in:
https://github.com/intel/lkvs/blob/main/KVM/docs/lkvs_on_avocado.md
The functionality of GetQuote has been tested with the Quote Generation
Service deployed on the host, thanks to Mikko Ylinen.
KVM selftests patch below, which is based on the latest TDX KVM selftests
patch series [8], was used to test the flows of GetQuote as well:
https://github.com/intel/tdx/commit/12b51b65b88ee95c3b0ce8ebc623408ecd8eea49
[0] https://lore.kernel.org/kvm/20250402001557.173586-1-binbin.wu@linux.intel.com
[1] https://lore.kernel.org/kvm/Z_Z61UlNM1vlEdW1@google.com
[2] https://lore.kernel.org/kvm/20250219151505.3538323-2-michael.roth@amd.com
[3] https://cdrdv2.intel.com/v1/dl/getContent/726792
[4] https://lore.kernel.org/kvm/Zg18ul8Q4PGQMWam@google.com
[5] https://lore.kernel.org/kvm/20250222014225.897298-1-binbin.wu@linux.intel.com
[6] https://drive.google.com/file/d/1fk957DWsyqWk-K-FqhBxdUtgrQYcZrqH/view?usp=drive_link&resourcekey=0-JFJuzmaZIux6_D6lhcxT7Q
[7] https://github.com/intel/tdx-module/releases/tag/TDX_1.5.06
[8] https://lore.kernel.org/kvm/20250414214801.2693294-1-sagis@google.com
Binbin Wu (1):
KVM: TDX: Handle TDG.VP.VMCALL<GetQuote>
Documentation/virt/kvm/api.rst | 25 +++++++++++++++++++++++++
arch/x86/kvm/vmx/tdx.c | 30 ++++++++++++++++++++++++++++++
include/uapi/linux/kvm.h | 7 +++++++
3 files changed, 62 insertions(+)
--
2.46.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v2 1/1] KVM: TDX: Handle TDG.VP.VMCALL<GetQuote>
2025-04-16 5:54 [PATCH v2 0/1] TDX attestation support Binbin Wu
@ 2025-04-16 5:54 ` Binbin Wu
2025-04-16 10:35 ` Huang, Kai
0 siblings, 1 reply; 3+ messages in thread
From: Binbin Wu @ 2025-04-16 5:54 UTC (permalink / raw)
To: pbonzini, seanjc, kvm
Cc: rick.p.edgecombe, kai.huang, adrian.hunter, reinette.chatre,
xiaoyao.li, tony.lindgren, isaku.yamahata, yan.y.zhao, chao.gao,
mikko.ylinen, linux-kernel, binbin.wu
Handle TDVMCALL for GetQuote to generate a TD-Quote.
GetQuote is a doorbell-like interface used by TDX guests to request VMM
to generate a TD-Quote signed by a service hosting TD-Quoting Enclave
operating on the host. A TDX guest passes a TD Report (TDREPORT_STRUCT) in
a shared-memory area as parameter. Host VMM can access it and queue the
operation for a service hosting TD-Quoting enclave. When completed, the
Quote is returned via the same shared-memory area.
KVM only checks the GPA from the TDX guest has the shared-bit set and drops
the shared-bit before exiting to userspace to avoid bleeding the shared-bit
into KVM's exit ABI. KVM forwards the request to userspace VMM (e.g. QEMU)
and userspace VMM queues the operation asynchronously. KVM sets the return
code according to the 'ret' field set by userspace to notify the TDX guest
whether the request has been queued successfully or not. When the request
has been queued successfully, the TDX guest can poll the status field in
the shared-memory area to check whether the Quote generation is completed
or not. When completed, the generated Quote is returned via the same
buffer.
Add KVM_EXIT_TDX_GET_QUOTE as a new exit reason to userspace.
Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com>
Tested-by: Mikko Ylinen <mikko.ylinen@linux.intel.com>
---
v2:
- Skip sanity checks except for the check of the shared-bit. (Rick, Sean)
- Drop the shared-bit of the GPA before exiting to userspace. (Sean)
- Improve the description of 'ret' field in the document. (Kai)
- Use number 40 for KVM_EXIT_TDX_GET_QUOTE. (Xiaoyao, Rick)
- Update the changelog and the description of KVM_EXIT_TDX_GET_QUOTE in the
document according to the code changes.
---
Documentation/virt/kvm/api.rst | 25 +++++++++++++++++++++++++
arch/x86/kvm/vmx/tdx.c | 30 ++++++++++++++++++++++++++++++
include/uapi/linux/kvm.h | 7 +++++++
3 files changed, 62 insertions(+)
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index ad1859f4699e..b2192d2983fe 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -7162,6 +7162,31 @@ The valid value for 'flags' is:
- KVM_NOTIFY_CONTEXT_INVALID -- the VM context is corrupted and not valid
in VMCS. It would run into unknown result if resume the target VM.
+::
+
+ /* KVM_EXIT_TDX_GET_QUOTE */
+ struct tdx_get_quote {
+ __u64 ret;
+ __u64 gpa;
+ __u64 size;
+ };
+
+If the exit reason is KVM_EXIT_TDX_GET_QUOTE, then it indicates that a TDX
+guest has requested to generate a TD-Quote signed by a service hosting
+TD-Quoting Enclave operating on the host. The 'gpa' field and 'size' specify
+the guest physical address and size of a shared-memory buffer, in which the
+TDX guest passes a TD Report. KVM checks the GPA from the TDX guest has the
+shared-bit set and drops the shared-bit in 'gpa' field before exiting to
+userspace. KVM doesn't do other sanity checks. The 'ret' field represents the
+return value of the GetQuote request. KVM only bridges the request to the
+userspace VMM, and the userspace VMM is responsible for setting up the return
+value since only userspace knows whether the request has been queued
+successfully or not. KVM sets the return code according to the 'ret' field
+before returning back to the TDX guest. When the request has been queued
+successfully, the TDX guest can poll the status field in the shared-memory area
+to check whether the Quote generation is completed or not. When completed, the
+generated Quote is returned via the same buffer.
+
::
/* Fix the size of the union. */
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index b952bc673271..cd1e9a1c040e 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -1463,6 +1463,34 @@ static int tdx_get_td_vm_call_info(struct kvm_vcpu *vcpu)
return 1;
}
+static int tdx_complete_get_quote(struct kvm_vcpu *vcpu)
+{
+ tdvmcall_set_return_code(vcpu, vcpu->run->tdx_get_quote.ret);
+ return 1;
+}
+
+static int tdx_get_quote(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_tdx *tdx = to_tdx(vcpu);
+
+ u64 gpa = tdx->vp_enter_args.r12;
+ u64 size = tdx->vp_enter_args.r13;
+
+ /* The gpa of buffer must have shared bit set. */
+ if (vt_is_tdx_private_gpa(vcpu->kvm, gpa)) {
+ tdvmcall_set_return_code(vcpu, TDVMCALL_STATUS_INVALID_OPERAND);
+ return 1;
+ }
+
+ vcpu->run->exit_reason = KVM_EXIT_TDX_GET_QUOTE;
+ vcpu->run->tdx_get_quote.gpa = gpa & ~gfn_to_gpa(kvm_gfn_direct_bits(tdx->vcpu.kvm));
+ vcpu->run->tdx_get_quote.size = size;
+
+ vcpu->arch.complete_userspace_io = tdx_complete_get_quote;
+
+ return 0;
+}
+
static int handle_tdvmcall(struct kvm_vcpu *vcpu)
{
switch (tdvmcall_leaf(vcpu)) {
@@ -1472,6 +1500,8 @@ static int handle_tdvmcall(struct kvm_vcpu *vcpu)
return tdx_report_fatal_error(vcpu);
case TDVMCALL_GET_TD_VM_CALL_INFO:
return tdx_get_td_vm_call_info(vcpu);
+ case TDVMCALL_GET_QUOTE:
+ return tdx_get_quote(vcpu);
default:
break;
}
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index c6988e2c68d5..4d7e8e88bcc3 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -178,6 +178,7 @@ struct kvm_xen_exit {
#define KVM_EXIT_NOTIFY 37
#define KVM_EXIT_LOONGARCH_IOCSR 38
#define KVM_EXIT_MEMORY_FAULT 39
+#define KVM_EXIT_TDX_GET_QUOTE 40
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -447,6 +448,12 @@ struct kvm_run {
__u64 gpa;
__u64 size;
} memory_fault;
+ /* KVM_EXIT_TDX_GET_QUOTE */
+ struct {
+ __u64 ret;
+ __u64 gpa;
+ __u64 size;
+ } tdx_get_quote;
/* Fix the size of the union. */
char padding[256];
};
--
2.46.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH v2 1/1] KVM: TDX: Handle TDG.VP.VMCALL<GetQuote>
2025-04-16 5:54 ` [PATCH v2 1/1] KVM: TDX: Handle TDG.VP.VMCALL<GetQuote> Binbin Wu
@ 2025-04-16 10:35 ` Huang, Kai
0 siblings, 0 replies; 3+ messages in thread
From: Huang, Kai @ 2025-04-16 10:35 UTC (permalink / raw)
To: kvm@vger.kernel.org, pbonzini@redhat.com, seanjc@google.com,
binbin.wu@linux.intel.com
Cc: Gao, Chao, Edgecombe, Rick P, mikko.ylinen@linux.intel.com,
Li, Xiaoyao, Lindgren, Tony, Hunter, Adrian, Chatre, Reinette,
linux-kernel@vger.kernel.org, Zhao, Yan Y, Yamahata, Isaku
On Wed, 2025-04-16 at 13:54 +0800, Binbin Wu wrote:
> Handle TDVMCALL for GetQuote to generate a TD-Quote.
>
> GetQuote is a doorbell-like interface used by TDX guests to request VMM
> to generate a TD-Quote signed by a service hosting TD-Quoting Enclave
> operating on the host. A TDX guest passes a TD Report (TDREPORT_STRUCT) in
> a shared-memory area as parameter. Host VMM can access it and queue the
> operation for a service hosting TD-Quoting enclave. When completed, the
> Quote is returned via the same shared-memory area.
>
> KVM only checks the GPA from the TDX guest has the shared-bit set and drops
> the shared-bit before exiting to userspace to avoid bleeding the shared-bit
> into KVM's exit ABI. KVM forwards the request to userspace VMM (e.g. QEMU)
> and userspace VMM queues the operation asynchronously. KVM sets the return
> code according to the 'ret' field set by userspace to notify the TDX guest
> whether the request has been queued successfully or not. When the request
> has been queued successfully, the TDX guest can poll the status field in
> the shared-memory area to check whether the Quote generation is completed
> or not. When completed, the generated Quote is returned via the same
> buffer.
>
> Add KVM_EXIT_TDX_GET_QUOTE as a new exit reason to userspace.
>
> Signed-off-by: Binbin Wu <binbin.wu@linux.intel.com>
> Tested-by: Mikko Ylinen <mikko.ylinen@linux.intel.com>
Acked-by: Kai Huang <kai.huang@intel.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-04-16 10:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-16 5:54 [PATCH v2 0/1] TDX attestation support Binbin Wu
2025-04-16 5:54 ` [PATCH v2 1/1] KVM: TDX: Handle TDG.VP.VMCALL<GetQuote> Binbin Wu
2025-04-16 10:35 ` Huang, Kai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox