18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __ASM_MMAN_H__ 38c2ecf20Sopenharmony_ci#define __ASM_MMAN_H__ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/compiler.h> 68c2ecf20Sopenharmony_ci#include <linux/types.h> 78c2ecf20Sopenharmony_ci#include <uapi/asm/mman.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistatic inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, 108c2ecf20Sopenharmony_ci unsigned long pkey __always_unused) 118c2ecf20Sopenharmony_ci{ 128c2ecf20Sopenharmony_ci unsigned long ret = 0; 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci if (system_supports_bti() && (prot & PROT_BTI)) 158c2ecf20Sopenharmony_ci ret |= VM_ARM64_BTI; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci if (system_supports_mte() && (prot & PROT_MTE)) 188c2ecf20Sopenharmony_ci ret |= VM_MTE; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci return ret; 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci#define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic inline unsigned long arch_calc_vm_flag_bits(unsigned long flags) 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci /* 278c2ecf20Sopenharmony_ci * Only allow MTE on anonymous mappings as these are guaranteed to be 288c2ecf20Sopenharmony_ci * backed by tags-capable memory. The vm_flags may be overridden by a 298c2ecf20Sopenharmony_ci * filesystem supporting MTE (RAM-based). 308c2ecf20Sopenharmony_ci */ 318c2ecf20Sopenharmony_ci if (system_supports_mte() && (flags & MAP_ANONYMOUS)) 328c2ecf20Sopenharmony_ci return VM_MTE_ALLOWED; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci return 0; 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci#define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags) 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci pteval_t prot = 0; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci if (vm_flags & VM_ARM64_BTI) 438c2ecf20Sopenharmony_ci prot |= PTE_GP; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci /* 468c2ecf20Sopenharmony_ci * There are two conditions required for returning a Normal Tagged 478c2ecf20Sopenharmony_ci * memory type: (1) the user requested it via PROT_MTE passed to 488c2ecf20Sopenharmony_ci * mmap() or mprotect() and (2) the corresponding vma supports MTE. We 498c2ecf20Sopenharmony_ci * register (1) as VM_MTE in the vma->vm_flags and (2) as 508c2ecf20Sopenharmony_ci * VM_MTE_ALLOWED. Note that the latter can only be set during the 518c2ecf20Sopenharmony_ci * mmap() call since mprotect() does not accept MAP_* flags. 528c2ecf20Sopenharmony_ci * Checking for VM_MTE only is sufficient since arch_validate_flags() 538c2ecf20Sopenharmony_ci * does not permit (VM_MTE & !VM_MTE_ALLOWED). 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_ci if (vm_flags & VM_MTE) 568c2ecf20Sopenharmony_ci prot |= PTE_ATTRINDX(MT_NORMAL_TAGGED); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci return __pgprot(prot); 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci#define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags) 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistatic inline bool arch_validate_prot(unsigned long prot, 638c2ecf20Sopenharmony_ci unsigned long addr __always_unused) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci unsigned long supported = PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci if (system_supports_bti()) 688c2ecf20Sopenharmony_ci supported |= PROT_BTI; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci if (system_supports_mte()) 718c2ecf20Sopenharmony_ci supported |= PROT_MTE; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci return (prot & ~supported) == 0; 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci#define arch_validate_prot(prot, addr) arch_validate_prot(prot, addr) 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic inline bool arch_validate_flags(unsigned long vm_flags) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci if (!system_supports_mte()) 808c2ecf20Sopenharmony_ci return true; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci /* only allow VM_MTE if VM_MTE_ALLOWED has been set previously */ 838c2ecf20Sopenharmony_ci return !(vm_flags & VM_MTE) || (vm_flags & VM_MTE_ALLOWED); 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci#define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags) 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#endif /* ! __ASM_MMAN_H__ */ 88