RE: [RFC PATCH 02/15] x86/tdx: Add TDCM hypercall wrapper for TDX Connect
From: Duan, Zhenzhong
Date: Thu Oct 29 2026 - 03:36:29 EST
>-----Original Message-----
>From: Li, Xiaoyao <xiaoyao.li@xxxxxxxxx>
>Subject: Re: [RFC PATCH 02/15] x86/tdx: Add TDCM hypercall wrapper for TDX
>Connect
>
>On 10/27/2026 2:08 PM, Duan, Zhenzhong wrote:
>>
>>
>>> -----Original Message-----
>>> From: Li, Xiaoyao <xiaoyao.li@xxxxxxxxx>
>>> Subject: Re: [RFC PATCH 02/15] x86/tdx: Add TDCM hypercall wrapper for
>TDX
>>> Connect
>>>
>>> On 10/27/2026 11:28 AM, Duan, Zhenzhong wrote:
>>>>>> Abstract the underlying leaf call and pass the shared buffer physical
>>>>>> address as a decrypted mapping. Add a runtime page alignment check
>>>>>> for the buffer to enforce correct usage.
>>>>> This doesn't match the implementation. The code only WARNs instead of
>>>>> enforcing
>>>>> correct usage.
>>>> You mean below code?
>>>>
>>>> static void tdx_devsec_unlock(struct pci_tsm *tsm)
>>>> {
>>>> struct tdx_devsec *tdevsec = to_tdx_devsec(tsm);
>>>> struct device_evidence *evidence = tsm->evidence;
>>>>
>>>> if (WARN_ON(tdx_tdi_unbind_dev(tdevsec)))
>>>> return;
>>>>
>>>> I think the unlock() callback should be defined with a return value so
>>>> userspace could catch the error.
>>>
>>> No. I meant just the code of tdx_hcall_tdcm()
>>>
>>> +u64 tdx_hcall_tdcm(u16 devid, void *buf, size_t size, u8 vector)
>>> +{
>>> + WARN_ON_ONCE(!PAGE_ALIGNED(buf) || !PAGE_ALIGNED(size));
>>> +
>>> + return _tdx_hypercall(TDVMCALL_TDCM, devid,
>>> cc_mkdec(virt_to_phys(buf)), size,
>>> vector);
>>> +}
>>>
>>> it warns on the unaligned buf and size, but the unaligned data are still
>>> consumed.
>>
>> The caller has guaranteed gpa and size are 4KB aligned.
>
>So far, no caller yet.
>
>> Meanwhile GHCI spec
>> requires passing 4KB aligned gpa and size, that means if we don't, the
>> hypercall will return failure. So maybe we can drop it?
>
>yeah. It should be OK to drop the WARN_ON_ONCE().
I have updated tdx_hcall_tdcm() to pass in a page pointer and page count
locally. I thought that could address your concern:
+/*
+ * tdx_hcall_tdcm - Send a TDCM command to the host via TDG.VP.VMCALL<TDCM>.
+ *
+ * @dev: PCI device identifying the TDI instance
+ * @buf_page: First page of a physically contiguous, shared buffer containing
+ * the TDCM command on input and the host response on output
+ * @nr_pages: Number of pages in the buffer
+ * @vector: Event notification interrupt vector, or 0 to poll for completion.
+ *
+ * The buffer physical address is passed to the host with decrypted/shared
+ * mark.
+ *
+ * Returns 0 on success or a TDX VMCALL status code on failure. See
+ * TDG.VP.VMCALL<TDCM> in the TDX GHCI v2.0 specification for status codes.
+ */
+u64 tdx_hcall_tdcm(struct pci_dev *dev, struct page *buf_page,
+ size_t nr_pages, u8 vector)
+{
+ return _tdx_hypercall(TDVMCALL_TDCM, pci_dev_id(dev),
+ cc_mkdec(page_to_phys(buf_page)),
+ nr_pages << PAGE_SHIFT, vector);
+}
+EXPORT_SYMBOL_FOR_MODULES(tdx_hcall_tdcm, "tdx-guest");