mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: seanjc@google.com, Yan Zhao <yan.y.zhao@intel.com>,
	Rick Edgecombe <rick.p.edgecombe@intel.com>,
	Isaku Yamahata <isaku.yamahata@intel.com>,
	Sean Christopherson <sean.j.christopherson@intel.com>,
	Kai Huang <kai.huang@intel.com>,
	Dave Hansen <dave.hansen@linux.intel.com>
Subject: [PATCH 04/29] x86/virt/tdx: Add SEAMCALL wrappers to remove a TD private page
Date: Wed, 26 Feb 2025 14:55:04 -0500	[thread overview]
Message-ID: <20250226195529.2314580-5-pbonzini@redhat.com> (raw)
In-Reply-To: <20250226195529.2314580-1-pbonzini@redhat.com>

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>
Acked-by: Dave Hansen <dave.hansen@linux.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 cc050cc1367a..28d25d1bfa96 100644
--- a/arch/x86/include/asm/tdx.h
+++ b/arch/x86/include/asm/tdx.h
@@ -183,8 +183,10 @@ u64 tdh_vp_rd(struct tdx_vp *vp, u64 field, u64 *data);
 u64 tdh_vp_wr(struct tdx_vp *vp, u64 field, u64 data, u64 mask);
 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 *ext_err1, u64 *ext_err2);
 u64 tdh_phymem_cache_wb(bool resume);
 u64 tdh_phymem_page_wbinvd_tdr(struct tdx_td *td);
+u64 tdh_phymem_page_wbinvd_hkid(u64 hkid, struct page *page);
 #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 f920754bb35e..ffa0f6b8254d 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1788,6 +1788,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 *ext_err1, u64 *ext_err2)
+{
+	struct tdx_module_args args = {
+		.rcx = gpa | level,
+		.rdx = tdx_tdr_pa(td),
+	};
+	u64 ret;
+
+	ret = seamcall_ret(TDH_MEM_PAGE_REMOVE, &args);
+
+	*ext_err1 = args.rcx;
+	*ext_err2 = args.rdx;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tdh_mem_page_remove);
+
 u64 tdh_phymem_cache_wb(bool resume)
 {
 	struct tdx_module_args args = {
@@ -1807,3 +1824,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 hkid, struct page *page)
+{
+	struct tdx_module_args args = {};
+
+	args.rcx = mk_keyed_paddr(hkid, page);
+
+	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 104c97abf264..c9bea023f2b4 100644
--- a/arch/x86/virt/vmx/tdx/tdx.h
+++ b/arch/x86/virt/vmx/tdx/tdx.h
@@ -32,6 +32,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
-- 
2.43.5



  parent reply	other threads:[~2025-02-26 19:55 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-26 19:55 [PATCH v3 00/29] TDX MMU part 2 Paolo Bonzini
2025-02-26 19:55 ` [PATCH 01/29] x86/virt/tdx: Add SEAMCALL wrapper tdh_mem_sept_add() to add SEPT pages Paolo Bonzini
2025-02-26 19:55 ` [PATCH 02/29] x86/virt/tdx: Add SEAMCALL wrappers to add TD private pages Paolo Bonzini
2025-02-26 19:55 ` [PATCH 03/29] x86/virt/tdx: Add SEAMCALL wrappers to manage TDX TLB tracking Paolo Bonzini
2025-02-26 19:55 ` Paolo Bonzini [this message]
2025-02-26 19:55 ` [PATCH 05/29] x86/virt/tdx: Add SEAMCALL wrappers for TD measurement of initial contents Paolo Bonzini
2025-02-26 19:55 ` [PATCH 06/29] KVM: x86/mmu: Implement memslot deletion for TDX Paolo Bonzini
2025-02-26 19:55 ` [PATCH 07/29] KVM: x86/tdp_mmu: Add a helper function to walk down the TDP MMU Paolo Bonzini
2025-02-26 19:55 ` [PATCH 08/29] KVM: x86/mmu: Do not enable page track for TD guest Paolo Bonzini
2025-02-26 19:55 ` [PATCH 09/29] KVM: VMX: Split out guts of EPT violation to common/exposed function Paolo Bonzini
2025-02-26 19:55 ` [PATCH 10/29] KVM: VMX: Teach EPT violation helper about private mem Paolo Bonzini
2025-02-26 19:55 ` [PATCH 11/29] KVM: TDX: Add accessors VMX VMCS helpers Paolo Bonzini
2025-02-26 19:55 ` [PATCH 12/29] KVM: TDX: Add load_mmu_pgd method for TDX Paolo Bonzini
2025-02-26 19:55 ` [PATCH 13/29] KVM: TDX: Set gfn_direct_bits to shared bit Paolo Bonzini
2025-02-26 19:55 ` [PATCH 14/29] KVM: TDX: Require TDP MMU, mmio caching and EPT A/D bits for TDX Paolo Bonzini
2025-02-26 19:55 ` [PATCH 15/29] KVM: x86/mmu: Add setter for shadow_mmio_value Paolo Bonzini
2025-02-26 19:55 ` [PATCH 16/29] KVM: TDX: Set per-VM shadow_mmio_value to 0 Paolo Bonzini
2025-02-26 19:55 ` [PATCH 17/29] KVM: TDX: Handle TLB tracking for TDX Paolo Bonzini
2025-02-26 19:55 ` [PATCH 18/29] KVM: TDX: Implement hooks to propagate changes of TDP MMU mirror page table Paolo Bonzini
2025-02-26 19:55 ` [PATCH 19/29] KVM: TDX: Implement hook to get max mapping level of private pages Paolo Bonzini
2025-02-26 19:55 ` [PATCH 20/29] KVM: x86/mmu: Bail out kvm_tdp_map_page() when VM dead Paolo Bonzini
2025-02-26 19:55 ` [PATCH 21/29] KVM: x86/mmu: Export kvm_tdp_map_page() Paolo Bonzini
2025-02-26 19:55 ` [PATCH 22/29] KVM: TDX: Add an ioctl to create initial guest memory Paolo Bonzini
2025-02-28  4:18   ` Yan Zhao
2025-03-06 16:04     ` Paolo Bonzini
2025-02-26 19:55 ` [PATCH 23/29] KVM: TDX: Finalize VM initialization Paolo Bonzini
2025-02-26 19:55 ` [PATCH 24/29] KVM: TDX: Handle vCPU dissociation Paolo Bonzini
2025-02-26 19:55 ` [PATCH 25/29] KVM: Add parameter "kvm" to kvm_cpu_dirty_log_size() and its callers Paolo Bonzini
2025-02-26 19:55 ` [PATCH 26/29] KVM: x86/mmu: Add parameter "kvm" to kvm_mmu_page_ad_need_write_protect() Paolo Bonzini
2025-02-26 19:55 ` [PATCH 27/29] KVM: x86: Make cpu_dirty_log_size a per-VM value Paolo Bonzini
2025-02-26 19:55 ` [PATCH 28/29] KVM: TDX: Skip updating CPU dirty logging request for TDs Paolo Bonzini
2025-02-26 19:55 ` [PATCH 29/29] KVM: TDX: Handle SEPT zap error due to page add error in premap Paolo Bonzini

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=20250226195529.2314580-5-pbonzini@redhat.com \
    --to=pbonzini@redhat.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=rick.p.edgecombe@intel.com \
    --cc=sean.j.christopherson@intel.com \
    --cc=seanjc@google.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

all inboxes | Powered by JetHome®