Skip to content

Commit 6ad0bad

Browse files
committed
x86/tdx: Use PFN directly for mapping guest private memory
Remove struct page assumptions/constraints in the SEAMCALL wrapper APIs for mapping guest private memory and have them take PFN directly. Having core TDX make assumptions that guest private memory must be backed by struct page (and/or folio) will create subtle dependencies on how KVM/guest_memfd allocates/manages memory (e.g., whether it uses memory allocated from core MM, if the memory is refcounted, or if the folio is split) that are easily avoided. [1]. KVM's MMUs work with PFNs. This is very much an intentional design choice. It ensures that the KVM MMUs remain flexible and are not too tied to the regular CPU MMUs and the kernel code around them. Using 'struct page' for TDX guest memory is not a good fit anywhere near the KVM MMU code [2]. Use "kvm_pfn_t pfn" for type safety. Using this KVM type is appropriate since APIs tdh_mem_page_add() and tdh_mem_page_aug() are exported to KVM only. [ Yan: Replace "u64 pfn" with "kvm_pfn_t pfn" ] Signed-off-by: Yan Zhao <yan.y.zhao@intel.com> Link: https://lore.kernel.org/all/aWgyhmTJphGQqO0Y@google.com [1] Link: https://lore.kernel.org/all/ac7V0g2q2hN3dU5u@google.com [2] Acked-by: Kiryl Shutsemau <kas@kernel.org> Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com> Reviewed-by: Ackerley Tng <ackerleytng@google.com> Acked-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://patch.msgid.link/20260430014929.24210-1-yan.y.zhao@intel.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent e1a31ca commit 6ad0bad

3 files changed

Lines changed: 20 additions & 13 deletions

File tree

arch/x86/include/asm/tdx.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <linux/init.h>
77
#include <linux/bits.h>
88
#include <linux/mmzone.h>
9+
#include <linux/kvm_types.h>
910

1011
#include <asm/errno.h>
1112
#include <asm/ptrace.h>
@@ -189,10 +190,12 @@ static inline u64 mk_keyed_paddr(u16 hkid, struct page *page)
189190

190191
u64 tdh_vp_enter(struct tdx_vp *vp, struct tdx_module_args *args);
191192
u64 tdh_mng_addcx(struct tdx_td *td, struct page *tdcs_page);
192-
u64 tdh_mem_page_add(struct tdx_td *td, u64 gpa, struct page *page, struct page *source, u64 *ext_err1, u64 *ext_err2);
193+
u64 tdh_mem_page_add(struct tdx_td *td, u64 gpa, kvm_pfn_t pfn, struct page *source,
194+
u64 *ext_err1, u64 *ext_err2);
193195
u64 tdh_mem_sept_add(struct tdx_td *td, u64 gpa, enum pg_level level, struct page *page, u64 *ext_err1, u64 *ext_err2);
194196
u64 tdh_vp_addcx(struct tdx_vp *vp, struct page *tdcx_page);
195-
u64 tdh_mem_page_aug(struct tdx_td *td, u64 gpa, enum pg_level level, struct page *page, u64 *ext_err1, u64 *ext_err2);
197+
u64 tdh_mem_page_aug(struct tdx_td *td, u64 gpa, enum pg_level level, kvm_pfn_t pfn,
198+
u64 *ext_err1, u64 *ext_err2);
196199
u64 tdh_mem_range_block(struct tdx_td *td, u64 gpa, enum pg_level level, u64 *ext_err1, u64 *ext_err2);
197200
u64 tdh_mng_key_config(struct tdx_td *td);
198201
u64 tdh_mng_create(struct tdx_td *td, u16 hkid);

arch/x86/kvm/vmx/tdx.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,8 +1624,8 @@ static int tdx_mem_page_add(struct kvm *kvm, gfn_t gfn, enum pg_level level,
16241624
KVM_BUG_ON(!kvm_tdx->page_add_src, kvm))
16251625
return -EIO;
16261626

1627-
err = tdh_mem_page_add(&kvm_tdx->td, gpa, pfn_to_page(pfn),
1628-
kvm_tdx->page_add_src, &entry, &level_state);
1627+
err = tdh_mem_page_add(&kvm_tdx->td, gpa, pfn, kvm_tdx->page_add_src,
1628+
&entry, &level_state);
16291629
if (unlikely(tdx_operand_busy(err)))
16301630
return -EBUSY;
16311631

