From: Jonathan Cameron <jonathan.cameron@huawei.com>
To: Dan Williams <dan.j.williams@intel.com>
Cc: <linux-coco@lists.linux.dev>, <linux-pci@vger.kernel.org>,
<xin@zytor.com>, <chao.gao@intel.com>,
Xu Yilun <yilun.xu@linux.intel.com>,
Zhenzhong Duan <zhenzhong.duan@intel.com>
Subject: Re: [RFC PATCH 05/27] x86/virt/tdx: Add tdx_page_array helpers for new TDX Module objects
Date: Thu, 30 Oct 2025 10:49:26 +0000 [thread overview]
Message-ID: <20251030104926.000066c3@huawei.com> (raw)
In-Reply-To: <20250919142237.418648-6-dan.j.williams@intel.com>
On Fri, 19 Sep 2025 07:22:14 -0700
Dan Williams <dan.j.williams@intel.com> wrote:
> From: Xu Yilun <yilun.xu@linux.intel.com>
>
> Add struct tdx_page_array definition for new TDX Module object
> types - HPA_ARRAY_T and HPA_LIST_INFO. They are used as input/output
> parameters in newly defined SEAMCALLs. Also define some helpers to
> allocate, setup and free tdx_page_array.
>
> HPA_ARRAY_T and HPA_LIST_INFO are similar in most aspects. They both
> represent a list of pages for TDX Module accessing. There are several
> use cases for these 2 structures:
>
> - As SEAMCALL inputs. They are claimed by TDX Module as control pages.
> - As SEAMCALL outputs. They were TDX Module control pages and now are
> released.
> - As SEAMCALL inputs. They are just medium for exchanging data blobs
> in one SEAMCALL. TDX Module will not hold them as control pages.
>
> The 2 structures both need a 'root page' which contains a list of HPAs.
> They compress the HPA of the root page and the number of valid HPAs into
> a 64 bit raw value for SEAMCALL parameters. The root page is always a
> medium for passing data pages, TDX Module never keeps the root page.
>
> A main difference is HPA_ARRAY_T requires singleton mode when
> containing just 1 functional page (page0). In this mode the root page is
> not needed and the HPA field of the raw value directly points to the
> page0.
>
> Another small difference is HPA_LIST_INFO contains a 'first entry' field
> which could be filled by TDX Module. This simplifies host by providing
> the same structure when re-invoke the interrupted SEAMCALL. No need for
> host to touch this field.
>
> Typical usages of the tdx_page_array:
>
> 1. Add control pages:
> - struct tdx_page_array *array = tdx_page_array_create(nr_pages, ...);
> - seamcall(TDH_XXX_CREATE, array, ...);
>
> 2. Release control pages:
> - seamcall(TDX_XXX_DELETE, array, &nr_released, &released_hpa);
> - tdx_page_array_ctrl_release(array, nr_released, released_hpa);
>
> 3. Exchange data blobs:
> - struct tdx_page_array *array = tdx_page_array_create(nr_pages, ...);
> - seamcall(TDX_XXX, array, ...);
> - Read data from array.
> - tdx_page_array_free(array);
>
> 4. Note the root page contains 512 HPAs at most, if more pages are
> required, refilling the tdx_page_array is needed.
>
> - struct tdx_page_array *array = tdx_page_array_alloc(nr_pages, ...);
> - for each 512-page bulk
> - tdx_page_array_fill_root(array, offset);
> - seamcall(TDH_XXX_ADD, array, ...);
>
> In case 2, SEAMCALLs output the released page array in the form of
> HPA_ARRAY_T or PAGE_LIST_INFO. tdx_page_array_ctrl_release() is
> responsible for checking if the output pages match the original input
> pages. If failed to match, the safer way is to leak the control pages,
> tdx_page_array_ctrl_leak() should be called.
>
> The usage of tdx_page_array will be in following patches.
>
> Co-developed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
> Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
One trivial thing + I think that introduction of a DEFINE_FREE() needs
to be more obvious to MM folk that it will be buried in here.
Looks fine but needs an Ack.
> diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
> index ada2fd4c2d54..bc5b8e288546 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.c
> +++ b/arch/x86/virt/vmx/tdx/tdx.c
> +static bool tdx_page_array_ctrl_match(struct tdx_page_array *array,
> + unsigned int offset,
> + unsigned int nr_released,
> + u64 released_hpa)
> +{
> + unsigned int nents;
> + u64 *entries;
> + int i;
> +
> + if (offset >= array->nr_pages)
> + return 0;
> +
> + nents = umin(array->nr_pages - offset, TDX_PAGE_ARRAY_MAX_NENTS);
> +
> + if (nents != nr_released) {
> + pr_err("%s nr_released [%d] doesn't match page array nents [%d]\n",
> + __func__, nr_released, nents);
> + return false;
> + }
> +
> + if (!array->root) {
> + if (page_to_phys(array->pages[0]) != released_hpa) {
> + pr_err("%s released_hpa [0x%llx] doesn't match page0 hpa [0x%llx]\n",
> + __func__, released_hpa,
> + page_to_phys(array->pages[0]));
> + return false;
> + }
> +
> + return true;
> + }
> +
> + if (page_to_phys(array->root) != released_hpa) {
> + pr_err("%s released_hpa [0x%llx] doesn't match root page hpa [0x%llx]\n",
> + __func__, released_hpa, page_to_phys(array->root));
> + return 0;
return false
> + }
> +
> + entries = (u64 *)page_address(array->root);
> + for (i = 0; i < nents; i++) {
> + if (page_to_phys(array->pages[offset + i]) != entries[i]) {
> + pr_err("%s entry[%d] [0x%llx] doesn't match page hpa [0x%llx]\n",
> + __func__, i, entries[i],
> + page_to_phys(array->pages[offset + i]));
> + return false;
> + }
> + }
> +
> + return true;
> +}
> +
> +/* For releasing control pages which are created by tdx_page_array_create() */
> +int tdx_page_array_ctrl_release(struct tdx_page_array *array,
> + unsigned int nr_released,
> + u64 released_hpa)
> +{
> + int i;
> + u64 r;
> +
> + if (WARN_ON(array->nr_pages > TDX_PAGE_ARRAY_MAX_NENTS))
> + return -EINVAL;
> +
> + if (WARN_ON(!tdx_page_array_ctrl_match(array, 0, nr_released,
> + released_hpa)))
> + return -EFAULT;
> +
> + for (i = 0; i < array->nr_pages; i++) {
> + r = tdh_phymem_page_wbinvd_hkid(tdx_global_keyid,
> + array->pages[i]);
> + if (WARN_ON(r))
> + return -EFAULT;
> + }
> +
> + tdx_page_array_free(array);
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(tdx_page_array_ctrl_release);
> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
> index 5ebf26fcdcfa..f0a651155872 100644
> --- a/include/linux/gfp.h
> +++ b/include/linux/gfp.h
> @@ -385,6 +385,8 @@ extern void free_pages(unsigned long addr, unsigned int order);
> #define __free_page(page) __free_pages((page), 0)
> #define free_page(addr) free_pages((addr), 0)
>
> +DEFINE_FREE(__free_page, struct page *, if (_T) __free_page(_T))
This is at least more 'normal' than the CCA set one for free_page.
Burying it down here means getting an MM review. I'd be tempted to find
an alternative use somewhere else and post this stand alone to get that
review done.
> +
> void page_alloc_init_cpuhp(void);
> int decay_pcp_high(struct zone *zone, struct per_cpu_pages *pcp);
> void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp);
next prev parent reply other threads:[~2025-10-30 10:49 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-19 14:22 [RFC PATCH 00/27] PCI/TSM: TDX Connect: SPDM Session and IDE Establishment Dan Williams
2025-09-19 14:22 ` [RFC PATCH 01/27] coco/tdx-host: Introduce a "tdx_host" device Dan Williams
2025-10-30 10:16 ` Jonathan Cameron
2025-11-03 23:01 ` dan.j.williams
2025-09-19 14:22 ` [RFC PATCH 02/27] x86/virt/tdx: Move bit definitions of TDX_FEATURES0 to public header Dan Williams
2025-09-19 14:22 ` [RFC PATCH 03/27] coco/tdx-host: Support Link TSM for TDX host Dan Williams
2025-10-30 10:31 ` Jonathan Cameron
2025-11-03 23:04 ` dan.j.williams
2025-09-19 14:22 ` [RFC PATCH 04/27] x86/virt/tdx: Move tdx_errno.h from KVM to public place Dan Williams
2025-09-22 11:47 ` Huang, Kai
2025-09-19 14:22 ` [RFC PATCH 05/27] x86/virt/tdx: Add tdx_page_array helpers for new TDX Module objects Dan Williams
2025-10-30 10:49 ` Jonathan Cameron [this message]
2025-11-03 23:17 ` dan.j.williams
2025-09-19 14:22 ` [RFC PATCH 06/27] x86/virt/tdx: Add SEAMCALL wrappers for TDH.EXT.MEM.ADD and TDH.EXT.INIT Dan Williams
2025-09-19 14:22 ` [RFC PATCH 07/27] TODO: x86/virt/tdx: Read TDX global metadata for TDX Module Extensions Dan Williams
2025-09-19 14:22 ` [RFC PATCH 08/27] x86/virt/tdx: Add tdx_enable_ext() to enable of " Dan Williams
2025-10-30 10:55 ` Jonathan Cameron
2025-11-05 9:14 ` Xu Yilun
2025-09-19 14:22 ` [RFC PATCH 09/27] ACPICA: Add KEYP table definitions Dan Williams
2025-10-06 14:41 ` Samuel Ortiz
2025-10-10 7:35 ` Xu Yilun
2025-09-19 14:22 ` [RFC PATCH 10/27] acpi: Add KEYP support to fw_table parsing Dan Williams
2025-09-19 14:22 ` [RFC PATCH 11/27] acpi: Add KEYP Key Configuration Unit parsing Dan Williams
2025-10-30 11:02 ` Jonathan Cameron
2025-11-05 10:18 ` Xu Yilun
2025-09-19 14:22 ` [RFC PATCH 12/27] iommu/vt-d: Cache max domain ID to avoid redundant calculation Dan Williams
2025-09-19 14:22 ` [RFC PATCH 13/27] iommu/vt-d: Reserve the MSB domain ID bit for the TDX module Dan Williams
2025-09-19 14:22 ` [RFC PATCH 14/27] TODO: x86/virt/tdx: Read TDX Connect global metadata for TDX Connect Dan Williams
2025-09-19 14:22 ` [RFC PATCH 15/27] x86/virt/tdx: Extend tdx_page_array to support IOMMU_MT Dan Williams
2025-10-30 11:07 ` Jonathan Cameron
2025-09-19 14:22 ` [RFC PATCH 16/27] x86/virt/tdx: Add SEAMCALL wrappers for trusted IOMMU setup and clear Dan Williams
2025-09-19 14:22 ` [RFC PATCH 17/27] iommu/vt-d: Export a helper to do function for each dmar_drhd_unit Dan Williams
2025-09-19 14:22 ` [RFC PATCH 18/27] coco/tdx-host: Setup all trusted IOMMUs on TDX Connect init Dan Williams
2025-10-30 11:09 ` Jonathan Cameron
2025-09-19 14:22 ` [RFC PATCH 19/27] coco/tdx-host: Add a helper to exchange SPDM messages through DOE Dan Williams
2025-10-30 11:15 ` Jonathan Cameron
2025-09-19 14:22 ` [RFC PATCH 20/27] coco/tdx-host: Add connect()/disconnect() handlers prototype Dan Williams
2025-10-30 11:20 ` Jonathan Cameron
2025-11-03 23:34 ` dan.j.williams
2025-11-06 5:18 ` Xu Yilun
2025-11-10 11:45 ` Jonathan Cameron
2025-11-11 0:51 ` dan.j.williams
2025-11-13 2:51 ` Xu Yilun
2025-11-14 20:19 ` dan.j.williams
2025-11-17 4:56 ` Xu Yilun
2025-09-19 14:22 ` [RFC PATCH 21/27] x86/virt/tdx: Add SEAMCALL wrappers for SPDM management Dan Williams
2025-10-30 11:24 ` Jonathan Cameron
2025-11-03 23:38 ` dan.j.williams
2025-09-19 14:22 ` [RFC PATCH 22/27] coco/tdx-host: Implement SPDM session setup Dan Williams
2025-10-30 11:36 ` Jonathan Cameron
2025-11-06 7:35 ` Xu Yilun
2025-09-19 14:22 ` [RFC PATCH 23/27] PCI: iov: Export pci_iov_virtfn_bus() Dan Williams
2025-09-19 14:22 ` [RFC PATCH 24/27] PCI/IDE: Add helpers for RID/Addr Association Registers setup Dan Williams
2025-09-19 14:22 ` [RFC PATCH 25/27] PCI/IDE: Export pci_ide_domain() Dan Williams
2025-09-19 14:22 ` [RFC PATCH 26/27] x86/virt/tdx: Add SEAMCALL wrappers for IDE stream management Dan Williams
2025-10-30 11:37 ` Jonathan Cameron
2025-09-19 14:22 ` [RFC PATCH 27/27] coco/tdx-host: Implement IDE stream setup/teardown Dan Williams
2025-10-30 11:43 ` Jonathan Cameron
2025-11-04 0:13 ` dan.j.williams
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=20251030104926.000066c3@huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=chao.gao@intel.com \
--cc=dan.j.williams@intel.com \
--cc=linux-coco@lists.linux.dev \
--cc=linux-pci@vger.kernel.org \
--cc=xin@zytor.com \
--cc=yilun.xu@linux.intel.com \
--cc=zhenzhong.duan@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).