Some systems (e.g. io_uring) need to load/store capabilities on buffers shared with the userspace. Shared mappings don't have load/store capabilities permissions by default, so add two new VM flags that would allow to set up such mappings.
Note: this won't allow userspace to make arbitrary shared mappings with tag access as the flags are not exposed; the new VM flags are for internal use only.
Signed-off-by: Tudor Cretu tudor.cretu@arm.com --- Documentation/filesystems/proc.rst | 2 ++ arch/arm64/Kconfig | 1 + arch/arm64/include/asm/mman.h | 6 ++++++ fs/proc/task_mmu.c | 4 ++++ include/linux/mm.h | 8 ++++++++ 5 files changed, 21 insertions(+)
diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst index 061744c436d9..6d9b22ebf3e9 100644 --- a/Documentation/filesystems/proc.rst +++ b/Documentation/filesystems/proc.rst @@ -553,6 +553,8 @@ encoded manner. The codes are the following: mg mergable advise flag bt arm64 BTI guarded page mt arm64 MTE allocation tags are enabled + rc arm64 Morello capability tag reads are enabled + wc arm64 Morello capability tag writes are enabled um userfaultfd missing tracking uw userfaultfd wr-protect tracking == ======================================= diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index c784d8664a40..e8e6b0f21a91 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1971,6 +1971,7 @@ config ARM64_MORELLO depends on CC_HAS_MORELLO select ARCH_NO_SWAP select ARCH_HAS_CHERI_CAPABILITIES + select ARCH_USES_HIGH_VMA_FLAGS help The Morello architecture is an experimental extension to Armv8.2-A, which extends the AArch64 state with the principles proposed in diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h index e3e28f7daf62..eb0b862121a2 100644 --- a/arch/arm64/include/asm/mman.h +++ b/arch/arm64/include/asm/mman.h @@ -55,6 +55,12 @@ static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) if (vm_flags & VM_MTE) prot |= PTE_ATTRINDX(MT_NORMAL_TAGGED);
+ if (vm_flags & VM_READ_CAPS) + prot |= PTE_LOAD_CAPS; + + if (vm_flags & VM_WRITE_CAPS) + prot |= PTE_STORE_CAPS; + return __pgprot(prot); } #define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index f46060eb91b5..4f56772da016 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -697,6 +697,10 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR [ilog2(VM_UFFD_MINOR)] = "ui", #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */ +#ifdef CONFIG_ARM64_MORELLO + [ilog2(VM_READ_CAPS)] = "rc", + [ilog2(VM_WRITE_CAPS)] = "wc", +#endif }; size_t i;
diff --git a/include/linux/mm.h b/include/linux/mm.h index 9b7b730db4e9..b399d6ca1d83 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -357,6 +357,14 @@ extern unsigned int kobjsize(const void *objp); # define VM_MTE_ALLOWED VM_NONE #endif
+#ifdef CONFIG_ARM64_MORELLO +# define VM_READ_CAPS VM_HIGH_ARCH_2 /* Permit capability tag loads */ +# define VM_WRITE_CAPS VM_HIGH_ARCH_3 /* Permit capability tag stores */ +#else +# define VM_READ_CAPS VM_NONE +# define VM_WRITE_CAPS VM_NONE +#endif + #ifndef VM_GROWSUP # define VM_GROWSUP VM_NONE #endif