All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
To: "pbonzini@redhat.com" <pbonzini@redhat.com>,
	"Hansen, Dave" <dave.hansen@intel.com>,
	"seanjc@google.com" <seanjc@google.com>,
	"Zhao, Yan Y" <yan.y.zhao@intel.com>
Cc: "kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	"Du, Fan" <fan.du@intel.com>,
	"Li, Xiaoyao" <xiaoyao.li@intel.com>,
	"Huang, Kai" <kai.huang@intel.com>,
	"thomas.lendacky@amd.com" <thomas.lendacky@amd.com>,
	"tabba@google.com" <tabba@google.com>,
	"vbabka@suse.cz" <vbabka@suse.cz>,
	"david@kernel.org" <david@kernel.org>,
	"kas@kernel.org" <kas@kernel.org>,
	"michael.roth@amd.com" <michael.roth@amd.com>,
	"binbin.wu@linux.intel.com" <binbin.wu@linux.intel.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"Peng, Chao P" <chao.p.peng@intel.com>,
	"ackerleytng@google.com" <ackerleytng@google.com>,
	"nik.borisov@suse.com" <nik.borisov@suse.com>,
	"francescolavra.fl@gmail.com" <francescolavra.fl@gmail.com>,
	"sagis@google.com" <sagis@google.com>,
	"Annapurve, Vishal" <vannapurve@google.com>,
	"Chen, Farrah" <farrah.chen@intel.com>,
	"Gao, Chao" <chao.gao@intel.com>,
	"Miao, Jun" <jun.miao@intel.com>,
	"jgross@suse.com" <jgross@suse.com>,
	"pgonda@google.com" <pgonda@google.com>,
	"x86@kernel.org" <x86@kernel.org>
Subject: Re: [PATCH v4 07/17] KVM: TDX: Add core support for splitting/demoting 2MB S-EPT mappings to 4KB
Date: Wed, 7 Oct 2026 21:52:05 +0000	[thread overview]
Message-ID: <90ecae2e769c85d5c32a2d31f004dd007f4f6774.camel@intel.com> (raw)
In-Reply-To: <20260928091021.15583-1-yan.y.zhao@intel.com>

On Mon, 2026-09-28 at 17:10 +0800, Yan Zhao wrote:
> Add support for splitting, a.k.a. demoting, a 2MB S-EPT leaf mapping to 512
> smaller 4KB leaf mappings.  As per the TDX module rules, first invoke
> MEM.RANGE.BLOCK to put the huge S-EPT leaf entry into a splittable state,
> then do MEM.TRACK and kick all vCPUs outside of guest mode to flush TLBs,
> and finally do MEM.PAGE.DEMOTE to demote/split the huge S-EPT leaf mapping.
> 
> Assert the mmu_lock is held for write, as the BLOCK => TRACK => DEMOTE
> sequence needs to be "atomic" to guarantee success (and because mmu_lock
> must be held for write to use tdh_do_no_vcpus()).
> 
> Note, even with kvm->mmu_lock held for write, tdh_mem_page_demote() may
> contend with tdh_vp_enter() and potentially with the guest's S-EPT entry
> operations.  Therefore, wrap the call with tdh_do_no_vcpus() to kick other
> vCPUs out of the guest and prevent tdh_vp_enter() to ensure success.
> 
> Invoke tdx_pamt_get() before invoking tdh_mem_page_demote() so that DPAMT
> pages for the new S-EPT page table page are installed before the DEMOTE
> SEAMCALL when DPAMT is enabled. DPAMT pages for the guest memory must be
> installed inside the DEMOTE SEAMCALL, since it is impossible to do so
> before a successful demotion.
> 
> Instead of allocating and freeing DPAMT pages for guest pages on the KVM
> side, pass pamt_cache to tdh_mem_page_demote() and let it draw DPAMT pages
> from pamt_cache before the DEMOTE SEAMCALL. This prevents KVM from having
> to manage DPAMT pages directly via alloc_pamt_array() and
> free_pamt_array(), or having knowledge of DPAMT-specific details such as
> TDX_DPAMT_ENTRY_PAGE_CNT.
> 
> Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>

