[RFC PATCH 14/15] x86/tdx: Add TDG.DMAR.ACCEPT module call wrapper for TDX Connect

From: Zhenzhong Duan

Date: Thu Sep 24 2026 - 00:15:17 EST


TDG.DMAR.ACCEPT updates the PASID table entry of the TDI as present to
allow DMA access to the TD private memory.

For TDG.DMAR.ACCEPT, the R8-R15 input registers are reserved and must
be zero. Use a zero-initialized argument structure with __tdcall_saved()
so the complete TDCALL input register set is loaded with the required
values.

Translate TDX module return codes into Linux errno values.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx>
---
arch/x86/coco/tdx/tdx_connect.c | 28 ++++++++++++++++++++++++++++
arch/x86/include/asm/shared/tdx.h | 1 +
arch/x86/include/asm/tdx.h | 1 +
3 files changed, 30 insertions(+)

diff --git a/arch/x86/coco/tdx/tdx_connect.c b/arch/x86/coco/tdx/tdx_connect.c
index 3ef10b1df401..a03b1da9a52a 100644
--- a/arch/x86/coco/tdx/tdx_connect.c
+++ b/arch/x86/coco/tdx/tdx_connect.c
@@ -136,3 +136,31 @@ int tdx_mcall_tdi_start(u64 func_id, u64 exp_bind_session)
return tdx_mcall_tdi_to_errno(ret);
}
EXPORT_SYMBOL_FOR_MODULES(tdx_mcall_tdi_start, "tdx-guest");
+
+/**
+ * tdx_mcall_dmar_accept() - Accept PASID table entry of a TDI instance
+ * @func_id: Function identifier specifying the TDI instance
+ * @target: DMAR target, 0 for non-partitioned TD or L1, 1-3 for L2 VM1-VM3,
+ * other value reserved
+ *
+ * Update the PASID table entry of the TDI to mark the DMA Remapping (DMAR)
+ * state as present, allowing DMA access to the TD private memory.
+ *
+ * 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_dmar_accept(u64 func_id, u64 target)
+{
+ struct tdx_module_args args = {
+ .rcx = func_id,
+ .rdx = target,
+ };
+ u64 ret;
+
+ ret = __tdcall_saved(TDG_DMAR_ACCEPT, &args);
+ if (!ret)
+ return 0;
+
+ return tdx_mcall_tdi_to_errno(ret);
+}
+EXPORT_SYMBOL_FOR_MODULES(tdx_mcall_dmar_accept, "tdx-guest");
diff --git a/arch/x86/include/asm/shared/tdx.h b/arch/x86/include/asm/shared/tdx.h
index 90f2842f4253..01387f6b24b3 100644
--- a/arch/x86/include/asm/shared/tdx.h
+++ b/arch/x86/include/asm/shared/tdx.h
@@ -22,6 +22,7 @@
#define TDG_VM_WR 8
#define TDG_TDI_READ 67
#define TDG_TDI_START 68
+#define TDG_DMAR_ACCEPT 70
#define TDG_MMIO_ACCEPT 71

/* TDX TD attributes */
diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
index 787b3039ef5a..118cc58cc909 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -157,6 +157,7 @@ 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);
int tdx_mcall_mmio_accept(u64 func_id, u64 index, u32 pg_offset, u32 page_cnt, phys_addr_t gpa);
int tdx_mcall_tdi_start(u64 func_id, u64 exp_bind_session);
+int tdx_mcall_dmar_accept(u64 func_id, u64 target);
#endif

void __init tdx_dump_attributes(u64 td_attr);
--
2.52.0