From: "Kirill A. Shutemov" If Dynamic PAMT is enabled, TDH.MEM.PAGE.DEMOTE will take the PAMT page pair in registers R12 and R13. Pass the pamt_pages list down to tdh_mem_page_demote() and populate registers R12 and R13 from it. Instead of using seamcall_ret(), use seamcall_saved_ret() as it can handle registers above R11. Signed-off-by: Kirill A. Shutemov Signed-off-by: Yan Zhao --- RFC v2: - Pulled from git://git.kernel.org/pub/scm/linux/kernel/git/kas/linux.git tdx/dpamt-huge. - Rebased on top of TDX huge page RFC v2 (Yan). --- arch/x86/include/asm/tdx.h | 1 + arch/x86/kvm/vmx/tdx.c | 4 ++-- arch/x86/virt/vmx/tdx/tdx.c | 13 +++++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index c058a82d4a97..2e529f0c578a 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -180,6 +180,7 @@ u64 tdh_mng_create(struct tdx_td *td, u16 hkid); u64 tdh_vp_create(struct tdx_td *td, struct tdx_vp *vp); u64 tdh_mng_rd(struct tdx_td *td, u64 field, u64 *data); u64 tdh_mem_page_demote(struct tdx_td *td, u64 gpa, int level, struct page *page, + struct list_head *pamt_pages, u64 *ext_err1, u64 *ext_err2); u64 tdh_mr_extend(struct tdx_td *td, u64 gpa, u64 *ext_err1, u64 *ext_err2); u64 tdh_mr_finalize(struct tdx_td *td); diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 24aa9aaad6d8..9d24a1a86a23 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -1924,12 +1924,12 @@ static int tdx_spte_demote_private_spte(struct kvm *kvm, gfn_t gfn, u64 err, entry, level_state; err = tdh_mem_page_demote(&kvm_tdx->td, gpa, tdx_level, page, - &entry, &level_state); + NULL, &entry, &level_state); if (unlikely(tdx_operand_busy(err))) { tdx_no_vcpus_enter_start(kvm); err = tdh_mem_page_demote(&kvm_tdx->td, gpa, tdx_level, page, - &entry, &level_state); + NULL, &entry, &level_state); tdx_no_vcpus_enter_stop(kvm); } diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index b7a0ee0f4a50..50f9d49f1c91 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -1825,6 +1825,7 @@ u64 tdh_mng_rd(struct tdx_td *td, u64 field, u64 *data) EXPORT_SYMBOL_GPL(tdh_mng_rd); u64 tdh_mem_page_demote(struct tdx_td *td, u64 gpa, int level, struct page *page, + struct list_head *pamt_pages, u64 *ext_err1, u64 *ext_err2) { struct tdx_module_args args = { @@ -1832,10 +1833,18 @@ u64 tdh_mem_page_demote(struct tdx_td *td, u64 gpa, int level, struct page *page .rdx = tdx_tdr_pa(td), .r8 = page_to_phys(page), }; - u64 ret; + struct page *pamt_page; + u64 *p, ret; + if (level == TDX_PS_2M) { + p = &args.r12; + list_for_each_entry(pamt_page, pamt_pages, lru) { + *p = page_to_phys(pamt_page); + p++; + } + } tdx_clflush_page(page); - ret = seamcall_ret(TDH_MEM_PAGE_DEMOTE, &args); + ret = seamcall_saved_ret(TDH_MEM_PAGE_DEMOTE, &args); *ext_err1 = args.rcx; *ext_err2 = args.rdx; -- 2.43.2