xref: /OK3568_Linux_fs/kernel/arch/sparc/include/asm/mman.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef __SPARC_MMAN_H__
3*4882a593Smuzhiyun #define __SPARC_MMAN_H__
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <uapi/asm/mman.h>
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifndef __ASSEMBLY__
8*4882a593Smuzhiyun #define arch_mmap_check(addr,len,flags)	sparc_mmap_check(addr,len)
9*4882a593Smuzhiyun int sparc_mmap_check(unsigned long addr, unsigned long len);
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #ifdef CONFIG_SPARC64
12*4882a593Smuzhiyun #include <asm/adi_64.h>
13*4882a593Smuzhiyun 
ipi_set_tstate_mcde(void * arg)14*4882a593Smuzhiyun static inline void ipi_set_tstate_mcde(void *arg)
15*4882a593Smuzhiyun {
16*4882a593Smuzhiyun 	struct mm_struct *mm = arg;
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun 	/* Set TSTATE_MCDE for the task using address map that ADI has been
19*4882a593Smuzhiyun 	 * enabled on if the task is running. If not, it will be set
20*4882a593Smuzhiyun 	 * automatically at the next context switch
21*4882a593Smuzhiyun 	 */
22*4882a593Smuzhiyun 	if (current->mm == mm) {
23*4882a593Smuzhiyun 		struct pt_regs *regs;
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 		regs = task_pt_regs(current);
26*4882a593Smuzhiyun 		regs->tstate |= TSTATE_MCDE;
27*4882a593Smuzhiyun 	}
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define arch_calc_vm_prot_bits(prot, pkey) sparc_calc_vm_prot_bits(prot)
sparc_calc_vm_prot_bits(unsigned long prot)31*4882a593Smuzhiyun static inline unsigned long sparc_calc_vm_prot_bits(unsigned long prot)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun 	if (adi_capable() && (prot & PROT_ADI)) {
34*4882a593Smuzhiyun 		struct pt_regs *regs;
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 		if (!current->mm->context.adi) {
37*4882a593Smuzhiyun 			regs = task_pt_regs(current);
38*4882a593Smuzhiyun 			regs->tstate |= TSTATE_MCDE;
39*4882a593Smuzhiyun 			current->mm->context.adi = true;
40*4882a593Smuzhiyun 			on_each_cpu_mask(mm_cpumask(current->mm),
41*4882a593Smuzhiyun 					 ipi_set_tstate_mcde, current->mm, 0);
42*4882a593Smuzhiyun 		}
43*4882a593Smuzhiyun 		return VM_SPARC_ADI;
44*4882a593Smuzhiyun 	} else {
45*4882a593Smuzhiyun 		return 0;
46*4882a593Smuzhiyun 	}
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define arch_vm_get_page_prot(vm_flags) sparc_vm_get_page_prot(vm_flags)
sparc_vm_get_page_prot(unsigned long vm_flags)50*4882a593Smuzhiyun static inline pgprot_t sparc_vm_get_page_prot(unsigned long vm_flags)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	return (vm_flags & VM_SPARC_ADI) ? __pgprot(_PAGE_MCD_4V) : __pgprot(0);
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #define arch_validate_prot(prot, addr) sparc_validate_prot(prot, addr)
sparc_validate_prot(unsigned long prot,unsigned long addr)56*4882a593Smuzhiyun static inline int sparc_validate_prot(unsigned long prot, unsigned long addr)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun 	if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_ADI))
59*4882a593Smuzhiyun 		return 0;
60*4882a593Smuzhiyun 	return 1;
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun #define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags)
64*4882a593Smuzhiyun /* arch_validate_flags() - Ensure combination of flags is valid for a
65*4882a593Smuzhiyun  *	VMA.
66*4882a593Smuzhiyun  */
arch_validate_flags(unsigned long vm_flags)67*4882a593Smuzhiyun static inline bool arch_validate_flags(unsigned long vm_flags)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun 	/* If ADI is being enabled on this VMA, check for ADI
70*4882a593Smuzhiyun 	 * capability on the platform and ensure VMA is suitable
71*4882a593Smuzhiyun 	 * for ADI
72*4882a593Smuzhiyun 	 */
73*4882a593Smuzhiyun 	if (vm_flags & VM_SPARC_ADI) {
74*4882a593Smuzhiyun 		if (!adi_capable())
75*4882a593Smuzhiyun 			return false;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 		/* ADI can not be enabled on PFN mapped pages */
78*4882a593Smuzhiyun 		if (vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
79*4882a593Smuzhiyun 			return false;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 		/* Mergeable pages can become unmergeable
82*4882a593Smuzhiyun 		 * if ADI is enabled on them even if they
83*4882a593Smuzhiyun 		 * have identical data on them. This can be
84*4882a593Smuzhiyun 		 * because ADI enabled pages with identical
85*4882a593Smuzhiyun 		 * data may still not have identical ADI
86*4882a593Smuzhiyun 		 * tags on them. Disallow ADI on mergeable
87*4882a593Smuzhiyun 		 * pages.
88*4882a593Smuzhiyun 		 */
89*4882a593Smuzhiyun 		if (vm_flags & VM_MERGEABLE)
90*4882a593Smuzhiyun 			return false;
91*4882a593Smuzhiyun 	}
92*4882a593Smuzhiyun 	return true;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun #endif /* CONFIG_SPARC64 */
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun #endif /* __ASSEMBLY__ */
97*4882a593Smuzhiyun #endif /* __SPARC_MMAN_H__ */
98