18ef8f360SDave Martin /* SPDX-License-Identifier: GPL-2.0 */ 28ef8f360SDave Martin #ifndef __ASM_MMAN_H__ 38ef8f360SDave Martin #define __ASM_MMAN_H__ 48ef8f360SDave Martin 58ef8f360SDave Martin #include <linux/compiler.h> 68ef8f360SDave Martin #include <linux/types.h> 78ef8f360SDave Martin #include <uapi/asm/mman.h> 88ef8f360SDave Martin 98ef8f360SDave Martin static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, 108ef8f360SDave Martin unsigned long pkey __always_unused) 118ef8f360SDave Martin { 129f341931SCatalin Marinas unsigned long ret = 0; 138ef8f360SDave Martin 149f341931SCatalin Marinas if (system_supports_bti() && (prot & PROT_BTI)) 159f341931SCatalin Marinas ret |= VM_ARM64_BTI; 169f341931SCatalin Marinas 179f341931SCatalin Marinas if (system_supports_mte() && (prot & PROT_MTE)) 189f341931SCatalin Marinas ret |= VM_MTE; 199f341931SCatalin Marinas 209f341931SCatalin Marinas return ret; 218ef8f360SDave Martin } 228ef8f360SDave Martin #define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey) 238ef8f360SDave Martin 249f341931SCatalin Marinas static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags) 259f341931SCatalin Marinas { 269f341931SCatalin Marinas /* 279f341931SCatalin Marinas * Only allow MTE on anonymous mappings as these are guaranteed to be 289f341931SCatalin Marinas * backed by tags-capable memory. The vm_flags may be overridden by a 299f341931SCatalin Marinas * filesystem supporting MTE (RAM-based). 309f341931SCatalin Marinas */ 319f341931SCatalin Marinas if (system_supports_mte() && (flags & MAP_ANONYMOUS)) 329f341931SCatalin Marinas return VM_MTE_ALLOWED; 339f341931SCatalin Marinas 349f341931SCatalin Marinas return 0; 359f341931SCatalin Marinas } 369f341931SCatalin Marinas #define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags) 379f341931SCatalin Marinas 388ef8f360SDave Martin static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) 398ef8f360SDave Martin { 409f341931SCatalin Marinas pteval_t prot = 0; 419f341931SCatalin Marinas 429f341931SCatalin Marinas if (vm_flags & VM_ARM64_BTI) 439f341931SCatalin Marinas prot |= PTE_GP; 449f341931SCatalin Marinas 459f341931SCatalin Marinas /* 469f341931SCatalin Marinas * There are two conditions required for returning a Normal Tagged 479f341931SCatalin Marinas * memory type: (1) the user requested it via PROT_MTE passed to 489f341931SCatalin Marinas * mmap() or mprotect() and (2) the corresponding vma supports MTE. We 499f341931SCatalin Marinas * register (1) as VM_MTE in the vma->vm_flags and (2) as 509f341931SCatalin Marinas * VM_MTE_ALLOWED. Note that the latter can only be set during the 519f341931SCatalin Marinas * mmap() call since mprotect() does not accept MAP_* flags. 52*00420905SCatalin Marinas * Checking for VM_MTE only is sufficient since arch_validate_flags() 53*00420905SCatalin Marinas * does not permit (VM_MTE & !VM_MTE_ALLOWED). 549f341931SCatalin Marinas */ 55*00420905SCatalin Marinas if (vm_flags & VM_MTE) 569f341931SCatalin Marinas prot |= PTE_ATTRINDX(MT_NORMAL_TAGGED); 579f341931SCatalin Marinas 589f341931SCatalin Marinas return __pgprot(prot); 598ef8f360SDave Martin } 608ef8f360SDave Martin #define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) 618ef8f360SDave Martin 628ef8f360SDave Martin static inline bool arch_validate_prot(unsigned long prot, 638ef8f360SDave Martin unsigned long addr __always_unused) 648ef8f360SDave Martin { 658ef8f360SDave Martin unsigned long supported = PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM; 668ef8f360SDave Martin 678ef8f360SDave Martin if (system_supports_bti()) 688ef8f360SDave Martin supported |= PROT_BTI; 698ef8f360SDave Martin 709f341931SCatalin Marinas if (system_supports_mte()) 719f341931SCatalin Marinas supported |= PROT_MTE; 729f341931SCatalin Marinas 738ef8f360SDave Martin return (prot & ~supported) == 0; 748ef8f360SDave Martin } 758ef8f360SDave Martin #define arch_validate_prot(prot, addr) arch_validate_prot(prot, addr) 768ef8f360SDave Martin 77*00420905SCatalin Marinas static inline bool arch_validate_flags(unsigned long vm_flags) 78*00420905SCatalin Marinas { 79*00420905SCatalin Marinas if (!system_supports_mte()) 80*00420905SCatalin Marinas return true; 81*00420905SCatalin Marinas 82*00420905SCatalin Marinas /* only allow VM_MTE if VM_MTE_ALLOWED has been set previously */ 83*00420905SCatalin Marinas return !(vm_flags & VM_MTE) || (vm_flags & VM_MTE_ALLOWED); 84*00420905SCatalin Marinas } 85*00420905SCatalin Marinas #define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags) 86*00420905SCatalin Marinas 878ef8f360SDave Martin #endif /* ! __ASM_MMAN_H__ */ 88