Correctly account for MTE on mmap_region(). We need to check this ahead of the operation, the shmem mmap hook was doing it, but this is at a point where a failure would mean we'd have to tear down a partially installed VMA. Avoid all this by adding a function to specifically handle this case. Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@xxxxxxxxxx> --- mm/mmap.c | 20 ++++++++++++++++++++ mm/shmem.c | 3 --- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 8462de1ee583..83afa1ebfd75 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1575,6 +1575,24 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr, return error; } +/* + * We check VMA flag validity early in the mmap() process, however this can + * cause issues for arm64 when using MTE, which requires that it be used with + * shmem and in this instance and only then is VM_MTE_ALLOWED set permitting + * this operation. + * + * To avoid having to tear down a partially complete mapping we do this ahead of + * time. + */ +static vm_flags_t arch_adjust_flags(struct file *file, vm_flags_t vm_flags) +{ + if (!IS_ENABLED(CONFIG_ARM64)) + return vm_flags; + + if (shmem_file(file)) + return vm_flags | VM_MTE_ALLOWED; +} + unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, vm_flags_t vm_flags, unsigned long pgoff, struct list_head *uf) @@ -1586,6 +1604,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, if (map_deny_write_exec(vm_flags, vm_flags)) return -EACCES; + vm_flags = arch_adjust_flags(file, vm_flags); + /* Allow architectures to sanity-check the vm_flags. */ if (!arch_validate_flags(vm_flags)) return -EINVAL; diff --git a/mm/shmem.c b/mm/shmem.c index 4ba1d00fabda..e87f5d6799a7 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -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) --