linux-coco.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
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);


  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).