From nobody Mon Feb 9 12:01:32 2026 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75DBB318B81 for ; Thu, 29 Jan 2026 01:15:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769649332; cv=none; b=iGY5bDAaVBmiUGWDQTq0wxIgACsjAJapFYMObYitJA4IPfKApFTQNWMen+EgiHUo4xRA5j0EC0sU+WelZ05rExQpzI881ss575+ggzdivQ4BKn09yMMU/oBcpSutEsZ1oQzyJ6vd//JtK3eoMjXWUHBqOd9orMWNCm5/qc2RH2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769649332; c=relaxed/simple; bh=6WZuX4SGOhlJ1EJPkuzateSePJBHf/L/b6Rra/zk9bI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jkRjJmWi64u9Jz8Pg8oiSYLof9jv/rGAJITxa1ylC7S3A+68Qrb83uj4s04KTgbzQw/2+7pTb0MNKfyLA6BIGMgKCr3LbAVzvp45TiifflGZvFRFbxpMCHB0E+/E3Pk0PeuV91pdLg3PWXZprnRdcVw/vanztwyKsQwKQonnX2A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Q/Bj2STU; arc=none smtp.client-ip=209.85.216.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Q/Bj2STU" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-353c9d644b0so266199a91.2 for ; Wed, 28 Jan 2026 17:15:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1769649330; x=1770254130; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=igCO2aefnhWl+0Qoc7v6+UqQKsYgMls58OQ/f2Mb56Y=; b=Q/Bj2STUpdeRKMjiuu6O30By6xRhtpRtE7MwtSKueyeBUIJtARtamLsQmQiw6CxnGl 8UjPpG64M3GZpiOtI1pGLOUiEEcf3t6PxKWZPbKRrKFRVIUD7cbVUCwiXvxjYEW3EMIO mc58dQTrKJv5ahKu0tE+lH9pYii6sRRNAV3S9Kr1rsMJZWj8jEfs5GF9WMHEde3HgRcB V+T+pFx3CpMGS715w8QM/hGCbTuV5mGwO3llL/E2O0WmpXb08m3sQvrcAEPILnpatuhp HZaVuoN/teDUsBZKhco2nxOPlJ9CXNSCzmJuMNKih1UVl4ZYXxCrUIMaC/gpZzIzJBC5 haag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769649330; x=1770254130; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=igCO2aefnhWl+0Qoc7v6+UqQKsYgMls58OQ/f2Mb56Y=; b=S8+eB3Sk5aJRq2eW0ys+1tA28GZO/BVRxMBYMNiq+PbmqeB6Gu4KvJIx6tYQnBWtSS RCYlmdZh0x1XUxZaDEcBRU3VPdyNi+88cxfKcQ+uzCICsMG5AUKh0xwGBr34Q41FR2uT bmxEVeRwCQ12HeIvs7xbX02zYIMFbY6DbnBGcAY5M3rBUV/DXSxZCjBlGKj3li2LzBDF 3EMYikHBkkdsvsMmrnGMxW99VHHxqqrI00BIZU0SDuAVd1qKnUWITPrpC8fXH6bAU+/F BjxW0mRQH3A6hT3D9RXFYQkdHjAgYOgYFZQIYNp6S9Qa/0ciBZFuz7dOEGTFFNUKIX7P p5Ew== X-Gm-Message-State: AOJu0Yz4E7oaJucGR3gdPiY7yvsgUdm/vqoynia0+U00YNnvyXFVH6zZ tqxyM/I+cuOqiRjJcu4Xx1YN1yMLKpuvfvzQ1zAbrPBbh0F+S4/zV3ADKtdUwsvuHNFWGNIkgYt 3YUWulQ== X-Received: from pjbos4.prod.google.com ([2002:a17:90b:1cc4:b0:34a:c87f:a95a]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2ecc:b0:340:9d52:44c1 with SMTP id 98e67ed59e1d1-353feda1774mr6383748a91.35.1769649329834; Wed, 28 Jan 2026 17:15:29 -0800 (PST) Reply-To: Sean Christopherson Date: Wed, 28 Jan 2026 17:14:33 -0800 In-Reply-To: <20260129011517.3545883-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260129011517.3545883-1-seanjc@google.com> X-Mailer: git-send-email 2.53.0.rc1.217.geba53bf80e-goog Message-ID: <20260129011517.3545883-2-seanjc@google.com> Subject: [RFC PATCH v5 01/45] x86/tdx: Use pg_level in TDX APIs, not the TDX-Module's 0-based level From: Sean Christopherson To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Kiryl Shutsemau , Sean Christopherson , Paolo Bonzini Cc: linux-kernel@vger.kernel.org, linux-coco@lists.linux.dev, kvm@vger.kernel.org, Kai Huang , Rick Edgecombe , Yan Zhao , Vishal Annapurve , Ackerley Tng , Sagi Shahar , Binbin Wu , Xiaoyao Li , Isaku Yamahata Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rework the TDX APIs to take the kernel's 1-based pg_level enum, not the TDX-Module's 0-based level. The APIs are _kernel_ APIs, not TDX-Module APIs, and the kernel (and KVM) uses "enum pg_level" literally everywhere. Using "enum pg_level" eliminates ambiguity when looking at the APIs (it's NOT clear that "int level" refers to the TDX-Module's level), and will allow for using existing helpers like page_level_size() when support for hugepages is added to the S-EPT APIs. No functional change intended. Cc: Kai Huang Cc: Dave Hansen Cc: Rick Edgecombe Cc: Yan Zhao Cc: Vishal Annapurve Cc: Ackerley Tng Acked-by: Kiryl Shutsemau Reviewed-by: Kai Huang Tested-by: Kai Huang Reviewed-by: Rick Edgecombe Tested-by: Rick Edgecombe Signed-off-by: Sean Christopherson Acked-by: Dave Hansen --- arch/x86/include/asm/tdx.h | 14 ++++---------- arch/x86/kvm/vmx/tdx.c | 11 ++++------- arch/x86/virt/vmx/tdx/tdx.c | 26 ++++++++++++++++++-------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index 6b338d7f01b7..bc0d03e70fd6 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -189,19 +189,13 @@ static inline u64 mk_keyed_paddr(u16 hkid, struct pag= e *page) return ret; } =20 -static inline int pg_level_to_tdx_sept_level(enum pg_level level) -{ - WARN_ON_ONCE(level =3D=3D PG_LEVEL_NONE); - return level - 1; -} - u64 tdh_vp_enter(struct tdx_vp *vp, struct tdx_module_args *args); u64 tdh_mng_addcx(struct tdx_td *td, struct page *tdcs_page); u64 tdh_mem_page_add(struct tdx_td *td, u64 gpa, struct page *page, struct= page *source, u64 *ext_err1, u64 *ext_err2); -u64 tdh_mem_sept_add(struct tdx_td *td, u64 gpa, int level, struct page *p= age, u64 *ext_err1, u64 *ext_err2); +u64 tdh_mem_sept_add(struct tdx_td *td, u64 gpa, enum pg_level level, stru= ct page *page, u64 *ext_err1, u64 *ext_err2); u64 tdh_vp_addcx(struct tdx_vp *vp, struct page *tdcx_page); -u64 tdh_mem_page_aug(struct tdx_td *td, u64 gpa, int level, struct page *p= age, u64 *ext_err1, u64 *ext_err2); -u64 tdh_mem_range_block(struct tdx_td *td, u64 gpa, int level, u64 *ext_er= r1, u64 *ext_err2); +u64 tdh_mem_page_aug(struct tdx_td *td, u64 gpa, enum pg_level level, stru= ct page *page, u64 *ext_err1, u64 *ext_err2); +u64 tdh_mem_range_block(struct tdx_td *td, u64 gpa, enum pg_level level, u= 64 *ext_err1, u64 *ext_err2); u64 tdh_mng_key_config(struct tdx_td *td); u64 tdh_mng_create(struct tdx_td *td, u16 hkid); u64 tdh_vp_create(struct tdx_td *td, struct tdx_vp *vp); @@ -217,7 +211,7 @@ 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_er= r1, u64 *ext_err2); +u64 tdh_mem_page_remove(struct tdx_td *td, u64 gpa, enum pg_level level, u= 64 *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); diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 5df9d32d2058..561461c9d131 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -1648,14 +1648,13 @@ static int tdx_mem_page_add(struct kvm *kvm, gfn_t = gfn, enum pg_level level, static int tdx_mem_page_aug(struct kvm *kvm, gfn_t gfn, enum pg_level level, kvm_pfn_t pfn) { - int tdx_level =3D pg_level_to_tdx_sept_level(level); struct kvm_tdx *kvm_tdx =3D to_kvm_tdx(kvm); struct page *page =3D pfn_to_page(pfn); gpa_t gpa =3D gfn_to_gpa(gfn); u64 entry, level_state; u64 err; =20 - err =3D tdh_mem_page_aug(&kvm_tdx->td, gpa, tdx_level, page, &entry, &lev= el_state); + err =3D tdh_mem_page_aug(&kvm_tdx->td, gpa, level, page, &entry, &level_s= tate); if (unlikely(tdx_operand_busy(err))) return -EBUSY; =20 @@ -1699,12 +1698,11 @@ static int tdx_sept_set_private_spte(struct kvm *kv= m, gfn_t gfn, static int tdx_sept_link_private_spt(struct kvm *kvm, gfn_t gfn, enum pg_level level, void *private_spt) { - int tdx_level =3D pg_level_to_tdx_sept_level(level); gpa_t gpa =3D gfn_to_gpa(gfn); struct page *page =3D virt_to_page(private_spt); u64 err, entry, level_state; =20 - err =3D tdh_mem_sept_add(&to_kvm_tdx(kvm)->td, gpa, tdx_level, page, &ent= ry, + err =3D tdh_mem_sept_add(&to_kvm_tdx(kvm)->td, gpa, level, page, &entry, &level_state); if (unlikely(tdx_operand_busy(err))) return -EBUSY; @@ -1788,7 +1786,6 @@ static void tdx_sept_remove_private_spte(struct kvm *= kvm, gfn_t gfn, enum pg_level level, u64 mirror_spte) { struct page *page =3D pfn_to_page(spte_to_pfn(mirror_spte)); - int tdx_level =3D pg_level_to_tdx_sept_level(level); struct kvm_tdx *kvm_tdx =3D to_kvm_tdx(kvm); gpa_t gpa =3D gfn_to_gpa(gfn); u64 err, entry, level_state; @@ -1808,7 +1805,7 @@ static void tdx_sept_remove_private_spte(struct kvm *= kvm, gfn_t gfn, return; =20 err =3D tdh_do_no_vcpus(tdh_mem_range_block, kvm, &kvm_tdx->td, gpa, - tdx_level, &entry, &level_state); + level, &entry, &level_state); if (TDX_BUG_ON_2(err, TDH_MEM_RANGE_BLOCK, entry, level_state, kvm)) return; =20 @@ -1824,7 +1821,7 @@ static void tdx_sept_remove_private_spte(struct kvm *= kvm, gfn_t gfn, * Race with TDH.VP.ENTER due to (0-step mitigation) and Guest TDCALLs. */ err =3D tdh_do_no_vcpus(tdh_mem_page_remove, kvm, &kvm_tdx->td, gpa, - tdx_level, &entry, &level_state); + level, &entry, &level_state); if (TDX_BUG_ON_2(err, TDH_MEM_PAGE_REMOVE, entry, level_state, kvm)) return; =20 diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 5ce4ebe99774..22c0f832cb37 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1516,6 +1516,12 @@ static void tdx_clflush_page(struct page *page) clflush_cache_range(page_to_virt(page), PAGE_SIZE); } =20 +static int pg_level_to_tdx_sept_level(enum pg_level level) +{ + WARN_ON_ONCE(level =3D=3D PG_LEVEL_NONE); + return level - 1; +} + noinstr u64 tdh_vp_enter(struct tdx_vp *td, struct tdx_module_args *args) { args->rcx =3D td->tdvpr_pa; @@ -1556,10 +1562,11 @@ u64 tdh_mem_page_add(struct tdx_td *td, u64 gpa, st= ruct page *page, struct page } EXPORT_SYMBOL_FOR_KVM(tdh_mem_page_add); =20 -u64 tdh_mem_sept_add(struct tdx_td *td, u64 gpa, int level, struct page *p= age, u64 *ext_err1, u64 *ext_err2) +u64 tdh_mem_sept_add(struct tdx_td *td, u64 gpa, enum pg_level level, + struct page *page, u64 *ext_err1, u64 *ext_err2) { struct tdx_module_args args =3D { - .rcx =3D gpa | level, + .rcx =3D gpa | pg_level_to_tdx_sept_level(level), .rdx =3D tdx_tdr_pa(td), .r8 =3D page_to_phys(page), }; @@ -1587,10 +1594,11 @@ u64 tdh_vp_addcx(struct tdx_vp *vp, struct page *td= cx_page) } EXPORT_SYMBOL_FOR_KVM(tdh_vp_addcx); =20 -u64 tdh_mem_page_aug(struct tdx_td *td, u64 gpa, int level, struct page *p= age, u64 *ext_err1, u64 *ext_err2) +u64 tdh_mem_page_aug(struct tdx_td *td, u64 gpa, enum pg_level level, + struct page *page, u64 *ext_err1, u64 *ext_err2) { struct tdx_module_args args =3D { - .rcx =3D gpa | level, + .rcx =3D gpa | pg_level_to_tdx_sept_level(level), .rdx =3D tdx_tdr_pa(td), .r8 =3D page_to_phys(page), }; @@ -1606,10 +1614,11 @@ u64 tdh_mem_page_aug(struct tdx_td *td, u64 gpa, in= t level, struct page *page, u } EXPORT_SYMBOL_FOR_KVM(tdh_mem_page_aug); =20 -u64 tdh_mem_range_block(struct tdx_td *td, u64 gpa, int level, u64 *ext_er= r1, u64 *ext_err2) +u64 tdh_mem_range_block(struct tdx_td *td, u64 gpa, enum pg_level level, + u64 *ext_err1, u64 *ext_err2) { struct tdx_module_args args =3D { - .rcx =3D gpa | level, + .rcx =3D gpa | pg_level_to_tdx_sept_level(level), .rdx =3D tdx_tdr_pa(td), }; u64 ret; @@ -1822,10 +1831,11 @@ u64 tdh_mem_track(struct tdx_td *td) } EXPORT_SYMBOL_FOR_KVM(tdh_mem_track); =20 -u64 tdh_mem_page_remove(struct tdx_td *td, u64 gpa, u64 level, u64 *ext_er= r1, u64 *ext_err2) +u64 tdh_mem_page_remove(struct tdx_td *td, u64 gpa, enum pg_level level, + u64 *ext_err1, u64 *ext_err2) { struct tdx_module_args args =3D { - .rcx =3D gpa | level, + .rcx =3D gpa | pg_level_to_tdx_sept_level(level), .rdx =3D tdx_tdr_pa(td), }; u64 ret; --=20 2.53.0.rc1.217.geba53bf80e-goog