aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
authorLorenzo Stoakes <ljs@kernel.org>2026-05-22 17:00:11 +0100
committerAndrew Morton <akpm@linux-foundation.org>2026-05-28 21:31:22 -0700
commit7bf8b6eee04cd282aa84e81e3328a88593bbcad2 (patch)
treecd0798ac7255754bd6746e31a61a83bc9c5345de /mm
parentf9c8525ca8fe76a4659da57b0dc43fa2f7f3f7b0 (diff)
downloadlinux-next-history-7bf8b6eee04cd282aa84e81e3328a88593bbcad2.tar.gz
mm/vma: eliminate mmap_action->error_hook, introduce error_filter
Rather than providing a hook, simplify things by providing the ability to filter errors. This allows us to more carefully validate the value provided and thus ensure only a valid error code is specified, and simplifies the interface. This way, we eliminate all hooks but mmap_prepare and allow only mmap actions to be specified (which core mm controls). This significantly improves robustness and eliminates any unnecessary code duplication in driver mmap hooks. We also update the /dev/mem logic (the only user) to use mmap_action->error_filter instead. Link: https://lore.kernel.org/e770b28427937057fa953ac380a134b24acd8bb4.1779462249.git.ljs@kernel.org Signed-off-by: Lorenzo Stoakes <ljs@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: David Hildenbrand <david@kernel.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jann Horn <jannh@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Pedro Falcato <pfalcato@suse.de> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/util.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/mm/util.c b/mm/util.c
index 4e172990afcd2..9b4e5432d45a2 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -1414,16 +1414,22 @@ static int mmap_action_finish(struct vm_area_struct *vma,
*/
len = vma_pages(vma) << PAGE_SHIFT;
do_munmap(current->mm, vma->vm_start, len, NULL);
- if (action->error_hook) {
- /* We may want to filter the error. */
- err = action->error_hook(err);
- /* The caller should not clear the error. */
- VM_WARN_ON_ONCE(!err);
- }
- return err;
+
+ return action->error_filter ?: err;
}
#ifdef CONFIG_MMU
+
+static int check_mmap_action(struct mmap_action *action)
+{
+ const unsigned long filter = action->error_filter;
+
+ if (WARN_ON_ONCE(filter && !IS_ERR_VALUE(filter)))
+ return -EINVAL;
+
+ return 0;
+}
+
/**
* mmap_action_prepare - Perform preparatory setup for an VMA descriptor
* action which need to be performed.
@@ -1433,7 +1439,14 @@ static int mmap_action_finish(struct vm_area_struct *vma,
*/
int mmap_action_prepare(struct vm_area_desc *desc)
{
- switch (desc->action.type) {
+ struct mmap_action *action = &desc->action;
+ int err;
+
+ err = check_mmap_action(action);
+ if (err)
+ return err;
+
+ switch (action->type) {
case MMAP_NOTHING:
return 0;
case MMAP_REMAP_PFN: