From nobody Mon Jun 8 07:21:51 2026 Received: from out-180.mta1.migadu.com (out-180.mta1.migadu.com [95.215.58.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 946F6393DF9 for ; Wed, 3 Jun 2026 10:46:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780483617; cv=none; b=SLxHavzVSrhjmef/a7eB0m6hngF1BxUU9uRZmnAg/oJJpRkcrnnjLuVVwKQAwrinYQn6D0UU1EIPB+t/DCXjL9r2InuzfNQtKEfPhQCbnWEfDEy7H88Al0U1c0wLkQ81BojYquP8UBLBsonOt9aaFSZgy4yKNHSUc37VqkAPx4A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780483617; c=relaxed/simple; bh=arBLRd2RXbGU37kIlHpH8zRLqnB5OIV7b9T0SvTcAvI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jW1HC/9VQEah2W87e3ABr3paKQ4/QTQqB4CAHu/S7ep7Wsp6irE7PR77qro7YKBZmpfbt37uaDJhQngFSZIgYu3D/JunxGezbdTVm+dG8dUwX7SmdQg9Q2NxKLe4974bJFM+pcK5n0mQNp1Fvuyu3O3uX5JYGqdMchW+GSBrQzw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=SaLIqHE8; arc=none smtp.client-ip=95.215.58.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="SaLIqHE8" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780483613; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9Db5QI22S+PmAf36h4l+5enVOhe4SLTSWaLegqKX8Kk=; b=SaLIqHE8MVrLhRMMW0UhnyHGHtygmT+8OPgIfrPnznSMLhbnKq1Dva1IY/qFMx5UbuTa7B SRRrqJmht8UHrPAlzA+ElUGKuRkKgGHDfJc3y8Frp/EvyIGBjpEgN5lZz3e1bVLojR5plw Awtl1jk5pJEwB6evELNS5wwPVEkxrBw= From: Lance Yang To: akpm@linux-foundation.org Cc: rppt@kernel.org, david@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, luto@kernel.org, peterz@infradead.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, xueyuan.chen21@gmail.com, ioworker0@gmail.com, Lance Yang Subject: [RFC PATCH 1/2] mm/secretmem: try to restore large page mappings in direct map Date: Wed, 3 Jun 2026 18:46:23 +0800 Message-ID: <20260603104624.36390-2-lance.yang@linux.dev> In-Reply-To: <20260603104624.36390-1-lance.yang@linux.dev> References: <20260603104624.36390-1-lance.yang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Lance Yang secretmem removes the pages backing secretmem mappings from the direct map. Removing one base page from the direct map can split the covering large mapping down to PTE mappings. Repeated splits can leave more of the direct map mapped with PTEs, meaning more TLB entries for the same range and potentially more TLB pressure. So let's try to restore large page mappings whenever secretmem restores a folio to the direct map. Tested-by: Xueyuan Chen Signed-off-by: Lance Yang --- include/linux/set_memory.h | 6 ++++++ mm/secretmem.c | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h index 3030d9245f5a..ad2fa414a22d 100644 --- a/include/linux/set_memory.h +++ b/include/linux/set_memory.h @@ -58,6 +58,12 @@ static inline bool can_set_direct_map(void) #endif #endif /* CONFIG_ARCH_HAS_SET_DIRECT_MAP */ =20 +#ifndef arch_try_collapse_direct_map +static inline void arch_try_collapse_direct_map(struct page *page) +{ +} +#endif + #ifdef CONFIG_X86_64 int set_mce_nospec(unsigned long pfn); int clear_mce_nospec(unsigned long pfn); diff --git a/mm/secretmem.c b/mm/secretmem.c index 5f57ac4720d3..82634b99aa2c 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -47,6 +47,14 @@ bool secretmem_active(void) return !!atomic_read(&secretmem_users); } =20 +static void secretmem_restore_direct_map(struct folio *folio) +{ + struct page *page =3D folio_page(folio, 0); + + if (!set_direct_map_default_noflush(page)) + arch_try_collapse_direct_map(page); +} + static vm_fault_t secretmem_fault(struct vm_fault *vmf) { struct address_space *mapping =3D vmf->vma->vm_file->f_mapping; @@ -87,7 +95,7 @@ static vm_fault_t secretmem_fault(struct vm_fault *vmf) * already happened when we marked the page invalid * which guarantees that this call won't fail */ - set_direct_map_default_noflush(folio_page(folio, 0)); + secretmem_restore_direct_map(folio); folio_put(folio); if (err =3D=3D -EEXIST) goto retry; @@ -151,7 +159,7 @@ static int secretmem_migrate_folio(struct address_space= *mapping, =20 static void secretmem_free_folio(struct folio *folio) { - set_direct_map_default_noflush(folio_page(folio, 0)); + secretmem_restore_direct_map(folio); folio_zero_segment(folio, 0, folio_size(folio)); } =20 --=20 2.49.0 From nobody Mon Jun 8 07:21:51 2026 Received: from out-181.mta0.migadu.com (out-181.mta0.migadu.com [91.218.175.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1F26C3E6387 for ; Wed, 3 Jun 2026 10:47:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780483626; cv=none; b=Uh4KgVMVTUbhm6UcXJF3eeOYXjjldtosaUucKsgXm5cF1Z4sTdELxmtSRdCFwQWMqDPJOxRlRgJYQRtiZ29P1lsYcze/EoDUGKSuTS3tGekh9Xhbafio/6i+woxZ0qP5YMwrl3kxSjOQ0aWh300cMBh9B/+IBaIvRRUXNeC0RFE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780483626; c=relaxed/simple; bh=240t7hPkntlxBNqY/y60TPWf6svHw6mrl6KpWkVVIUQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nHBwjdgRUJuakLZ3MqvYDNVfsofLmpj8i/FCVWkKVUV/DEn7b7JyHMXJpDx7SuFKscN2f0f1Lal++Mw0hQ4DCQlxtFE5BXEKKp0wXaJqLiM8Lz+HZyNKsg3I8m4qcJgajRK495tzJwrwAZs/epXlkebVlVWNFolCcjQ5SBkKUgU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=rOGK+hjB; arc=none smtp.client-ip=91.218.175.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="rOGK+hjB" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1780483623; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uDivKNl50/oglC97Ig2qp3GHfbl7ogmTnLA9RISadv8=; b=rOGK+hjBTX7M1kHbQ2XvvKqnp1jett+Tj8n+9qKo5Zv3H4e7/UqA2vmrI/T5yoFdeZuONF s03n+ItMVdgigxDknLtYsctpJUmvx/njkgApQzgszPqIMOlLBj8XDhudjTBEYQHD+s35v4 Luvt6hhSwL3O36lOBXhUgAHFcCyOKYY= From: Lance Yang To: akpm@linux-foundation.org Cc: rppt@kernel.org, david@kernel.org, tglx@kernel.org, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, luto@kernel.org, peterz@infradead.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, xueyuan.chen21@gmail.com, ioworker0@gmail.com, Lance Yang Subject: [RFC PATCH 2/2] x86/mm: restore large page mappings for secretmem Date: Wed, 3 Jun 2026 18:46:24 +0800 Message-ID: <20260603104624.36390-3-lance.yang@linux.dev> In-Reply-To: <20260603104624.36390-1-lance.yang@linux.dev> References: <20260603104624.36390-1-lance.yang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Lance Yang secretmem can ask the architecture to restore large page mappings in the direct map after a page has been restored. On x86, set_direct_map_invalid_noflush() clears _PAGE_PRESENT, _PAGE_RW and _PAGE_DIRTY through CPA. CPA also clears _PAGE_GLOBAL after the PTE becomes non-present, because that bit is used for PROTNONE. set_direct_map_default_noflush() only restores _PAGE_PRESENT and _PAGE_RW, so the restored PTE can still differ from the rest of the direct map. Put back the missing PAGE_KERNEL bits before trying to collapse the range. Use PAGE_KERNEL so the restored PTE keeps _PAGE_GLOBAL when PAGE_KERNEL has it, and does not get it when PTI clears _PAGE_GLOBAL from __default_kernel_pte_mask. Tested-by: Xueyuan Chen Signed-off-by: Lance Yang --- arch/x86/include/asm/set_memory.h | 2 ++ arch/x86/mm/pat/set_memory.c | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_m= emory.h index 4362c26aa992..f9e94bcd83df 100644 --- a/arch/x86/include/asm/set_memory.h +++ b/arch/x86/include/asm/set_memory.h @@ -89,6 +89,8 @@ int set_pages_rw(struct page *page, int numpages); int set_direct_map_invalid_noflush(struct page *page); int set_direct_map_default_noflush(struct page *page); int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool vali= d); +void arch_try_collapse_direct_map(struct page *page); +#define arch_try_collapse_direct_map arch_try_collapse_direct_map bool kernel_page_present(struct page *page); =20 extern int kernel_set_to_readonly; diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index d023a40a1e03..b118619fa83c 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -2654,6 +2654,33 @@ int set_direct_map_default_noflush(struct page *page) return __set_pages_p(page, 1); } =20 +void arch_try_collapse_direct_map(struct page *page) +{ + pgprotval_t mask =3D pgprot_val(PAGE_KERNEL) & (_PAGE_DIRTY | _PAGE_GLOBA= L); + unsigned long addr; + struct cpa_data cpa =3D { .vaddr =3D &addr, + .pgd =3D NULL, + .numpages =3D 1, + .mask_set =3D __pgprot(mask), + .mask_clr =3D __pgprot(0), + .flags =3D CPA_NO_CHECK_ALIAS }; + + if (PageHighMem(page) || debug_pagealloc_enabled()) + return; + + addr =3D (unsigned long)page_address(page); + + /* + * set_direct_map_default_noflush() only restores _PAGE_PRESENT and + * _PAGE_RW. Put back the other PAGE_KERNEL bits needed for a restored + * direct-map PTE to match the rest of the range. + */ + if (__change_page_attr_set_clr(&cpa, 1)) + return; + + cpa_collapse_large_pages(&cpa); +} + int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool vali= d) { if (valid) --=20 2.49.0