18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __SPARC_MMAN_H__ 38c2ecf20Sopenharmony_ci#define __SPARC_MMAN_H__ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <uapi/asm/mman.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 88c2ecf20Sopenharmony_ci#define arch_mmap_check(addr,len,flags) sparc_mmap_check(addr,len) 98c2ecf20Sopenharmony_ciint sparc_mmap_check(unsigned long addr, unsigned long len); 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifdef CONFIG_SPARC64 128c2ecf20Sopenharmony_ci#include <asm/adi_64.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic inline void ipi_set_tstate_mcde(void *arg) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci struct mm_struct *mm = arg; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci /* Set TSTATE_MCDE for the task using address map that ADI has been 198c2ecf20Sopenharmony_ci * enabled on if the task is running. If not, it will be set 208c2ecf20Sopenharmony_ci * automatically at the next context switch 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_ci if (current->mm == mm) { 238c2ecf20Sopenharmony_ci struct pt_regs *regs; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci regs = task_pt_regs(current); 268c2ecf20Sopenharmony_ci regs->tstate |= TSTATE_MCDE; 278c2ecf20Sopenharmony_ci } 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define arch_calc_vm_prot_bits(prot, pkey) sparc_calc_vm_prot_bits(prot) 318c2ecf20Sopenharmony_cistatic inline unsigned long sparc_calc_vm_prot_bits(unsigned long prot) 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci if (adi_capable() && (prot & PROT_ADI)) { 348c2ecf20Sopenharmony_ci struct pt_regs *regs; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci if (!current->mm->context.adi) { 378c2ecf20Sopenharmony_ci regs = task_pt_regs(current); 388c2ecf20Sopenharmony_ci regs->tstate |= TSTATE_MCDE; 398c2ecf20Sopenharmony_ci current->mm->context.adi = true; 408c2ecf20Sopenharmony_ci on_each_cpu_mask(mm_cpumask(current->mm), 418c2ecf20Sopenharmony_ci ipi_set_tstate_mcde, current->mm, 0); 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci return VM_SPARC_ADI; 448c2ecf20Sopenharmony_ci } else { 458c2ecf20Sopenharmony_ci return 0; 468c2ecf20Sopenharmony_ci } 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define arch_vm_get_page_prot(vm_flags) sparc_vm_get_page_prot(vm_flags) 508c2ecf20Sopenharmony_cistatic inline pgprot_t sparc_vm_get_page_prot(unsigned long vm_flags) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci return (vm_flags & VM_SPARC_ADI) ? __pgprot(_PAGE_MCD_4V) : __pgprot(0); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define arch_validate_prot(prot, addr) sparc_validate_prot(prot, addr) 568c2ecf20Sopenharmony_cistatic inline int sparc_validate_prot(unsigned long prot, unsigned long addr) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_ADI)) 598c2ecf20Sopenharmony_ci return 0; 608c2ecf20Sopenharmony_ci return 1; 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci#define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags) 648c2ecf20Sopenharmony_ci/* arch_validate_flags() - Ensure combination of flags is valid for a 658c2ecf20Sopenharmony_ci * VMA. 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_cistatic inline bool arch_validate_flags(unsigned long vm_flags) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci /* If ADI is being enabled on this VMA, check for ADI 708c2ecf20Sopenharmony_ci * capability on the platform and ensure VMA is suitable 718c2ecf20Sopenharmony_ci * for ADI 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_ci if (vm_flags & VM_SPARC_ADI) { 748c2ecf20Sopenharmony_ci if (!adi_capable()) 758c2ecf20Sopenharmony_ci return false; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci /* ADI can not be enabled on PFN mapped pages */ 788c2ecf20Sopenharmony_ci if (vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) 798c2ecf20Sopenharmony_ci return false; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci /* Mergeable pages can become unmergeable 828c2ecf20Sopenharmony_ci * if ADI is enabled on them even if they 838c2ecf20Sopenharmony_ci * have identical data on them. This can be 848c2ecf20Sopenharmony_ci * because ADI enabled pages with identical 858c2ecf20Sopenharmony_ci * data may still not have identical ADI 868c2ecf20Sopenharmony_ci * tags on them. Disallow ADI on mergeable 878c2ecf20Sopenharmony_ci * pages. 888c2ecf20Sopenharmony_ci */ 898c2ecf20Sopenharmony_ci if (vm_flags & VM_MERGEABLE) 908c2ecf20Sopenharmony_ci return false; 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci return true; 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci#endif /* CONFIG_SPARC64 */ 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 978c2ecf20Sopenharmony_ci#endif /* __SPARC_MMAN_H__ */ 98