@@ -1639,12 +1639,11 @@ static int tdx_mem_page_aug(struct kvm *kvm, gfn_t gfn,
16391639
enum pg_level level, kvm_pfn_t pfn)
16401640
{
16411641
struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm);
1642-
struct page *page = pfn_to_page(pfn);
16431642
gpa_t gpa = gfn_to_gpa(gfn);
16441643
u64 entry, level_state;
16451644
u64 err;
16461645

1647-
err = tdh_mem_page_aug(&kvm_tdx->td, gpa, level, page, &entry, &level_state);
1646+
err = tdh_mem_page_aug(&kvm_tdx->td, gpa, level, pfn, &entry, &level_state);
16481647
if (unlikely(tdx_operand_busy(err)))
16491648
return -EBUSY;
16501649

arch/x86/virt/vmx/tdx/tdx.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include <linux/suspend.h>
3131
#include <linux/syscore_ops.h>
3232
#include <linux/idr.h>
33-
#include <linux/kvm_types.h>
3433
#include <asm/page.h>
3534
#include <asm/special_insns.h>
3635
#include <asm/msr-index.h>
@@ -1568,6 +1567,11 @@ static void tdx_clflush_page(struct page *page)
15681567
clflush_cache_range(page_to_virt(page), PAGE_SIZE);
15691568
}
15701569

1570+
static void tdx_clflush_pfn(kvm_pfn_t pfn)
1571+
{
1572+
clflush_cache_range(__va(PFN_PHYS(pfn)), PAGE_SIZE);
1573+
}
1574+
15711575
static int pg_level_to_tdx_sept_level(enum pg_level level)
15721576
{
15731577
WARN_ON_ONCE(level == PG_LEVEL_NONE);
@@ -1594,17 +1598,18 @@ u64 tdh_mng_addcx(struct tdx_td *td, struct page *tdcs_page)
15941598
}
15951599
EXPORT_SYMBOL_FOR_KVM(tdh_mng_addcx);
15961600

1597-
u64 tdh_mem_page_add(struct tdx_td *td, u64 gpa, struct page *page, struct page *source, u64 *ext_err1, u64 *ext_err2)
1601+
u64 tdh_mem_page_add(struct tdx_td *td, u64 gpa, kvm_pfn_t pfn, struct page *source,
1602+
u64 *ext_err1, u64 *ext_err2)
15981603
{
15991604
struct tdx_module_args args = {
16001605
.rcx = gpa,
16011606
.rdx = tdx_tdr_pa(td),
1602-
.r8 = page_to_phys(page),
1607+
.r8 = PFN_PHYS(pfn),
16031608
.r9 = page_to_phys(source),
16041609
};
16051610
u64 ret;
16061611

1607-
tdx_clflush_page(page);
1612+
tdx_clflush_pfn(pfn);
16081613
ret = seamcall_ret(TDH_MEM_PAGE_ADD, &args);
16091614

16101615
*ext_err1 = args.rcx;
@@ -1647,16 +1652,16 @@ u64 tdh_vp_addcx(struct tdx_vp *vp, struct page *tdcx_page)
16471652
EXPORT_SYMBOL_FOR_KVM(tdh_vp_addcx);
16481653

16491654
u64 tdh_mem_page_aug(struct tdx_td *td, u64 gpa, enum pg_level level,
1650-
struct page *page, u64 *ext_err1, u64 *ext_err2)
1655+
kvm_pfn_t pfn, u64 *ext_err1, u64 *ext_err2)
16511656
{
16521657
struct tdx_module_args args = {
16531658
.rcx = gpa | pg_level_to_tdx_sept_level(level),
16541659
.rdx = tdx_tdr_pa(td),
1655-
.r8 = page_to_phys(page),
1660+
.r8 = PFN_PHYS(pfn),
16561661
};
16571662
u64 ret;
16581663

1659-
tdx_clflush_page(page);
1664+
tdx_clflush_pfn(pfn);
16601665
ret = seamcall_ret(TDH_MEM_PAGE_AUG, &args);
16611666

16621667
*ext_err1 = args.rcx;

0 commit comments

Comments
 (0)