Skip to content

Commit 8fad7b0

Browse files
lorenzo-stoakesgregkh
authored andcommitted
mm: refactor arch_calc_vm_flag_bits() and arm64 MTE handling
[ Upstream commit 5baf8b037debf4ec60108ccfeccb8636d1dbad81 ] 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(). [[email protected]: fix whitespace, per Catalin] Link: https://lkml.kernel.org/r/ec251b20ba1964fb64cf1607d2ad80c47f3873df.1730224667.git.lorenzo.stoakes@oracle.com Fixes: deb0f65 ("mm/mmap: undo ->mmap() when arch_validate_flags() fails") Signed-off-by: Lorenzo Stoakes <[email protected]> Suggested-by: Catalin Marinas <[email protected]> Reported-by: Jann Horn <[email protected]> Reviewed-by: Catalin Marinas <[email protected]> Reviewed-by: Vlastimil Babka <[email protected]> Cc: Andreas Larsson <[email protected]> Cc: David S. Miller <[email protected]> Cc: Helge Deller <[email protected]> Cc: James E.J. Bottomley <[email protected]> Cc: Liam R. Howlett <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Mark Brown <[email protected]> Cc: Peter Xu <[email protected]> Cc: Will Deacon <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Lorenzo Stoakes <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 77b50f6 commit 8fad7b0

File tree

5 files changed

+13
-11
lines changed

5 files changed

+13
-11
lines changed

arch/arm64/include/asm/mman.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#define __ASM_MMAN_H__
44

55
#include <linux/compiler.h>
6+
#include <linux/fs.h>
7+
#include <linux/shmem_fs.h>
68
#include <linux/types.h>
79
#include <uapi/asm/mman.h>
810

@@ -21,19 +23,21 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
2123
}
2224
#define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey)
2325

24-
static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags)
26+
static inline unsigned long arch_calc_vm_flag_bits(struct file *file,
27+
unsigned long flags)
2528
{
2629
/*
2730
* Only allow MTE on anonymous mappings as these are guaranteed to be
2831
* backed by tags-capable memory. The vm_flags may be overridden by a
2932
* filesystem supporting MTE (RAM-based).
3033
*/
31-
if (system_supports_mte() && (flags & MAP_ANONYMOUS))
34+
if (system_supports_mte() &&
35+
((flags & MAP_ANONYMOUS) || shmem_file(file)))
3236
return VM_MTE_ALLOWED;
3337

3438
return 0;
3539
}
36-
#define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags)
40+
#define arch_calc_vm_flag_bits(file, flags) arch_calc_vm_flag_bits(file, flags)
3741

3842
static inline bool arch_validate_prot(unsigned long prot,
3943
unsigned long addr __always_unused)

include/linux/mman.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef _LINUX_MMAN_H
33
#define _LINUX_MMAN_H
44

5+
#include <linux/fs.h>
56
#include <linux/mm.h>
67
#include <linux/percpu_counter.h>
78

@@ -90,7 +91,7 @@ static inline void vm_unacct_memory(long pages)
9091
#endif
9192

9293
#ifndef arch_calc_vm_flag_bits
93-
#define arch_calc_vm_flag_bits(flags) 0
94+
#define arch_calc_vm_flag_bits(file, flags) 0
9495
#endif
9596

9697
#ifndef arch_validate_prot
@@ -147,12 +148,12 @@ calc_vm_prot_bits(unsigned long prot, unsigned long pkey)
147148
* Combine the mmap "flags" argument into "vm_flags" used internally.
148149
*/
149150
static inline unsigned long
150-
calc_vm_flag_bits(unsigned long flags)
151+
calc_vm_flag_bits(struct file *file, unsigned long flags)
151152
{
152153
return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
153154
_calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ) |
154155
_calc_vm_trans(flags, MAP_SYNC, VM_SYNC ) |
155-
arch_calc_vm_flag_bits(flags);
156+
arch_calc_vm_flag_bits(file, flags);
156157
}
157158

158159
unsigned long vm_commit_limit(void);

mm/mmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
13161316
* to. we assume access permissions have been handled by the open
13171317
* of the memory object, so we don't do any here.
13181318
*/
1319-
vm_flags = calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(flags) |
1319+
vm_flags = calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(file, flags) |
13201320
mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
13211321

13221322
if (flags & MAP_LOCKED)

mm/nommu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ static unsigned long determine_vm_flags(struct file *file,
903903
{
904904
unsigned long vm_flags;
905905

906-
vm_flags = calc_vm_prot_bits(prot, 0) | calc_vm_flag_bits(flags);
906+
vm_flags = calc_vm_prot_bits(prot, 0) | calc_vm_flag_bits(file, flags);
907907
/* vm_flags |= mm->def_flags; */
908908

909909
if (!(capabilities & NOMMU_MAP_DIRECT)) {

mm/shmem.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2306,9 +2306,6 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
23062306
if (ret)
23072307
return ret;
23082308

2309-
/* arm64 - allow memory tagging on RAM-based files */
2310-
vma->vm_flags |= VM_MTE_ALLOWED;
2311-
23122309
file_accessed(file);
23132310
vma->vm_ops = &shmem_vm_ops;
23142311
return 0;

0 commit comments

Comments
 (0)