The SOB seems wrong. You are the the listed author, but these don't have a Co-
developed-by tag.

> [sean: wire up via op set_external_spte(), merge in DPAMT-related code,
>  massage changelog]
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Yan Zhao <yan.y.zhao@intel.com>
> ---
> v4:
> - Hooked tdx_sept_split_leaf_spte() in x86 op set_external_spte() instead
>   of in x86 op split_external_spte() which was no longer introduced in v4.
>   (Sean).
> - Renamed tdx_sept_split_private_spte() --> tdx_sept_split_leaf_spte().
> - Merged in DPAMT-related code (i.e., passing to_tdx(vcpu)->pamt_cache to
>   tdh_mem_page_demote(). (Sean).
> - Assert new_spte is non-leaf. (Yan)
> 
> v3:
> - Rebased on top of Sean's cleanup series.
> - Call out UNBLOCK is not required after DEMOTE. (Kai)
> - tdx_sept_split_private_spt() --> tdx_sept_split_private_spte().
> 
> RFC v2:
> - Split out the code to handle the error TDX_INTERRUPTED_RESTARTABLE.
> - Rebased to 6.16.0-rc6 (the way of defining TDX hook changes).
> 
> RFC v1:
> - Split patch for exclusive mmu_lock only,
> - Invoke tdx_sept_zap_private_spte() and tdx_track() for splitting.
> - Handled busy error of tdh_mem_page_demote() by kicking off vCPUs.
> ---
>  arch/x86/kvm/vmx/tdx.c | 69 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 68 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
> index 3dcddf1b48c5..3186c4808cae 100644
> --- a/arch/x86/kvm/vmx/tdx.c
> +++ b/arch/x86/kvm/vmx/tdx.c
> @@ -1873,11 +1873,74 @@ static int tdx_sept_remove_leaf_spte(struct kvm *kvm, gfn_t gfn,
>  	return 0;
>  }
>  
> +/*
> + * Split a huge mapping into smaller mappings at a lower level.  Currently only
> + * supports splitting 2MB mappings (KVM doesn't yet support 1GB mappings for TDX
> + * guests).
> + *
> + * Invoke "BLOCK + TRACK + kick off vCPUs (inside tdx_track())" since the TDX
> + * module does not yet support the NON-BLOCKING-RESIZE feature for DEMOTE.
> + *
> + * No UNBLOCK is needed after a successful DEMOTE.
> + *
> + * Under write mmu_lock, kick off all vCPUs and disallow vCPUs from entering to
> + * ensure DEMOTE will succeed on the second invocation if the first invocation
> + * returns BUSY.

How about putting these in the function instead of up here?

> + */
> +static int tdx_sept_split_leaf_spte(struct kvm *kvm, gfn_t gfn, u64 old_spte,
> +				    u64 new_spte, enum pg_level level)
> +{
> +	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
> +	struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm);
> +	gpa_t gpa = gfn_to_gpa(gfn);
> +	u64 err, entry, level_state;
> +	struct page *sept_pt;
> +	int r;
> +
> +	lockdep_assert_held_write(&kvm->mmu_lock);
> +
> +	if (KVM_BUG_ON(!is_last_spte(old_spte, level) || is_last_spte(new_spte, level), kvm))
> +		return -EIO;
> +
> +	sept_pt = tdx_spte_to_sept_pt(kvm, gfn, new_spte, level);
> +	if (!sept_pt)
> +		return -EIO;
> +
> +	if (KVM_BUG_ON(!vcpu || vcpu->kvm != kvm, kvm))
> +		return -EIO;
> +
> +	r = tdx_pamt_get(page_to_pfn(sept_pt), PG_LEVEL_4K, &to_tdx(vcpu)->pamt_cache);
> +	if (KVM_BUG_ON(r, kvm))
> +		return r;
> +
> +	err = tdh_do_no_vcpus(tdh_mem_range_block, kvm, &kvm_tdx->td, gpa,
> +			      level, &entry, &level_state);
> +	if (TDX_BUG_ON_2(err, TDH_MEM_RANGE_BLOCK, entry, level_state, kvm)) {
> +		r = -EIO;
> +		goto err;
> +	}
> +
> +	tdx_track(kvm);
> +	err = tdh_do_no_vcpus(tdh_mem_page_demote, kvm, &kvm_tdx->td, gpa,
> +			      level, spte_to_pfn(old_spte), sept_pt,
> +			      &to_tdx(vcpu)->pamt_cache, &entry, &level_state);
> +	if (TDX_BUG_ON_2(err, TDH_MEM_PAGE_DEMOTE, entry, level_state, kvm)) {
> +		r = -EIO;

Not trying to rollback with an unlock in this case seems like the right call,
but can we have a comment justification?

> +		goto err;
> +	}
> +
> +	return 0;
> +err:
> +	tdx_pamt_put(page_to_pfn(sept_pt), PG_LEVEL_4K);
> +	return r;
> +}
> +
>  /*
>   * Handle changes for
>   * (1) leaf SPTEs from non-present to present
>   * (2) non-leaf SPTEs from non-present to present
>   * (3) leaf SPTEs from present to non-present
> + * (4) present leaf SPTEs to present non-leaf SPTEs (splitting)
>   *
>   * - (1) and (2) must be under shared mmu_lock. If (1) and (2) are under
>   *   exclusive mmu_lock (currently impossible), contention errors may lead to
> @@ -1888,13 +1951,17 @@ static int tdx_sept_remove_leaf_spte(struct kvm *kvm, gfn_t gfn,
>   *   (currently impossible), warnings will be generated due to
>   *   lockdep_assert_held_write() or TDX_BUG_ON() caused by concurrent BLOCK,
>   *   TRACK, REMOVE.
> - * - Promotion/demotion is not yet supported.
> + * - (4) must be under write mmu_lock currently.

Currently?

> + * - Promotion is not yet supported.

And we are not trying to support it, right?

Can we not make this imply some roadmap of enhancements that may never happen
for a long time if ever?

>   */
>  static int tdx_sept_set_private_spte(struct kvm *kvm, gfn_t gfn, u64 old_spte,
>  				     u64 new_spte, enum pg_level level)
>  {
>  	lockdep_assert_held(&kvm->mmu_lock);
>  
> +	if (is_shadow_present_pte(old_spte) && is_shadow_present_pte(new_spte))
> +		return tdx_sept_split_leaf_spte(kvm, gfn, old_spte, new_spte, level);
> +
>  	if (is_shadow_present_pte(old_spte))
>  		return tdx_sept_remove_leaf_spte(kvm, gfn, level, old_spte);
>  

Except for those small comments, overall looks good to me.


  reply	other threads:[~2026-10-07 21:52 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28  9:07 [PATCH v4 00/17] KVM: TDX huge page support for private memory Yan Zhao
2026-09-28  9:08 ` [PATCH v4 01/17] x86/virt/tdx: Enhance tdx_pamt_get/put() to support huge pages Yan Zhao
2026-10-01 23:02   ` Edgecombe, Rick P
2026-09-28  9:08 ` [PATCH v4 02/17] x86/virt/tdx: Add a SEAMCALL wrapper to demote a 2MB huge page Yan Zhao
2026-10-02  0:54   ` Edgecombe, Rick P
2026-09-28  9:08 ` [PATCH v4 03/17] KVM: TDX: Reset private huge pages after S-EPT page removal Yan Zhao
2026-10-07  0:06   ` Edgecombe, Rick P
2026-09-28  9:09 ` [PATCH v4 04/17] KVM: x86/mmu: Prevent huge page promotion for mirror roots in fault path Yan Zhao
2026-10-07  0:32   ` Edgecombe, Rick P
2026-09-28  9:09 ` [PATCH v4 05/17] KVM: x86/tdp_mmu: Alloc external_spt page for mirror page table splitting Yan Zhao
2026-10-07  0:33   ` Edgecombe, Rick P
2026-09-28  9:10 ` [PATCH v4 06/17] KVM: x86/mmu: Allocate DPAMT pages for vCPU-induced page split Yan Zhao
2026-10-07 15:45   ` Edgecombe, Rick P
2026-09-28  9:10 ` [PATCH v4 07/17] KVM: TDX: Add core support for splitting/demoting 2MB S-EPT mappings to 4KB Yan Zhao
2026-10-07 21:52   ` Edgecombe, Rick P [this message]
2026-09-28  9:10 ` [PATCH v4 08/17] KVM: TDX: Adjust the topup count of DPAMT page pairs for splitting S-EPT Yan Zhao
2026-10-07 22:48   ` Edgecombe, Rick P
2026-10-08  1:16     ` Edgecombe, Rick P
2026-09-28  9:10 ` [PATCH v4 09/17] KVM: x86/mmu: Introduce hugepage_set_guest_inhibit() Yan Zhao
2026-10-07 23:57   ` Edgecombe, Rick P
2026-09-28  9:11 ` [PATCH v4 10/17] KVM: x86/mmu: Add a TDP MMU API to split huge pages for mirror roots Yan Zhao
2026-10-08  0:25   ` Edgecombe, Rick P
2026-09-28  9:11 ` [PATCH v4 11/17] KVM: TDX: Honor the guest's accept level contained in an EPT violation Yan Zhao
2026-10-08  1:05   ` Edgecombe, Rick P
2026-09-28  9:11 ` [PATCH v4 12/17] KVM: x86/mmu: Add support for splitting S-EPT entry under non-vCPU context Yan Zhao
2026-09-28  9:11 ` [PATCH v4 13/17] [GMEM-DEPENDENT] KVM: guest_memfd: Add helpers to get start/end gfns give gmem+slot+pgoff Yan Zhao
2026-10-08 23:16   ` Edgecombe, Rick P
2026-09-28  9:11 ` [PATCH v4 14/17] [GMEM-DEPENDENT] KVM: guest_memfd: Split kvm_gmem_invalidate_start() to start() and zap() Yan Zhao
2026-09-28  9:12 ` [PATCH v4 15/17] [GMEM-DEPENDENT] KVM: guest_memfd: Add a pre-zap hook .gmem_prezap() Yan Zhao
2026-09-28  9:12 ` [PATCH v4 16/17] [GMEM-DEPENDENT] KVM: TDX: Implement .gmem_prezap() hook to split S-EPT Yan Zhao
2026-09-28  9:12 ` [PATCH v4 17/17] KVM: TDX: Turn on PG_LEVEL_2M Yan Zhao

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=90ecae2e769c85d5c32a2d31f004dd007f4f6774.camel@intel.com \
    --to=rick.p.edgecombe@intel.com \
    --cc=ackerleytng@google.com \
    --cc=binbin.wu@linux.intel.com \
    --cc=chao.gao@intel.com \
    --cc=chao.p.peng@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=david@kernel.org \
    --cc=fan.du@intel.com \
    --cc=farrah.chen@intel.com \
    --cc=francescolavra.fl@gmail.com \
    --cc=jgross@suse.com \
    --cc=jun.miao@intel.com \
    --cc=kai.huang@intel.com \
    --cc=kas@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michael.roth@amd.com \
    --cc=nik.borisov@suse.com \
    --cc=pbonzini@redhat.com \
    --cc=pgonda@google.com \
    --cc=sagis@google.com \
    --cc=seanjc@google.com \
    --cc=tabba@google.com \
    --cc=thomas.lendacky@amd.com \
    --cc=vannapurve@google.com \
    --cc=vbabka@suse.cz \
    --cc=x86@kernel.org \
    --cc=xiaoyao.li@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 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.