FAILED: patch "[PATCH] mm: refactor arch_calc_vm_flag_bits() and arm64 MTE handling" failed to apply to 6.11-stable tree
Subsystems (6)
[email protected]
maintainerThe patch below does not apply to the 6.11-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.11.y
git checkout FETCH_HEAD
git cherry-pick -x 5baf8b037debf4ec60108ccfeccb8636d1dbad81
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024111135-thumb-pretended-bad3@gregkh' --subject-prefix 'PATCH 6.11.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 5baf8b037debf4ec60108ccfeccb8636d1dbad81 Mon Sep 17 00:00:00 2001
From: Lorenzo Stoakes <[email protected]>
Date: Tue, 29 Oct 2024 18:11:47 +0000
Subject: [PATCH] mm: refactor arch_calc_vm_flag_bits() and arm64 MTE handling
Currently MTE is permitted in two circumstances (desiring to use MTE having been specified by the VM_MTE flag) - where MAP_ANONYMOUS is specified, as checked by arch_calc_vm_flag_bits() and actualised by setting the VM_MTE_ALLOWED flag, or if the file backing the mapping is shmem, in which case we set VM_MTE_ALLOWED in shmem_mmap() when the mmap hook is activated in mmap_region().
The function that checks that, if VM_MTE is set, VM_MTE_ALLOWED is also set is the arm64 implementation of arch_validate_flags().
Unfortunately, we intend to refactor mmap_region() to perform this check earlier, meaning that in the case of a shmem backing we will not have invoked shmem_mmap() yet, causing the mapping to fail spuriously.
It is inappropriate to set this architecture-specific flag in general mm code anyway, so a sensible resolution of this issue is to instead move the check somewhere else.
We resolve this by setting VM_MTE_ALLOWED much earlier in do_mmap(), via the arch_calc_vm_flag_bits() call.
This is an appropriate place to do this as we already check for the MAP_ANONYMOUS case here, and the shmem file case is simply a variant of the same idea - we permit RAM-backed memory.
This requires a modification to the arch_calc_vm_flag_bits() signature to pass in a pointer to the struct file associated with the mapping, however this is not too egregious as this is only used by two architectures anyway
- arm64 and parisc.
So this patch performs this adjustment and removes the unnecessary assignment of VM_MTE_ALLOWED in shmem_mmap().
arch/arm64/include/asm/mman.h +7 -3
@@ -6,6 +6,8 @@#ifndef BUILD_VDSO #include <linux/compiler.h> +#include <linux/fs.h> +#include <linux/shmem_fs.h> #include <linux/types.h> static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
@@ -31,19 +33,21 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, }#define arch_calc_vm_prot_bits (prot, pkey) arch_calc_vm_prot_bits(prot, pkey) -static inline unsigned long arch_calc_vm_flag_bits (unsigned long flags) +static inline unsigned long arch_calc_vm_flag_bits (struct file *file, +unsigned long flags) {/* * Only allow MTE on anonymous mappings as these are guaranteed to be * backed by tags-capable memory. The vm_flags may be overridden by a * filesystem supporting MTE (RAM-based). */ -if (system_supports_mte () && (flags &MAP_ANONYMOUS )) +if (system_supports_mte () && + ((flags &MAP_ANONYMOUS ) ||shmem_file (file)))return VM_MTE_ALLOWED ;return 0 ; } -#define arch_calc_vm_flag_bits (flags) arch_calc_vm_flag_bits(flags) +#define arch_calc_vm_flag_bits (file, flags) arch_calc_vm_flag_bits(file, flags)static inline bool arch_validate_prot (unsigned long prot,unsigned long addr__always_unused )
arch/parisc/include/asm/mman.h +3 -2
@@ -2,6 +2,7 @@#ifndef __ASM_MMAN_H__#define __ASM_MMAN_H__ +#include <linux/fs.h> #include <uapi/asm/mman.h> /* PARISC cannot allow mdwe as it needs writable stacks */
@@ -11,7 +12,7 @@ static inline bool arch_memory_deny_write_exec_supported(void) }#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported -static inline unsigned long arch_calc_vm_flag_bits (unsigned long flags) +static inline unsigned long arch_calc_vm_flag_bits (struct file *file,unsigned long flags) {/* * The stack on parisc grows upwards, so if userspace requests memory
@@ -23,6 +24,6 @@ static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags) return 0; } -#define arch_calc_vm_flag_bits (flags) arch_calc_vm_flag_bits(flags) +#define arch_calc_vm_flag_bits (file, flags) arch_calc_vm_flag_bits(file, flags)#endif /* __ASM_MMAN_H__ */
include/linux/mman.h +4 -3
@@ -2,6 +2,7 @@#ifndef _LINUX_MMAN_H#define _LINUX_MMAN_H +#include <linux/fs.h> #include <linux/mm.h> #include <linux/percpu_counter.h>
@@ -94,7 +95,7 @@ static inline void vm_unacct_memory(long pages)#endif #ifndef arch_calc_vm_flag_bits -#define arch_calc_vm_flag_bits (flags) 0 +#define arch_calc_vm_flag_bits (file, flags) 0#endif #ifndef arch_validate_prot
@@ -151,13 +152,13 @@ calc_vm_prot_bits(unsigned long prot, unsigned long pkey)* Combine the mmap "flags" argument into "vm_flags" used internally. */ static inline unsigned long -calc_vm_flag_bits (unsigned long flags) +calc_vm_flag_bits (struct file *file,unsigned long flags) {return _calc_vm_trans (flags,MAP_GROWSDOWN ,VM_GROWSDOWN ) |_calc_vm_trans (flags,MAP_LOCKED ,VM_LOCKED ) |_calc_vm_trans (flags,MAP_SYNC ,VM_SYNC ) |_calc_vm_trans (flags,MAP_STACK ,VM_NOHUGEPAGE ) | -arch_calc_vm_flag_bits (flags); +arch_calc_vm_flag_bits (file, flags); }unsigned long vm_commit_limit (void );
mm/mmap.c +1 -1
@@ -344,7 +344,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,* to. we assume access permissions have been handled by the open * of the memory object, so we don't do any here. */ - vm_flags |=calc_vm_prot_bits (prot, pkey) |calc_vm_flag_bits (flags) | + vm_flags |=calc_vm_prot_bits (prot, pkey) |calc_vm_flag_bits (file, flags) | mm->def_flags |VM_MAYREAD |VM_MAYWRITE |VM_MAYEXEC ;/* Obtain the address to map to. we verify (or select) it and ensure
mm/nommu.c +1 -1
@@ -842,7 +842,7 @@ static unsigned long determine_vm_flags(struct file *file, {unsigned long vm_flags; - vm_flags =calc_vm_prot_bits (prot,0 ) |calc_vm_flag_bits (flags); + vm_flags =calc_vm_prot_bits (prot,0 ) |calc_vm_flag_bits (file, flags);if (!file) {/*
mm/shmem.c +0 -3
@@ -2733,9 +2733,6 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)if (ret)return ret; -/* arm64 - allow memory tagging on RAM-based files */ -vm_flags_set (vma,VM_MTE_ALLOWED ); -file_accessed (file);/* This is anonymous shared memory if it is unlinked at the time of mmap */ if (inode->i_nlink)