From: Zhenzhong Duan <zhenzhong.duan@intel.com>
To: x86@kernel.org, linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org
Cc: dave.hansen@linux.intel.com, tglx@kernel.org, mingo@redhat.com,
bp@alien8.de, hpa@zytor.com, dave.hansen@intel.com,
kas@kernel.org, rick.p.edgecombe@intel.com, jgg@nvidia.com,
nicolinc@nvidia.com, aik@amd.com, aneesh.kumar@kernel.org,
seanjc@google.com, pbonzini@redhat.com, yilun.xu@linux.intel.com,
chao.gao@intel.com, vishal.l.verma@intel.com,
xiaoyao.li@intel.com, kevin.tian@intel.com,
chao.p.peng@intel.com
Subject: [RFC PATCH 03/15] x86/tdx: Add TDG.TDI.RD module call wrapper for TDX Connect
Date: Thu, 24 Sep 2026 12:10:20 +0800 [thread overview]
Message-ID: <20260924041032.1096569-4-zhenzhong.duan@intel.com> (raw)
In-Reply-To: <20260924041032.1096569-1-zhenzhong.duan@intel.com>
Introduce wrapper tdx_mcall_tdi_read() to provide tdx-guest driver with a
standard interface for querying specific metadata fields from a target
Trust Device Interface Control Structure (TDI_CS).
Explicitly mapping architectural TDX error codes into Linux POSIX errno
with two helpers, introducing tdx_mcall_to_errno() to handle general
module calls, while introducing tdx_mcall_tdi_to_errno() specifically for
TDI related module calls.
Unlike TDG.VP.VMCALL based hypercalls which communicate with the host,
TDG.TDI.RD is a module call (mcall) that communicates directly with the
TDX module. This distinction is reflected in the tdx_mcall_ naming
prefix, as opposed to tdx_hcall_ used for host-directed hypercalls.
Note that while host-bound hypercalls (such as tdx_hcall_tdcm()) pass a
platform-specific Device Identifier (devid), the func_id parameter used
here is defined by the TDISP standard (refer to Section 11.2 "TDISP
rules"). Although these values result in the same underlying bit format
when the PCI segment is zero, they represent separate structural
abstractions in their respective specifications.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
---
arch/x86/coco/tdx/tdx.c | 5 ----
arch/x86/coco/tdx/tdx_connect.c | 41 +++++++++++++++++++++++++++++++
arch/x86/include/asm/shared/tdx.h | 1 +
arch/x86/include/asm/tdx.h | 20 +++++++++++++++
4 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index 22cc177a6db4..c3db2451c078 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -34,11 +34,6 @@
#define VE_GET_PORT_NUM(e) ((e) >> 16)
#define VE_IS_IO_STRING(e) ((e) & BIT(4))
-/* TDX Module call error codes */
-#define TDCALL_RETURN_CODE(a) ((a) >> 32)
-#define TDCALL_INVALID_OPERAND 0xc0000100
-#define TDCALL_OPERAND_BUSY 0x80000200
-
#define TDREPORT_SUBTYPE_0 0
static atomic_long_t nr_shared;
diff --git a/arch/x86/coco/tdx/tdx_connect.c b/arch/x86/coco/tdx/tdx_connect.c
index 0c6ca650771a..1409b1a30cc6 100644
--- a/arch/x86/coco/tdx/tdx_connect.c
+++ b/arch/x86/coco/tdx/tdx_connect.c
@@ -8,6 +8,17 @@
#include <asm/tdx.h>
#include <linux/mm.h>
+static inline int tdx_mcall_tdi_to_errno(u64 ret)
+{
+ switch (TDCALL_RETURN_CODE(ret)) {
+ case TDCALL_TDI_NOT_PRESENT:
+ case TDCALL_TDI_INVALID_METADATA:
+ return -ENODEV;
+ default:
+ return tdx_mcall_to_errno(ret);
+ }
+}
+
/*
* tdx_hcall_tdcm - Send a TDCM command to the host via TDG.VP.VMCALL<TDCM>.
*
@@ -30,3 +41,33 @@ u64 tdx_hcall_tdcm(u16 devid, void *buf, size_t size, u8 vector)
return _tdx_hypercall(TDVMCALL_TDCM, devid, cc_mkdec(virt_to_phys(buf)), size, vector);
}
EXPORT_SYMBOL_FOR_MODULES(tdx_hcall_tdcm, "tdx-guest");
+
+/**
+ * tdx_mcall_tdi_read() - Read field from a Trust Device Interface Control Structure (TDI_CS)
+ * @func_id: Function identifier specifying the TDI_CS
+ * @field: Field identifier within the specified TDI_CS
+ * @value: Storage for the successfully retrieved field value
+ *
+ * Invokes the TDG.TDI.RD TDCALL to read the value of @field within the TDI_CS specified
+ * by @func_id.
+ *
+ * Return 0 on success, -ENXIO for invalid operands, -EBUSY for busy operation,
+ * -ENODEV for TDI not present or invalid metadata, or -EIO on other TDCALL failures.
+ */
+int tdx_mcall_tdi_read(u64 func_id, u64 field, u64 *value)
+{
+ struct tdx_module_args args = {
+ .rcx = func_id,
+ .rdx = field,
+ };
+ u64 ret;
+
+ ret = __tdcall_ret(TDG_TDI_READ, &args);
+ if (!ret) {
+ *value = args.rcx;
+ return 0;
+ }
+
+ return tdx_mcall_tdi_to_errno(ret);
+}
+EXPORT_SYMBOL_FOR_MODULES(tdx_mcall_tdi_read, "tdx-guest");
diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
index f46a3171a512..665c12925ff6 100644
--- a/arch/x86/include/asm/shared/tdx.h
+++ b/arch/x86/include/asm/shared/tdx.h
@@ -20,6 +20,7 @@
#define TDG_MEM_PAGE_ACCEPT 6
#define TDG_VM_RD 7
#define TDG_VM_WR 8
+#define TDG_TDI_READ 67
/* TDX TD attributes */
#define TDX_TD_ATTR_DEBUG_BIT 0
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index df4496ef8a6a..4937e23d5483 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -77,6 +77,25 @@ void tdx_halt(void);
bool tdx_early_handle_ve(struct pt_regs *regs);
+/* TDX Module call error codes */
+#define TDCALL_RETURN_CODE(a) ((a) >> 32)
+#define TDCALL_INVALID_OPERAND 0xc0000100
+#define TDCALL_OPERAND_BUSY 0x80000200
+#define TDCALL_TDI_NOT_PRESENT 0xc0000f40
+#define TDCALL_TDI_INVALID_METADATA 0xc0000f41
+
+static inline int tdx_mcall_to_errno(u64 ret)
+{
+ switch (TDCALL_RETURN_CODE(ret)) {
+ case TDCALL_INVALID_OPERAND:
+ return -ENXIO;
+ case TDCALL_OPERAND_BUSY:
+ return -EBUSY;
+ default:
+ return -EIO;
+ }
+}
+
u64 tdg_vm_rd(u64 field, u64 *value);
int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport);
@@ -87,6 +106,7 @@ u64 tdx_hcall_get_quote(u8 *buf, size_t size);
#ifdef CONFIG_TDX_CONNECT_GUEST
u64 tdx_hcall_tdcm(u16 devid, void *buf, size_t size, u8 vector);
+int tdx_mcall_tdi_read(u64 func_id, u64 field, u64 *value);
#endif
void __init tdx_dump_attributes(u64 td_attr);
--
2.52.0
next prev parent reply other threads:[~2026-09-24 4:11 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 4:10 [RFC PATCH 00/15] PCI/TSM: coco/tdx-guest: Implement TDX-Connect PCIe TDISP (phase2) Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 01/15] x86/tdx: Export tdg_vm_rd() for tdx-guest module Zhenzhong Duan
2026-09-30 22:13 ` Peter Fang
2026-10-01 12:38 ` Xu Yilun
2026-10-08 6:45 ` Duan, Zhenzhong
2026-10-08 16:30 ` Edgecombe, Rick P
2026-09-24 4:10 ` [RFC PATCH 02/15] x86/tdx: Add TDCM hypercall wrapper for TDX Connect Zhenzhong Duan
2026-09-24 4:10 ` Zhenzhong Duan [this message]
2026-09-25 0:06 ` [RFC PATCH 03/15] x86/tdx: Add TDG.TDI.RD module call " Edgecombe, Rick P
2026-10-08 6:27 ` Duan, Zhenzhong
2026-10-08 16:42 ` Edgecombe, Rick P
2026-10-09 2:28 ` Duan, Zhenzhong
2026-09-24 4:10 ` [RFC PATCH 04/15] virt: tdx-guest: Support devsec TSM for secure devices Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 05/15] virt: tdx-guest: Add TDCM helpers and TEE-IO support check Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 06/15] virt: tdx-guest: Support TDI bind and unbind operations Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 07/15] PCI/TSM: Track Device Interface Report MMIO range index Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 08/15] x86/tdx: Add TDG.MMIO.ACCEPT module call wrapper for TDX Connect Zhenzhong Duan
2026-09-24 23:41 ` Edgecombe, Rick P
2026-09-25 0:02 ` Edgecombe, Rick P
2026-10-08 6:01 ` Duan, Zhenzhong
2026-10-08 16:47 ` Edgecombe, Rick P
2026-10-08 5:49 ` Duan, Zhenzhong
2026-10-08 16:44 ` Edgecombe, Rick P
2026-10-09 2:16 ` Duan, Zhenzhong
2026-09-24 4:10 ` [RFC PATCH 09/15] virt: tdx-guest: Capture the TDI report during device lock Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 10/15] virt: tdx-guest: Set up and accept private MMIO ranges Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 11/15] x86/tdx: Add TDG.TDI.START module call wrapper for TDX Connect Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 12/15] virt: tdx-guest: Support Trust Device Interface (TDI) activation Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 13/15] x86/tdx: Add __tdcall_saved() helper Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 14/15] x86/tdx: Add TDG.DMAR.ACCEPT module call wrapper for TDX Connect Zhenzhong Duan
2026-09-24 4:10 ` [RFC PATCH 15/15] virt: tdx-guest: Accept default DMAR entry during PCI driver attach Zhenzhong Duan
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=20260924041032.1096569-4-zhenzhong.duan@intel.com \
--to=zhenzhong.duan@intel.com \
--cc=aik@amd.com \
--cc=aneesh.kumar@kernel.org \
--cc=bp@alien8.de \
--cc=chao.gao@intel.com \
--cc=chao.p.peng@intel.com \
--cc=dave.hansen@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jgg@nvidia.com \
--cc=kas@kernel.org \
--cc=kevin.tian@intel.com \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=nicolinc@nvidia.com \
--cc=pbonzini@redhat.com \
--cc=rick.p.edgecombe@intel.com \
--cc=seanjc@google.com \
--cc=tglx@kernel.org \
--cc=vishal.l.verma@intel.com \
--cc=x86@kernel.org \
--cc=xiaoyao.li@intel.com \
--cc=yilun.xu@linux.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