From: "Kalyazin, Nikita" <kalyazin@amazon.co.uk>
To: "kvm@vger.kernel.org" <kvm@vger.kernel.org>,
"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>,
"kvmarm@lists.linux.dev" <kvmarm@lists.linux.dev>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
"linux-mm@kvack.org" <linux-mm@kvack.org>,
"bpf@vger.kernel.org" <bpf@vger.kernel.org>,
"linux-kselftest@vger.kernel.org"
<linux-kselftest@vger.kernel.org>,
"kernel@xen0n.name" <kernel@xen0n.name>,
"linux-riscv@lists.infradead.org"
<linux-riscv@lists.infradead.org>,
"linux-s390@vger.kernel.org" <linux-s390@vger.kernel.org>,
"loongarch@lists.linux.dev" <loongarch@lists.linux.dev>
Cc: "pbonzini@redhat.com" <pbonzini@redhat.com>,
"corbet@lwn.net" <corbet@lwn.net>,
"maz@kernel.org" <maz@kernel.org>,
"oupton@kernel.org" <oupton@kernel.org>,
"joey.gouly@arm.com" <joey.gouly@arm.com>,
"suzuki.poulose@arm.com" <suzuki.poulose@arm.com>,
"yuzenghui@huawei.com" <yuzenghui@huawei.com>,
"catalin.marinas@arm.com" <catalin.marinas@arm.com>,
"will@kernel.org" <will@kernel.org>,
"seanjc@google.com" <seanjc@google.com>,
"tglx@kernel.org" <tglx@kernel.org>,
"mingo@redhat.com" <mingo@redhat.com>,
"bp@alien8.de" <bp@alien8.de>,
"dave.hansen@linux.intel.com" <dave.hansen@linux.intel.com>,
"x86@kernel.org" <x86@kernel.org>,
"hpa@zytor.com" <hpa@zytor.com>,
"luto@kernel.org" <luto@kernel.org>,
"peterz@infradead.org" <peterz@infradead.org>,
"willy@infradead.org" <willy@infradead.org>,
"akpm@linux-foundation.org" <akpm@linux-foundation.org>,
"david@kernel.org" <david@kernel.org>,
"lorenzo.stoakes@oracle.com" <lorenzo.stoakes@oracle.com>,
"vbabka@suse.cz" <vbabka@suse.cz>,
"rppt@kernel.org" <rppt@kernel.org>,
"surenb@google.com" <surenb@google.com>,
"mhocko@suse.com" <mhocko@suse.com>,
"ast@kernel.org" <ast@kernel.org>,
"daniel@iogearbox.net" <daniel@iogearbox.net>,
"andrii@kernel.org" <andrii@kernel.org>,
"martin.lau@linux.dev" <martin.lau@linux.dev>,
"eddyz87@gmail.com" <eddyz87@gmail.com>,
"song@kernel.org" <song@kernel.org>,
"yonghong.song@linux.dev" <yonghong.song@linux.dev>,
"john.fastabend@gmail.com" <john.fastabend@gmail.com>,
"kpsingh@kernel.org" <kpsingh@kernel.org>,
"sdf@fomichev.me" <sdf@fomichev.me>,
"haoluo@google.com" <haoluo@google.com>,
"jolsa@kernel.org" <jolsa@kernel.org>,
"jgg@ziepe.ca" <jgg@ziepe.ca>,
"jhubbard@nvidia.com" <jhubbard@nvidia.com>,
"peterx@redhat.com" <peterx@redhat.com>,
"jannh@google.com" <jannh@google.com>,
"pfalcato@suse.de" <pfalcato@suse.de>,
"shuah@kernel.org" <shuah@kernel.org>,
"riel@surriel.com" <riel@surriel.com>,
"ryan.roberts@arm.com" <ryan.roberts@arm.com>,
"jgross@suse.com" <jgross@suse.com>,
"yu-cheng.yu@intel.com" <yu-cheng.yu@intel.com>,
"kas@kernel.org" <kas@kernel.org>,
"coxu@redhat.com" <coxu@redhat.com>,
"kevin.brodsky@arm.com" <kevin.brodsky@arm.com>,
"ackerleytng@google.com" <ackerleytng@google.com>,
"maobibo@loongson.cn" <maobibo@loongson.cn>,
"prsampat@amd.com" <prsampat@amd.com>,
"mlevitsk@redhat.com" <mlevitsk@redhat.com>,
"jmattson@google.com" <jmattson@google.com>,
"jthoughton@google.com" <jthoughton@google.com>,
"agordeev@linux.ibm.com" <agordeev@linux.ibm.com>,
"alex@ghiti.fr" <alex@ghiti.fr>,
"aou@eecs.berkeley.edu" <aou@eecs.berkeley.edu>,
"borntraeger@linux.ibm.com" <borntraeger@linux.ibm.com>,
"chenhuacai@kernel.org" <chenhuacai@kernel.org>,
"dev.jain@arm.com" <dev.jain@arm.com>,
"gor@linux.ibm.com" <gor@linux.ibm.com>,
"hca@linux.ibm.com" <hca@linux.ibm.com>,
"palmer@dabbelt.com" <palmer@dabbelt.com>,
"pjw@kernel.org" <pjw@kernel.org>,
"shijie@os.amperecomputing.com" <shijie@os.amperecomputing.com>,
"svens@linux.ibm.com" <svens@linux.ibm.com>,
"thuth@redhat.com" <thuth@redhat.com>,
"wyihan@google.com" <wyihan@google.com>,
"yang@os.amperecomputing.com" <yang@os.amperecomputing.com>,
"Jonathan.Cameron@huawei.com" <Jonathan.Cameron@huawei.com>,
"Liam.Howlett@oracle.com" <Liam.Howlett@oracle.com>,
"urezki@gmail.com" <urezki@gmail.com>,
"zhengqi.arch@bytedance.com" <zhengqi.arch@bytedance.com>,
"gerald.schaefer@linux.ibm.com" <gerald.schaefer@linux.ibm.com>,
"jiayuan.chen@shopee.com" <jiayuan.chen@shopee.com>,
"lenb@kernel.org" <lenb@kernel.org>,
"osalvador@suse.de" <osalvador@suse.de>,
"pavel@kernel.org" <pavel@kernel.org>,
"rafael@kernel.org" <rafael@kernel.org>,
"vannapurve@google.com" <vannapurve@google.com>,
"jackmanb@google.com" <jackmanb@google.com>,
"aneesh.kumar@kernel.org" <aneesh.kumar@kernel.org>,
"patrick.roy@linux.dev" <patrick.roy@linux.dev>,
"Thomson, Jack" <jackabt@amazon.co.uk>,
"Itazuri, Takahiro" <itazur@amazon.co.uk>,
"Manwaring, Derek" <derekmn@amazon.com>,
"Cali, Marco" <xmarcalx@amazon.co.uk>,
"Kalyazin, Nikita" <kalyazin@amazon.co.uk>
Subject: [PATCH v10 02/15] set_memory: add folio_{zap,restore}_direct_map helpers
Date: Mon, 26 Jan 2026 16:47:11 +0000 [thread overview]
Message-ID: <20260126164445.11867-3-kalyazin@amazon.com> (raw)
In-Reply-To: <20260126164445.11867-1-kalyazin@amazon.com>
From: Nikita Kalyazin <kalyazin@amazon.com>
These allow guest_memfd to remove its memory from the direct map.
Only implement them for architectures that have direct map.
In folio_zap_direct_map(), flush TLB on architectures where
set_direct_map_valid_noflush() does not flush it internally.
The new helpers need to be accessible to KVM on architectures that
support guest_memfd (x86 and arm64). Since arm64 does not support
building KVM as a module, only export them on x86.
Direct map removal gives guest_memfd the same protection that
memfd_secret does, such as hardening against Spectre-like attacks
through in-kernel gadgets.
Reviewed-by: Ackerley Tng <ackerleytng@google.com>
Signed-off-by: Nikita Kalyazin <kalyazin@amazon.com>
---
arch/arm64/include/asm/set_memory.h | 2 ++
arch/arm64/mm/pageattr.c | 12 ++++++++++++
arch/loongarch/include/asm/set_memory.h | 2 ++
arch/loongarch/mm/pageattr.c | 12 ++++++++++++
arch/riscv/include/asm/set_memory.h | 2 ++
arch/riscv/mm/pageattr.c | 12 ++++++++++++
arch/s390/include/asm/set_memory.h | 2 ++
arch/s390/mm/pageattr.c | 12 ++++++++++++
arch/x86/include/asm/set_memory.h | 2 ++
arch/x86/mm/pat/set_memory.c | 20 ++++++++++++++++++++
include/linux/set_memory.h | 10 ++++++++++
11 files changed, 88 insertions(+)
diff --git a/arch/arm64/include/asm/set_memory.h b/arch/arm64/include/asm/set_memory.h
index c71a2a6812c4..49fd54f3c265 100644
--- a/arch/arm64/include/asm/set_memory.h
+++ b/arch/arm64/include/asm/set_memory.h
@@ -15,6 +15,8 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
bool kernel_page_present(struct page *page);
int set_memory_encrypted(unsigned long addr, int numpages);
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index e2bdc3c1f992..0b88b0344499 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -356,6 +356,18 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return set_memory_valid((unsigned long)addr, numpages, valid);
}
+int folio_zap_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), false);
+}
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
+
#ifdef CONFIG_DEBUG_PAGEALLOC
/*
* This is - apart from the return value - doing the same
diff --git a/arch/loongarch/include/asm/set_memory.h b/arch/loongarch/include/asm/set_memory.h
index 5e9b67b2fea1..1cdec6afe209 100644
--- a/arch/loongarch/include/asm/set_memory.h
+++ b/arch/loongarch/include/asm/set_memory.h
@@ -19,5 +19,7 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
#endif /* _ASM_LOONGARCH_SET_MEMORY_H */
diff --git a/arch/loongarch/mm/pageattr.c b/arch/loongarch/mm/pageattr.c
index c1b2be915038..be397fddc991 100644
--- a/arch/loongarch/mm/pageattr.c
+++ b/arch/loongarch/mm/pageattr.c
@@ -235,3 +235,15 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return __set_memory((unsigned long)addr, 1, set, clear);
}
+
+int folio_zap_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), false);
+}
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
index a87eabd7fc78..208755d9d45e 100644
--- a/arch/riscv/include/asm/set_memory.h
+++ b/arch/riscv/include/asm/set_memory.h
@@ -44,6 +44,8 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
bool kernel_page_present(struct page *page);
#endif /* __ASSEMBLER__ */
diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index 0a457177a88c..9a8237658c48 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -402,6 +402,18 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return __set_memory((unsigned long)addr, numpages, set, clear);
}
+int folio_zap_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), false);
+}
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
+
#ifdef CONFIG_DEBUG_PAGEALLOC
static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data)
{
diff --git a/arch/s390/include/asm/set_memory.h b/arch/s390/include/asm/set_memory.h
index 3e43c3c96e67..a51ff50df3ca 100644
--- a/arch/s390/include/asm/set_memory.h
+++ b/arch/s390/include/asm/set_memory.h
@@ -64,6 +64,8 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
bool kernel_page_present(struct page *page);
#endif
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index e231757bb0e0..f739fee0e110 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -413,6 +413,18 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return __set_memory((unsigned long)addr, numpages, flags);
}
+int folio_zap_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), false);
+}
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
+
bool kernel_page_present(struct page *page)
{
unsigned long addr;
diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index f912191f0853..febbfbdc39df 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -91,6 +91,8 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
bool kernel_page_present(struct page *page);
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 bc8e1c23175b..4a5a3124a92d 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -2657,6 +2657,26 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return __set_pages_np(addr, numpages);
}
+int folio_zap_direct_map(struct folio *folio)
+{
+ const void *addr = folio_address(folio);
+ int ret;
+
+ ret = set_direct_map_valid_noflush(addr, folio_nr_pages(folio), false);
+ flush_tlb_kernel_range((unsigned long)addr,
+ (unsigned long)addr + folio_size(folio));
+
+ return ret;
+}
+EXPORT_SYMBOL_FOR_MODULES(folio_zap_direct_map, "kvm");
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
+EXPORT_SYMBOL_FOR_MODULES(folio_restore_direct_map, "kvm");
+
#ifdef CONFIG_DEBUG_PAGEALLOC
void __kernel_map_pages(struct page *page, int numpages, int enable)
{
diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
index 1a2563f525fc..e2e6485f88db 100644
--- a/include/linux/set_memory.h
+++ b/include/linux/set_memory.h
@@ -41,6 +41,16 @@ static inline int set_direct_map_valid_noflush(const void *addr,
return 0;
}
+static inline int folio_zap_direct_map(struct folio *folio)
+{
+ return 0;
+}
+
+static inline int folio_restore_direct_map(struct folio *folio)
+{
+ return 0;
+}
+
static inline bool kernel_page_present(struct page *page)
{
return true;
--
2.50.1
WARNING: multiple messages have this Message-ID (diff)
From: "Kalyazin, Nikita" <kalyazin@amazon.co.uk>
To: "kvm@vger.kernel.org" <kvm@vger.kernel.org>,
"linux-doc@vger.kernel.org" <linux-doc@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>,
"kvmarm@lists.linux.dev" <kvmarm@lists.linux.dev>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
"linux-mm@kvack.org" <linux-mm@kvack.org>,
"bpf@vger.kernel.org" <bpf@vger.kernel.org>,
"linux-kselftest@vger.kernel.org"
<linux-kselftest@vger.kernel.org>,
"kernel@xen0n.name" <kernel@xen0n.name>,
"linux-riscv@lists.infradead.org"
<linux-riscv@lists.infradead.org>,
"linux-s390@vger.kernel.org" <linux-s390@vger.kernel.org>,
"loongarch@lists.linux.dev" <loongarch@lists.linux.dev>
Cc: "pbonzini@redhat.com" <pbonzini@redhat.com>,
"corbet@lwn.net" <corbet@lwn.net>,
"maz@kernel.org" <maz@kernel.org>,
"oupton@kernel.org" <oupton@kernel.org>,
"joey.gouly@arm.com" <joey.gouly@arm.com>,
"suzuki.poulose@arm.com" <suzuki.poulose@arm.com>,
"yuzenghui@huawei.com" <yuzenghui@huawei.com>,
"catalin.marinas@arm.com" <catalin.marinas@arm.com>,
"will@kernel.org" <will@kernel.org>,
"seanjc@google.com" <seanjc@google.com>,
"tglx@kernel.org" <tglx@kernel.org>,
"mingo@redhat.com" <mingo@redhat.com>,
"bp@alien8.de" <bp@alien8.de>,
"dave.hansen@linux.intel.com" <dave.hansen@linux.intel.com>,
"x86@kernel.org" <x86@kernel.org>,
"hpa@zytor.com" <hpa@zytor.com>,
"luto@kernel.org" <luto@kernel.org>,
"peterz@infradead.org" <peterz@infradead.org>,
"willy@infradead.org" <willy@infradead.org>,
"akpm@linux-foundation.org" <akpm@linux-foundation.org>,
"david@kernel.org" <david@kernel.org>,
"lorenzo.stoakes@oracle.com" <lorenzo.stoakes@oracle.com>,
"vbabka@suse.cz" <vbabka@suse.cz>,
"rppt@kernel.org" <rppt@kernel.org>,
"surenb@google.com" <surenb@google.com>,
"mhocko@suse.com" <mhocko@suse.com>,
"ast@kernel.org" <ast@kernel.org>,
"daniel@iogearbox.net" <daniel@iogearbox.net>,
"andrii@kernel.org" <andrii@kernel.org>,
"martin.lau@linux.dev" <martin.lau@linux.dev>,
"eddyz87@gmail.com" <eddyz87@gmail.com>,
"song@kernel.org" <song@kernel.org>,
"yonghong.song@linux.dev" <yonghong.song@linux.dev>,
"john.fastabend@gmail.com" <john.fastabend@gmail.com>,
"kpsingh@kernel.org" <kpsingh@kernel.org>,
"sdf@fomichev.me" <sdf@fomichev.me>,
"haoluo@google.com" <haoluo@google.com>,
"jolsa@kernel.org" <jolsa@kernel.org>,
"jgg@ziepe.ca" <jgg@ziepe.ca>,
"jhubbard@nvidia.com" <jhubbard@nvidia.com>,
"peterx@redhat.com" <peterx@redhat.com>,
"jannh@google.com" <jannh@google.com>,
"pfalcato@suse.de" <pfalcato@suse.de>,
"shuah@kernel.org" <shuah@kernel.org>,
"riel@surriel.com" <riel@surriel.com>,
"ryan.roberts@arm.com" <ryan.roberts@arm.com>,
"jgross@suse.com" <jgross@suse.com>,
"yu-cheng.yu@intel.com" <yu-cheng.yu@intel.com>,
"kas@kernel.org" <kas@kernel.org>,
"coxu@redhat.com" <coxu@redhat.com>,
"kevin.brodsky@arm.com" <kevin.brodsky@arm.com>,
"ackerleytng@google.com" <ackerleytng@google.com>,
"maobibo@loongson.cn" <maobibo@loongson.cn>,
"prsampat@amd.com" <prsampat@amd.com>,
"mlevitsk@redhat.com" <mlevitsk@redhat.com>,
"jmattson@google.com" <jmattson@google.com>,
"jthoughton@google.com" <jthoughton@google.com>,
"agordeev@linux.ibm.com" <agordeev@linux.ibm.com>,
"alex@ghiti.fr" <alex@ghiti.fr>,
"aou@eecs.berkeley.edu" <aou@eecs.berkeley.edu>,
"borntraeger@linux.ibm.com" <borntraeger@linux.ibm.com>,
"chenhuacai@kernel.org" <chenhuacai@kernel.org>,
"dev.jain@arm.com" <dev.jain@arm.com>,
"gor@linux.ibm.com" <gor@linux.ibm.com>,
"hca@linux.ibm.com" <hca@linux.ibm.com>,
"palmer@dabbelt.com" <palmer@dabbelt.com>,
"pjw@kernel.org" <pjw@kernel.org>,
"shijie@os.amperecomputing.com" <shijie@os.amperecomputing.com>,
"svens@linux.ibm.com" <svens@linux.ibm.com>,
"thuth@redhat.com" <thuth@redhat.com>,
"wyihan@google.com" <wyihan@google.com>,
"yang@os.amperecomputing.com" <yang@os.amperecomputing.com>,
"Jonathan.Cameron@huawei.com" <Jonathan.Cameron@huawei.com>,
"Liam.Howlett@oracle.com" <Liam.Howlett@oracle.com>,
"urezki@gmail.com" <urezki@gmail.com>,
"zhengqi.arch@bytedance.com" <zhengqi.arch@bytedance.com>,
"gerald.schaefer@linux.ibm.com" <gerald.schaefer@linux.ibm.com>,
"jiayuan.chen@shopee.com" <jiayuan.chen@shopee.com>,
"lenb@kernel.org" <lenb@kernel.org>,
"osalvador@suse.de" <osalvador@suse.de>,
"pavel@kernel.org" <pavel@kernel.org>,
"rafael@kernel.org" <rafael@kernel.org>,
"vannapurve@google.com" <vannapurve@google.com>,
"jackmanb@google.com" <jackmanb@google.com>,
"aneesh.kumar@kernel.org" <aneesh.kumar@kernel.org>,
"patrick.roy@linux.dev" <patrick.roy@linux.dev>,
"Thomson, Jack" <jackabt@amazon.co.uk>,
"Itazuri, Takahiro" <itazur@amazon.co.uk>,
"Manwaring, Derek" <derekmn@amazon.com>,
"Cali, Marco" <xmarcalx@amazon.co.uk>,
"Kalyazin, Nikita" <kalyazin@amazon.co.uk>
Subject: [PATCH v10 02/15] set_memory: add folio_{zap,restore}_direct_map helpers
Date: Mon, 26 Jan 2026 16:47:11 +0000 [thread overview]
Message-ID: <20260126164445.11867-3-kalyazin@amazon.com> (raw)
In-Reply-To: <20260126164445.11867-1-kalyazin@amazon.com>
From: Nikita Kalyazin <kalyazin@amazon.com>
These allow guest_memfd to remove its memory from the direct map.
Only implement them for architectures that have direct map.
In folio_zap_direct_map(), flush TLB on architectures where
set_direct_map_valid_noflush() does not flush it internally.
The new helpers need to be accessible to KVM on architectures that
support guest_memfd (x86 and arm64). Since arm64 does not support
building KVM as a module, only export them on x86.
Direct map removal gives guest_memfd the same protection that
memfd_secret does, such as hardening against Spectre-like attacks
through in-kernel gadgets.
Reviewed-by: Ackerley Tng <ackerleytng@google.com>
Signed-off-by: Nikita Kalyazin <kalyazin@amazon.com>
---
arch/arm64/include/asm/set_memory.h | 2 ++
arch/arm64/mm/pageattr.c | 12 ++++++++++++
arch/loongarch/include/asm/set_memory.h | 2 ++
arch/loongarch/mm/pageattr.c | 12 ++++++++++++
arch/riscv/include/asm/set_memory.h | 2 ++
arch/riscv/mm/pageattr.c | 12 ++++++++++++
arch/s390/include/asm/set_memory.h | 2 ++
arch/s390/mm/pageattr.c | 12 ++++++++++++
arch/x86/include/asm/set_memory.h | 2 ++
arch/x86/mm/pat/set_memory.c | 20 ++++++++++++++++++++
include/linux/set_memory.h | 10 ++++++++++
11 files changed, 88 insertions(+)
diff --git a/arch/arm64/include/asm/set_memory.h b/arch/arm64/include/asm/set_memory.h
index c71a2a6812c4..49fd54f3c265 100644
--- a/arch/arm64/include/asm/set_memory.h
+++ b/arch/arm64/include/asm/set_memory.h
@@ -15,6 +15,8 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
bool kernel_page_present(struct page *page);
int set_memory_encrypted(unsigned long addr, int numpages);
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index e2bdc3c1f992..0b88b0344499 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -356,6 +356,18 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return set_memory_valid((unsigned long)addr, numpages, valid);
}
+int folio_zap_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), false);
+}
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
+
#ifdef CONFIG_DEBUG_PAGEALLOC
/*
* This is - apart from the return value - doing the same
diff --git a/arch/loongarch/include/asm/set_memory.h b/arch/loongarch/include/asm/set_memory.h
index 5e9b67b2fea1..1cdec6afe209 100644
--- a/arch/loongarch/include/asm/set_memory.h
+++ b/arch/loongarch/include/asm/set_memory.h
@@ -19,5 +19,7 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
#endif /* _ASM_LOONGARCH_SET_MEMORY_H */
diff --git a/arch/loongarch/mm/pageattr.c b/arch/loongarch/mm/pageattr.c
index c1b2be915038..be397fddc991 100644
--- a/arch/loongarch/mm/pageattr.c
+++ b/arch/loongarch/mm/pageattr.c
@@ -235,3 +235,15 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return __set_memory((unsigned long)addr, 1, set, clear);
}
+
+int folio_zap_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), false);
+}
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
index a87eabd7fc78..208755d9d45e 100644
--- a/arch/riscv/include/asm/set_memory.h
+++ b/arch/riscv/include/asm/set_memory.h
@@ -44,6 +44,8 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
bool kernel_page_present(struct page *page);
#endif /* __ASSEMBLER__ */
diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index 0a457177a88c..9a8237658c48 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -402,6 +402,18 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return __set_memory((unsigned long)addr, numpages, set, clear);
}
+int folio_zap_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), false);
+}
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
+
#ifdef CONFIG_DEBUG_PAGEALLOC
static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data)
{
diff --git a/arch/s390/include/asm/set_memory.h b/arch/s390/include/asm/set_memory.h
index 3e43c3c96e67..a51ff50df3ca 100644
--- a/arch/s390/include/asm/set_memory.h
+++ b/arch/s390/include/asm/set_memory.h
@@ -64,6 +64,8 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
bool kernel_page_present(struct page *page);
#endif
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index e231757bb0e0..f739fee0e110 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -413,6 +413,18 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return __set_memory((unsigned long)addr, numpages, flags);
}
+int folio_zap_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), false);
+}
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
+
bool kernel_page_present(struct page *page)
{
unsigned long addr;
diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h
index f912191f0853..febbfbdc39df 100644
--- a/arch/x86/include/asm/set_memory.h
+++ b/arch/x86/include/asm/set_memory.h
@@ -91,6 +91,8 @@ int set_direct_map_invalid_noflush(const void *addr);
int set_direct_map_default_noflush(const void *addr);
int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
bool valid);
+int folio_zap_direct_map(struct folio *folio);
+int folio_restore_direct_map(struct folio *folio);
bool kernel_page_present(struct page *page);
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 bc8e1c23175b..4a5a3124a92d 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -2657,6 +2657,26 @@ int set_direct_map_valid_noflush(const void *addr, unsigned long numpages,
return __set_pages_np(addr, numpages);
}
+int folio_zap_direct_map(struct folio *folio)
+{
+ const void *addr = folio_address(folio);
+ int ret;
+
+ ret = set_direct_map_valid_noflush(addr, folio_nr_pages(folio), false);
+ flush_tlb_kernel_range((unsigned long)addr,
+ (unsigned long)addr + folio_size(folio));
+
+ return ret;
+}
+EXPORT_SYMBOL_FOR_MODULES(folio_zap_direct_map, "kvm");
+
+int folio_restore_direct_map(struct folio *folio)
+{
+ return set_direct_map_valid_noflush(folio_address(folio),
+ folio_nr_pages(folio), true);
+}
+EXPORT_SYMBOL_FOR_MODULES(folio_restore_direct_map, "kvm");
+
#ifdef CONFIG_DEBUG_PAGEALLOC
void __kernel_map_pages(struct page *page, int numpages, int enable)
{
diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h
index 1a2563f525fc..e2e6485f88db 100644
--- a/include/linux/set_memory.h
+++ b/include/linux/set_memory.h
@@ -41,6 +41,16 @@ static inline int set_direct_map_valid_noflush(const void *addr,
return 0;
}
+static inline int folio_zap_direct_map(struct folio *folio)
+{
+ return 0;
+}
+
+static inline int folio_restore_direct_map(struct folio *folio)
+{
+ return 0;
+}
+
static inline bool kernel_page_present(struct page *page)
{
return true;
--
2.50.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2026-01-26 16:47 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-26 16:46 [PATCH v10 00/15] Direct Map Removal Support for guest_memfd Kalyazin, Nikita
2026-01-26 16:46 ` Kalyazin, Nikita
2026-01-26 16:46 ` [PATCH v10 01/15] set_memory: set_direct_map_* to take address Kalyazin, Nikita
2026-01-26 16:46 ` Kalyazin, Nikita
2026-01-28 12:18 ` kernel test robot
2026-01-28 12:18 ` kernel test robot
2026-03-05 17:23 ` David Hildenbrand (Arm)
2026-03-05 17:23 ` David Hildenbrand (Arm)
2026-03-06 12:48 ` Nikita Kalyazin
2026-03-06 12:48 ` Nikita Kalyazin
2026-01-26 16:47 ` Kalyazin, Nikita [this message]
2026-01-26 16:47 ` [PATCH v10 02/15] set_memory: add folio_{zap,restore}_direct_map helpers Kalyazin, Nikita
2026-03-05 17:34 ` David Hildenbrand (Arm)
2026-03-05 17:34 ` David Hildenbrand (Arm)
2026-03-06 12:48 ` [PATCH v10 02/15] set_memory: add folio_{zap, restore}_direct_map helpers Nikita Kalyazin
2026-03-06 12:48 ` Nikita Kalyazin
2026-03-06 14:17 ` David Hildenbrand (Arm)
2026-03-06 14:17 ` David Hildenbrand (Arm)
2026-03-06 14:48 ` Nikita Kalyazin
2026-03-06 14:48 ` Nikita Kalyazin
2026-03-06 15:17 ` David Hildenbrand (Arm)
2026-03-06 15:17 ` David Hildenbrand (Arm)
2026-03-06 15:41 ` Nikita Kalyazin
2026-03-06 15:41 ` Nikita Kalyazin
2026-03-06 20:06 ` David Hildenbrand (Arm)
2026-03-06 20:06 ` David Hildenbrand (Arm)
2026-01-26 16:47 ` [PATCH v10 03/15] mm/gup: drop secretmem optimization from gup_fast_folio_allowed Kalyazin, Nikita
2026-01-26 16:47 ` Kalyazin, Nikita
2026-01-26 16:47 ` [PATCH v10 04/15] mm/gup: drop local variable in gup_fast_folio_allowed Kalyazin, Nikita
2026-01-26 16:47 ` Kalyazin, Nikita
2026-03-05 19:07 ` David Hildenbrand (Arm)
2026-03-05 19:07 ` David Hildenbrand (Arm)
2026-03-06 12:49 ` Nikita Kalyazin
2026-03-06 12:49 ` Nikita Kalyazin
2026-01-26 16:47 ` [PATCH v10 05/15] mm: introduce AS_NO_DIRECT_MAP Kalyazin, Nikita
2026-01-26 16:47 ` Kalyazin, Nikita
2026-01-26 16:49 ` [PATCH v10 06/15] KVM: guest_memfd: Add stub for kvm_arch_gmem_invalidate Kalyazin, Nikita
2026-01-26 16:49 ` Kalyazin, Nikita
2026-01-26 16:50 ` [PATCH v10 07/15] KVM: x86: define kvm_arch_gmem_supports_no_direct_map() Kalyazin, Nikita
2026-01-26 16:50 ` Kalyazin, Nikita
2026-03-05 19:08 ` David Hildenbrand (Arm)
2026-03-05 19:08 ` David Hildenbrand (Arm)
2026-01-26 16:50 ` [PATCH v10 08/15] KVM: arm64: " Kalyazin, Nikita
2026-01-26 16:50 ` Kalyazin, Nikita
2026-03-05 19:08 ` David Hildenbrand (Arm)
2026-03-05 19:08 ` David Hildenbrand (Arm)
2026-01-26 16:50 ` [PATCH v10 09/15] KVM: guest_memfd: Add flag to remove from direct map Kalyazin, Nikita
2026-01-26 16:50 ` Kalyazin, Nikita
2026-03-05 19:18 ` David Hildenbrand (Arm)
2026-03-05 19:18 ` David Hildenbrand (Arm)
2026-03-06 12:49 ` Nikita Kalyazin
2026-03-06 12:49 ` Nikita Kalyazin
2026-03-06 14:22 ` David Hildenbrand (Arm)
2026-03-06 14:22 ` David Hildenbrand (Arm)
2026-03-06 14:49 ` Nikita Kalyazin
2026-03-06 14:49 ` Nikita Kalyazin
2026-03-06 15:16 ` David Hildenbrand (Arm)
2026-03-06 15:16 ` David Hildenbrand (Arm)
2026-03-06 15:42 ` Nikita Kalyazin
2026-03-06 15:42 ` Nikita Kalyazin
2026-01-26 16:50 ` [PATCH v10 10/15] KVM: selftests: load elf via bounce buffer Kalyazin, Nikita
2026-01-26 16:50 ` Kalyazin, Nikita
2026-01-26 16:50 ` [PATCH v10 11/15] KVM: selftests: set KVM_MEM_GUEST_MEMFD in vm_mem_add() if guest_memfd != -1 Kalyazin, Nikita
2026-01-26 16:50 ` Kalyazin, Nikita
2026-01-26 16:53 ` [PATCH v10 12/15] KVM: selftests: Add guest_memfd based vm_mem_backing_src_types Kalyazin, Nikita
2026-01-26 16:53 ` Kalyazin, Nikita
2026-01-26 16:53 ` [PATCH v10 13/15] KVM: selftests: cover GUEST_MEMFD_FLAG_NO_DIRECT_MAP in existing selftests Kalyazin, Nikita
2026-01-26 16:53 ` Kalyazin, Nikita
2026-01-26 16:53 ` [PATCH v10 14/15] KVM: selftests: stuff vm_mem_backing_src_type into vm_shape Kalyazin, Nikita
2026-01-26 16:53 ` Kalyazin, Nikita
2026-01-26 16:53 ` [PATCH v10 15/15] KVM: selftests: Test guest execution from direct map removed gmem Kalyazin, Nikita
2026-01-26 16:53 ` Kalyazin, Nikita
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=20260126164445.11867-3-kalyazin@amazon.com \
--to=kalyazin@amazon.co.uk \
--cc=Jonathan.Cameron@huawei.com \
--cc=Liam.Howlett@oracle.com \
--cc=ackerleytng@google.com \
--cc=agordeev@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=andrii@kernel.org \
--cc=aneesh.kumar@kernel.org \
--cc=aou@eecs.berkeley.edu \
--cc=ast@kernel.org \
--cc=borntraeger@linux.ibm.com \
--cc=bp@alien8.de \
--cc=bpf@vger.kernel.org \
--cc=catalin.marinas@arm.com \
--cc=chenhuacai@kernel.org \
--cc=corbet@lwn.net \
--cc=coxu@redhat.com \
--cc=daniel@iogearbox.net \
--cc=dave.hansen@linux.intel.com \
--cc=david@kernel.org \
--cc=derekmn@amazon.com \
--cc=dev.jain@arm.com \
--cc=eddyz87@gmail.com \
--cc=gerald.schaefer@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=haoluo@google.com \
--cc=hca@linux.ibm.com \
--cc=hpa@zytor.com \
--cc=itazur@amazon.co.uk \
--cc=jackabt@amazon.co.uk \
--cc=jackmanb@google.com \
--cc=jannh@google.com \
--cc=jgg@ziepe.ca \
--cc=jgross@suse.com \
--cc=jhubbard@nvidia.com \
--cc=jiayuan.chen@shopee.com \
--cc=jmattson@google.com \
--cc=joey.gouly@arm.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=jthoughton@google.com \
--cc=kas@kernel.org \
--cc=kernel@xen0n.name \
--cc=kevin.brodsky@arm.com \
--cc=kpsingh@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=lenb@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-s390@vger.kernel.org \
--cc=loongarch@lists.linux.dev \
--cc=lorenzo.stoakes@oracle.com \
--cc=luto@kernel.org \
--cc=maobibo@loongson.cn \
--cc=martin.lau@linux.dev \
--cc=maz@kernel.org \
--cc=mhocko@suse.com \
--cc=mingo@redhat.com \
--cc=mlevitsk@redhat.com \
--cc=osalvador@suse.de \
--cc=oupton@kernel.org \
--cc=palmer@dabbelt.com \
--cc=patrick.roy@linux.dev \
--cc=pavel@kernel.org \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=peterz@infradead.org \
--cc=pfalcato@suse.de \
--cc=pjw@kernel.org \
--cc=prsampat@amd.com \
--cc=rafael@kernel.org \
--cc=riel@surriel.com \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=sdf@fomichev.me \
--cc=seanjc@google.com \
--cc=shijie@os.amperecomputing.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=surenb@google.com \
--cc=suzuki.poulose@arm.com \
--cc=svens@linux.ibm.com \
--cc=tglx@kernel.org \
--cc=thuth@redhat.com \
--cc=urezki@gmail.com \
--cc=vannapurve@google.com \
--cc=vbabka@suse.cz \
--cc=will@kernel.org \
--cc=willy@infradead.org \
--cc=wyihan@google.com \
--cc=x86@kernel.org \
--cc=xmarcalx@amazon.co.uk \
--cc=yang@os.amperecomputing.com \
--cc=yonghong.song@linux.dev \
--cc=yu-cheng.yu@intel.com \
--cc=yuzenghui@huawei.com \
--cc=zhengqi.arch@bytedance.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.