From: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
To: "kvm@vger.kernel.org" <kvm@vger.kernel.org>,
"pbonzini@redhat.com" <pbonzini@redhat.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: "Zhao, Yan Y" <yan.y.zhao@intel.com>,
"sean.j.christopherson@intel.com"
<sean.j.christopherson@intel.com>,
"Huang, Kai" <kai.huang@intel.com>,
"dave.hansen@linux.intel.com" <dave.hansen@linux.intel.com>,
"Yamahata, Isaku" <isaku.yamahata@intel.com>
Subject: Re: [PATCH 10/13] x86/virt/tdx: Add SEAMCALL wrappers to remove a TD private page
Date: Fri, 3 Jan 2025 01:36:41 +0000 [thread overview]
Message-ID: <f35eff4bf646adad3463b655382e249007a3ff7c.camel@intel.com> (raw)
In-Reply-To: <20250101074959.412696-11-pbonzini@redhat.com>
On Wed, 2025-01-01 at 02:49 -0500, Paolo Bonzini wrote:
> From: Isaku Yamahata <isaku.yamahata@intel.com>
>
> TDX architecture introduces the concept of private GPA vs shared GPA,
> depending on the GPA.SHARED bit. The TDX module maintains a single Secure
> EPT (S-EPT or SEPT) tree per TD to translate TD's private memory accessed
> using a private GPA. Wrap the SEAMCALL TDH.MEM.PAGE.REMOVE with
> tdh_mem_page_remove() and TDH_PHYMEM_PAGE_WBINVD with
> tdh_phymem_page_wbinvd_hkid() to unmap a TD private page from the SEPT,
> remove the TD private page from the TDX module and flush cache lines to
> memory after removal of the private page.
>
> Callers should specify "GPA" and "level" when calling tdh_mem_page_remove()
> to indicate to the TDX module which TD private page to unmap and remove.
>
> TDH.MEM.PAGE.REMOVE may fail, and the caller of tdh_mem_page_remove() can
> check the function return value and retrieve extended error information
> from the function output parameters. Follow the TLB tracking protocol
> before calling tdh_mem_page_remove() to remove a TD private page to avoid
> SEAMCALL failure.
>
> After removing a TD's private page, the TDX module does not write back and
> invalidate cache lines associated with the page and the page's keyID (i.e.,
> the TD's guest keyID). Therefore, provide tdh_phymem_page_wbinvd_hkid() to
> allow the caller to pass in the TD's guest keyID and invoke
> TDH_PHYMEM_PAGE_WBINVD to perform this action.
>
> Before reusing the page, the host kernel needs to map the page with keyID 0
> and invoke movdir64b() to convert the TD private page to a normal shared
> page.
>
> TDH.MEM.PAGE.REMOVE and TDH_PHYMEM_PAGE_WBINVD may meet contentions inside
> the TDX module for TDX's internal resources. To avoid staying in SEAM mode
> for too long, TDX module will return a BUSY error code to the kernel
> instead of spinning on the locks. The caller may need to handle this error
> in specific ways (e.g., retry). The wrappers return the SEAMCALL error code
> directly to the caller. Don't attempt to handle it in the core kernel.
>
> [Kai: Switched from generic seamcall export]
> [Yan: Re-wrote the changelog]
> Co-developed-by: Sean Christopherson <sean.j.christopherson@intel.com>
> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
> Signed-off-by: Kai Huang <kai.huang@intel.com>
> Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Signed-off-by: Yan Zhao <yan.y.zhao@intel.com>
> Message-ID: <20241112073658.22157-1-yan.y.zhao@intel.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> arch/x86/include/asm/tdx.h | 2 ++
> arch/x86/virt/vmx/tdx/tdx.c | 27 +++++++++++++++++++++++++++
> arch/x86/virt/vmx/tdx/tdx.h | 1 +
> 3 files changed, 30 insertions(+)
>
> diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
> index f0b7b7b7d506..74938f725481 100644
> --- a/arch/x86/include/asm/tdx.h
> +++ b/arch/x86/include/asm/tdx.h
> @@ -157,8 +157,10 @@ u64 tdh_vp_wr(struct tdx_vp *vp, u64 field, u64 data, u64 mask);
> u64 tdh_vp_init_apicid(struct tdx_vp *vp, u64 initial_rcx, u32 x2apicid);
> u64 tdh_phymem_page_reclaim(struct page *page, u64 *tdx_pt, u64 *tdx_owner, u64 *tdx_size);
> u64 tdh_mem_track(struct tdx_td *tdr);
> +u64 tdh_mem_page_remove(struct tdx_td *td, u64 gpa, u64 level, u64 *rcx, u64 *rdx);
> u64 tdh_phymem_cache_wb(bool resume);
> u64 tdh_phymem_page_wbinvd_tdr(struct tdx_td *td);
> +u64 tdh_phymem_page_wbinvd_hkid(u64 hpa, u64 hkid);
> #else
> static inline void tdx_init(void) { }
> static inline int tdx_cpu_enable(void) { return -ENODEV; }
> diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
> index c7e6f30d0a14..cde55e9b3280 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.c
> +++ b/arch/x86/virt/vmx/tdx/tdx.c
> @@ -1761,6 +1761,23 @@ u64 tdh_mem_track(struct tdx_td *td)
> }
> EXPORT_SYMBOL_GPL(tdh_mem_track);
>
> +u64 tdh_mem_page_remove(struct tdx_td *td, u64 gpa, u64 level, u64 *rcx, u64 *rdx)
level could be an int instead of a u64. An enum was also discussed, but
considered to be not completely necessary. Probably we could even lose the level
arg, depending on what we want to do about the one for page.aug.
> +{
> + struct tdx_module_args args = {
> + .rcx = gpa | level,
Yan had "= gpa | (level & 0x7)" here, to make sure to only apply bits 0-2.
> + .rdx = tdx_tdr_pa(td),
> + };
> + u64 ret;
> +
> + ret = seamcall_ret(TDH_MEM_PAGE_REMOVE, &args);
> +
> + *rcx = args.rcx;
> + *rdx = args.rdx;
Switch to extended_err1/2 if the others get changed.
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(tdh_mem_page_remove);
> +
> u64 tdh_phymem_cache_wb(bool resume)
> {
> struct tdx_module_args args = {
> @@ -1780,3 +1797,13 @@ u64 tdh_phymem_page_wbinvd_tdr(struct tdx_td *td)
> return seamcall(TDH_PHYMEM_PAGE_WBINVD, &args);
> }
> EXPORT_SYMBOL_GPL(tdh_phymem_page_wbinvd_tdr);
> +
> +u64 tdh_phymem_page_wbinvd_hkid(u64 hpa, u64 hkid)
> +{
> + struct tdx_module_args args = {};
> +
> + args.rcx = hpa | (hkid << boot_cpu_data.x86_phys_bits);
> +
> + return seamcall(TDH_PHYMEM_PAGE_WBINVD, &args);
> +}
> +EXPORT_SYMBOL_GPL(tdh_phymem_page_wbinvd_hkid);
> diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h
> index 4b0ad536afd9..d49cdd9b0577 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.h
> +++ b/arch/x86/virt/vmx/tdx/tdx.h
> @@ -33,6 +33,7 @@
> #define TDH_PHYMEM_PAGE_RDMD 24
> #define TDH_VP_RD 26
> #define TDH_PHYMEM_PAGE_RECLAIM 28
> +#define TDH_MEM_PAGE_REMOVE 29
> #define TDH_SYS_KEY_CONFIG 31
> #define TDH_SYS_INIT 33
> #define TDH_SYS_RD 34
next prev parent reply other threads:[~2025-01-03 1:36 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-01 7:49 [PATCH v2 00/13] x86/virt/tdx: Add SEAMCALL wrappers for KVM Paolo Bonzini
2025-01-01 7:49 ` [PATCH 01/13] x86/virt/tdx: Add SEAMCALL wrappers for TDX KeyID management Paolo Bonzini
2025-01-02 19:44 ` Edgecombe, Rick P
2025-01-01 7:49 ` [PATCH 02/13] x86/virt/tdx: Add SEAMCALL wrappers for TDX TD creation Paolo Bonzini
2025-01-03 17:51 ` Edgecombe, Rick P
2025-01-01 7:49 ` [PATCH 03/13] x86/virt/tdx: Add SEAMCALL wrappers for TDX vCPU creation Paolo Bonzini
2025-01-01 7:49 ` [PATCH 04/13] x86/virt/tdx: Add SEAMCALL wrappers for TDX page cache management Paolo Bonzini
2025-01-01 7:49 ` [PATCH 05/13] x86/virt/tdx: Add SEAMCALL wrappers for TDX VM/vCPU field access Paolo Bonzini
2025-01-01 7:49 ` [PATCH 06/13] x86/virt/tdx: Add SEAMCALL wrappers for TDX flush operations Paolo Bonzini
2025-01-01 7:49 ` [PATCH 07/13] x86/virt/tdx: Add SEAMCALL wrapper tdh_mem_sept_add() to add SEPT pages Paolo Bonzini
2025-01-02 21:59 ` Edgecombe, Rick P
2025-01-07 5:27 ` Yan Zhao
2025-01-07 19:48 ` Dave Hansen
2025-01-08 1:12 ` Yan Zhao
2025-01-08 1:20 ` Dave Hansen
2025-01-08 1:43 ` Edgecombe, Rick P
2025-01-08 2:14 ` Yan Zhao
2025-01-01 7:49 ` [PATCH 08/13] x86/virt/tdx: Add SEAMCALL wrappers to add TD private pages Paolo Bonzini
2025-01-02 23:32 ` Edgecombe, Rick P
2025-01-06 5:50 ` Yan Zhao
2025-01-06 19:21 ` Edgecombe, Rick P
2025-01-07 6:37 ` Yan Zhao
2025-01-14 23:32 ` Paolo Bonzini
2025-01-15 0:49 ` Edgecombe, Rick P
2025-01-15 2:02 ` Edgecombe, Rick P
2025-01-15 5:49 ` Yan Zhao
2025-01-01 7:49 ` [PATCH 09/13] x86/virt/tdx: Add SEAMCALL wrappers to manage TDX TLB tracking Paolo Bonzini
2025-01-03 1:28 ` Edgecombe, Rick P
2025-01-07 6:40 ` Yan Zhao
2025-01-01 7:49 ` [PATCH 10/13] x86/virt/tdx: Add SEAMCALL wrappers to remove a TD private page Paolo Bonzini
2025-01-03 1:36 ` Edgecombe, Rick P [this message]
2025-01-07 6:43 ` Yan Zhao
2025-01-07 6:52 ` Yan Zhao
2025-01-07 22:13 ` Dave Hansen
2025-01-08 0:41 ` Yan Zhao
2025-01-08 16:31 ` Dave Hansen
2025-01-09 2:19 ` Yan Zhao
2025-01-01 7:49 ` [PATCH 11/13] x86/virt/tdx: Add SEAMCALL wrappers for TD measurement of initial contents Paolo Bonzini
2025-01-03 18:02 ` Edgecombe, Rick P
2025-01-14 22:03 ` Paolo Bonzini
2025-01-14 22:10 ` Dave Hansen
2025-01-15 1:24 ` Yan Zhao
2025-01-07 7:01 ` Yan Zhao
2025-01-07 22:05 ` Dave Hansen
2025-01-01 7:49 ` [PATCH 12/13] x86/virt/tdx: Read essential global metadata for KVM Paolo Bonzini
2025-01-03 18:26 ` Edgecombe, Rick P
2025-01-01 7:49 ` [PATCH 13/13] x86/virt/tdx: Add tdx_guest_keyid_alloc/free() to alloc and free TDX guest KeyID Paolo Bonzini
2025-01-02 19:43 ` [PATCH v2 00/13] x86/virt/tdx: Add SEAMCALL wrappers for KVM Edgecombe, Rick P
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=f35eff4bf646adad3463b655382e249007a3ff7c.camel@intel.com \
--to=rick.p.edgecombe@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=isaku.yamahata@intel.com \
--cc=kai.huang@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=sean.j.christopherson@intel.com \
--cc=yan.y.zhao@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