Re: [PATCH 6.1.y] mm: refactor arch_calc_vm_flag_bits() and arm64 MTE handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Nov 14, 2024 at 06:07:41PM +0000, Lorenzo Stoakes wrote:
> 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().

For avoidance of doubt, NACK this and rest of 6.1.y series, I'll resend.

>
> [akpm@xxxxxxxxxxxxxxxxxxxx: fix whitespace, per Catalin]
> Link: https://lkml.kernel.org/r/ec251b20ba1964fb64cf1607d2ad80c47f3873df.1730224667.git.lorenzo.stoakes@xxxxxxxxxx
> Fixes: deb0f6562884 ("mm/mmap: undo ->mmap() when arch_validate_flags() fails")
> Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@xxxxxxxxxx>
> Suggested-by: Catalin Marinas <catalin.marinas@xxxxxxx>
> Reported-by: Jann Horn <jannh@xxxxxxxxxx>
> Reviewed-by: Catalin Marinas <catalin.marinas@xxxxxxx>
> Reviewed-by: Vlastimil Babka <vbabka@xxxxxxx>
> Cc: Andreas Larsson <andreas@xxxxxxxxxxx>
> Cc: David S. Miller <davem@xxxxxxxxxxxxx>
> Cc: Helge Deller <deller@xxxxxx>
> Cc: James E.J. Bottomley <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx>
> Cc: Liam R. Howlett <Liam.Howlett@xxxxxxxxxx>
> Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
> Cc: Mark Brown <broonie@xxxxxxxxxx>
> Cc: Peter Xu <peterx@xxxxxxxxxx>
> Cc: Will Deacon <will@xxxxxxxxxx>
> Cc: <stable@xxxxxxxxxxxxxxx>
> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> (cherry picked from commit 5baf8b037debf4ec60108ccfeccb8636d1dbad81)
> ---
>  arch/arm64/include/asm/mman.h | 10 +++++++---
>  include/linux/mman.h          |  7 ++++---
>  mm/mmap.c                     |  2 +-
>  mm/nommu.c                    |  2 +-
>  mm/shmem.c                    |  3 ---
>  5 files changed, 13 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h
> index 5966ee4a6154..ef35c52aabd6 100644
> --- a/arch/arm64/include/asm/mman.h
> +++ b/arch/arm64/include/asm/mman.h
> @@ -3,6 +3,8 @@
>  #define __ASM_MMAN_H__
>
>  #include <linux/compiler.h>
> +#include <linux/fs.h>
> +#include <linux/shmem_fs.h>
>  #include <linux/types.h>
>  #include <uapi/asm/mman.h>
>
> @@ -21,19 +23,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)
> diff --git a/include/linux/mman.h b/include/linux/mman.h
> index 58b3abd457a3..21ea08b919d9 100644
> --- a/include/linux/mman.h
> +++ b/include/linux/mman.h
> @@ -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>
>
> @@ -90,7 +91,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
> @@ -147,12 +148,12 @@ 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      ) |
> -	       arch_calc_vm_flag_bits(flags);
> +	       arch_calc_vm_flag_bits(file, flags);
>  }
>
>  unsigned long vm_commit_limit(void);
> diff --git a/mm/mmap.c b/mm/mmap.c
> index 4bfec4df51c2..322677f61d30 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -1316,7 +1316,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;
>
>  	if (flags & MAP_LOCKED)
> diff --git a/mm/nommu.c b/mm/nommu.c
> index e0428fa57526..859ba6bdeb9c 100644
> --- a/mm/nommu.c
> +++ b/mm/nommu.c
> @@ -903,7 +903,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);
>  	/* vm_flags |= mm->def_flags; */
>
>  	if (!(capabilities & NOMMU_MAP_DIRECT)) {
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 0e1fbc53717d..d1a33f66cc7f 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -2308,9 +2308,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 */
> -	vma->vm_flags |= VM_MTE_ALLOWED;
> -
>  	file_accessed(file);
>  	vma->vm_ops = &shmem_vm_ops;
>  	return 0;
> --
> 2.47.0
>




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux