All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.