1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds #ifndef _LINUX_MMAN_H
31da177e4SLinus Torvalds #define _LINUX_MMAN_H
41da177e4SLinus Torvalds
55baf8b03SLorenzo Stoakes #include <linux/fs.h>
69cdcb566SDavid Woodhouse #include <linux/mm.h>
700a62ce9SKOSAKI Motohiro #include <linux/percpu_counter.h>
89cdcb566SDavid Woodhouse
960063497SArun Sharma #include <linux/atomic.h>
10607ca46eSDavid Howells #include <uapi/linux/mman.h>
119cdcb566SDavid Woodhouse
121c972597SDan Williams /*
131c972597SDan Williams * Arrange for legacy / undefined architecture specific flags to be
14b6fb293fSJan Kara * ignored by mmap handling code.
151c972597SDan Williams */
161c972597SDan Williams #ifndef MAP_32BIT
171c972597SDan Williams #define MAP_32BIT 0
181c972597SDan Williams #endif
1929f890d1SRick Edgecombe #ifndef MAP_ABOVE4G
2029f890d1SRick Edgecombe #define MAP_ABOVE4G 0
2129f890d1SRick Edgecombe #endif
221c972597SDan Williams #ifndef MAP_HUGE_2MB
231c972597SDan Williams #define MAP_HUGE_2MB 0
241c972597SDan Williams #endif
251c972597SDan Williams #ifndef MAP_HUGE_1GB
261c972597SDan Williams #define MAP_HUGE_1GB 0
271c972597SDan Williams #endif
281c972597SDan Williams #ifndef MAP_UNINITIALIZED
291c972597SDan Williams #define MAP_UNINITIALIZED 0
301c972597SDan Williams #endif
31b6fb293fSJan Kara #ifndef MAP_SYNC
32b6fb293fSJan Kara #define MAP_SYNC 0
33b6fb293fSJan Kara #endif
341c972597SDan Williams
351c972597SDan Williams /*
361c972597SDan Williams * The historical set of flags that all mmap implementations implicitly
371c972597SDan Williams * support when a ->mmap_validate() op is not provided in file_operations.
383b8db39fSDavid Hildenbrand *
396128b3afSDavid Hildenbrand * MAP_EXECUTABLE and MAP_DENYWRITE are completely ignored throughout the
406128b3afSDavid Hildenbrand * kernel.
411c972597SDan Williams */
421c972597SDan Williams #define LEGACY_MAP_MASK (MAP_SHARED \
431c972597SDan Williams | MAP_PRIVATE \
441c972597SDan Williams | MAP_FIXED \
451c972597SDan Williams | MAP_ANONYMOUS \
461c972597SDan Williams | MAP_DENYWRITE \
471c972597SDan Williams | MAP_EXECUTABLE \
481c972597SDan Williams | MAP_UNINITIALIZED \
491c972597SDan Williams | MAP_GROWSDOWN \
501c972597SDan Williams | MAP_LOCKED \
511c972597SDan Williams | MAP_NORESERVE \
521c972597SDan Williams | MAP_POPULATE \
531c972597SDan Williams | MAP_NONBLOCK \
541c972597SDan Williams | MAP_STACK \
551c972597SDan Williams | MAP_HUGETLB \
561c972597SDan Williams | MAP_32BIT \
5729f890d1SRick Edgecombe | MAP_ABOVE4G \
581c972597SDan Williams | MAP_HUGE_2MB \
591c972597SDan Williams | MAP_HUGE_1GB)
601c972597SDan Williams
611da177e4SLinus Torvalds extern int sysctl_overcommit_memory;
6200a62ce9SKOSAKI Motohiro extern struct percpu_counter vm_committed_as;
631da177e4SLinus Torvalds
64917d9290STim Chen #ifdef CONFIG_SMP
65917d9290STim Chen extern s32 vm_committed_as_batch;
6656f3547bSFeng Tang extern void mm_compute_batch(int overcommit_policy);
67917d9290STim Chen #else
68917d9290STim Chen #define vm_committed_as_batch 0
mm_compute_batch(int overcommit_policy)6956f3547bSFeng Tang static inline void mm_compute_batch(int overcommit_policy)
7056f3547bSFeng Tang {
7156f3547bSFeng Tang }
72917d9290STim Chen #endif
73917d9290STim Chen
74997071bcSK. Y. Srinivasan unsigned long vm_memory_committed(void);
75997071bcSK. Y. Srinivasan
vm_acct_memory(long pages)761da177e4SLinus Torvalds static inline void vm_acct_memory(long pages)
771da177e4SLinus Torvalds {
78104b4e51SNikolay Borisov percpu_counter_add_batch(&vm_committed_as, pages, vm_committed_as_batch);
791da177e4SLinus Torvalds }
801da177e4SLinus Torvalds
vm_unacct_memory(long pages)811da177e4SLinus Torvalds static inline void vm_unacct_memory(long pages)
821da177e4SLinus Torvalds {
831da177e4SLinus Torvalds vm_acct_memory(-pages);
841da177e4SLinus Torvalds }
851da177e4SLinus Torvalds
861da177e4SLinus Torvalds /*
87b3fbbea4SKevin Brodsky * Allow architectures to handle additional protection and flag bits. The
88b3fbbea4SKevin Brodsky * overriding macros must be defined in the arch-specific asm/mman.h file.
89b845f313SDave Kleikamp */
90b845f313SDave Kleikamp
91b845f313SDave Kleikamp #ifndef arch_calc_vm_prot_bits
92e6bfb709SDave Hansen #define arch_calc_vm_prot_bits(prot, pkey) 0
93b845f313SDave Kleikamp #endif
94b845f313SDave Kleikamp
95b3fbbea4SKevin Brodsky #ifndef arch_calc_vm_flag_bits
965baf8b03SLorenzo Stoakes #define arch_calc_vm_flag_bits(file, flags) 0
97b3fbbea4SKevin Brodsky #endif
98b3fbbea4SKevin Brodsky
99b845f313SDave Kleikamp #ifndef arch_validate_prot
100b845f313SDave Kleikamp /*
101b845f313SDave Kleikamp * This is called from mprotect(). PROT_GROWSDOWN and PROT_GROWSUP have
102b845f313SDave Kleikamp * already been masked out.
103b845f313SDave Kleikamp *
104b845f313SDave Kleikamp * Returns true if the prot flags are valid
105b845f313SDave Kleikamp */
arch_validate_prot(unsigned long prot,unsigned long addr)1069035cf9aSKhalid Aziz static inline bool arch_validate_prot(unsigned long prot, unsigned long addr)
107b845f313SDave Kleikamp {
108b845f313SDave Kleikamp return (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM)) == 0;
109b845f313SDave Kleikamp }
110b845f313SDave Kleikamp #define arch_validate_prot arch_validate_prot
111b845f313SDave Kleikamp #endif
112b845f313SDave Kleikamp
113c462ac28SCatalin Marinas #ifndef arch_validate_flags
114c462ac28SCatalin Marinas /*
115c462ac28SCatalin Marinas * This is called from mmap() and mprotect() with the updated vma->vm_flags.
116c462ac28SCatalin Marinas *
117c462ac28SCatalin Marinas * Returns true if the VM_* flags are valid.
118c462ac28SCatalin Marinas */
arch_validate_flags(unsigned long flags)119c462ac28SCatalin Marinas static inline bool arch_validate_flags(unsigned long flags)
120c462ac28SCatalin Marinas {
121c462ac28SCatalin Marinas return true;
122c462ac28SCatalin Marinas }
123c462ac28SCatalin Marinas #define arch_validate_flags arch_validate_flags
124c462ac28SCatalin Marinas #endif
125c462ac28SCatalin Marinas
126b845f313SDave Kleikamp /*
1271da177e4SLinus Torvalds * Optimisation macro. It is equivalent to:
1281da177e4SLinus Torvalds * (x & bit1) ? bit2 : 0
1291da177e4SLinus Torvalds * but this version is faster.
1301da177e4SLinus Torvalds * ("bit1" and "bit2" must be single bits)
1311da177e4SLinus Torvalds */
1321da177e4SLinus Torvalds #define _calc_vm_trans(x, bit1, bit2) \
133592e2545SJan Kara ((!(bit1) || !(bit2)) ? 0 : \
1341da177e4SLinus Torvalds ((bit1) <= (bit2) ? ((x) & (bit1)) * ((bit2) / (bit1)) \
135592e2545SJan Kara : ((x) & (bit1)) / ((bit1) / (bit2))))
1361da177e4SLinus Torvalds
1371da177e4SLinus Torvalds /*
1381da177e4SLinus Torvalds * Combine the mmap "prot" argument into "vm_flags" used internally.
1391da177e4SLinus Torvalds */
1401da177e4SLinus Torvalds static inline unsigned long
calc_vm_prot_bits(unsigned long prot,unsigned long pkey)141e6bfb709SDave Hansen calc_vm_prot_bits(unsigned long prot, unsigned long pkey)
1421da177e4SLinus Torvalds {
1431da177e4SLinus Torvalds return _calc_vm_trans(prot, PROT_READ, VM_READ ) |
1441da177e4SLinus Torvalds _calc_vm_trans(prot, PROT_WRITE, VM_WRITE) |
145b845f313SDave Kleikamp _calc_vm_trans(prot, PROT_EXEC, VM_EXEC) |
146e6bfb709SDave Hansen arch_calc_vm_prot_bits(prot, pkey);
1471da177e4SLinus Torvalds }
1481da177e4SLinus Torvalds
1491da177e4SLinus Torvalds /*
1501da177e4SLinus Torvalds * Combine the mmap "flags" argument into "vm_flags" used internally.
1511da177e4SLinus Torvalds */
1521da177e4SLinus Torvalds static inline unsigned long
calc_vm_flag_bits(struct file * file,unsigned long flags)1535baf8b03SLorenzo Stoakes calc_vm_flag_bits(struct file *file, unsigned long flags)
1541da177e4SLinus Torvalds {
1551da177e4SLinus Torvalds return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
156b6fb293fSJan Kara _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ) |
157b3fbbea4SKevin Brodsky _calc_vm_trans(flags, MAP_SYNC, VM_SYNC ) |
158*7190b3c8SIgnacio Moreno Gonzalez #ifdef CONFIG_TRANSPARENT_HUGEPAGE
159c4608d1bSYang Shi _calc_vm_trans(flags, MAP_STACK, VM_NOHUGEPAGE) |
160*7190b3c8SIgnacio Moreno Gonzalez #endif
1615baf8b03SLorenzo Stoakes arch_calc_vm_flag_bits(file, flags);
1621da177e4SLinus Torvalds }
16300619bccSJerome Marchand
16400619bccSJerome Marchand unsigned long vm_commit_limit(void);
165b507808eSJoey Gouly
166d5aad4c2SZev Weiss #ifndef arch_memory_deny_write_exec_supported
arch_memory_deny_write_exec_supported(void)167d5aad4c2SZev Weiss static inline bool arch_memory_deny_write_exec_supported(void)
168d5aad4c2SZev Weiss {
169d5aad4c2SZev Weiss return true;
170d5aad4c2SZev Weiss }
171d5aad4c2SZev Weiss #define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
172d5aad4c2SZev Weiss #endif
173d5aad4c2SZev Weiss
174b507808eSJoey Gouly /*
175b507808eSJoey Gouly * Denies creating a writable executable mapping or gaining executable permissions.
176b507808eSJoey Gouly *
177b507808eSJoey Gouly * This denies the following:
178b507808eSJoey Gouly *
179b507808eSJoey Gouly * a) mmap(PROT_WRITE | PROT_EXEC)
180b507808eSJoey Gouly *
181b507808eSJoey Gouly * b) mmap(PROT_WRITE)
182b507808eSJoey Gouly * mprotect(PROT_EXEC)
183b507808eSJoey Gouly *
184b507808eSJoey Gouly * c) mmap(PROT_WRITE)
185b507808eSJoey Gouly * mprotect(PROT_READ)
186b507808eSJoey Gouly * mprotect(PROT_EXEC)
187b507808eSJoey Gouly *
188b507808eSJoey Gouly * But allows the following:
189b507808eSJoey Gouly *
190b507808eSJoey Gouly * d) mmap(PROT_READ | PROT_EXEC)
191b507808eSJoey Gouly * mmap(PROT_READ | PROT_EXEC | PROT_BTI)
1920fb4a7adSLorenzo Stoakes *
1930fb4a7adSLorenzo Stoakes * This is only applicable if the user has set the Memory-Deny-Write-Execute
1940fb4a7adSLorenzo Stoakes * (MDWE) protection mask for the current process.
1950fb4a7adSLorenzo Stoakes *
1960fb4a7adSLorenzo Stoakes * @old specifies the VMA flags the VMA originally possessed, and @new the ones
1970fb4a7adSLorenzo Stoakes * we propose to set.
1980fb4a7adSLorenzo Stoakes *
1990fb4a7adSLorenzo Stoakes * Return: false if proposed change is OK, true if not ok and should be denied.
200b507808eSJoey Gouly */
map_deny_write_exec(unsigned long old,unsigned long new)2010fb4a7adSLorenzo Stoakes static inline bool map_deny_write_exec(unsigned long old, unsigned long new)
202b507808eSJoey Gouly {
2030fb4a7adSLorenzo Stoakes /* If MDWE is disabled, we have nothing to deny. */
204b507808eSJoey Gouly if (!test_bit(MMF_HAS_MDWE, ¤t->mm->flags))
205b507808eSJoey Gouly return false;
206b507808eSJoey Gouly
2070fb4a7adSLorenzo Stoakes /* If the new VMA is not executable, we have nothing to deny. */
2080fb4a7adSLorenzo Stoakes if (!(new & VM_EXEC))
2090fb4a7adSLorenzo Stoakes return false;
2100fb4a7adSLorenzo Stoakes
2110fb4a7adSLorenzo Stoakes /* Under MDWE we do not accept newly writably executable VMAs... */
2120fb4a7adSLorenzo Stoakes if (new & VM_WRITE)
213b507808eSJoey Gouly return true;
214b507808eSJoey Gouly
2150fb4a7adSLorenzo Stoakes /* ...nor previously non-executable VMAs becoming executable. */
2160fb4a7adSLorenzo Stoakes if (!(old & VM_EXEC))
217b507808eSJoey Gouly return true;
218b507808eSJoey Gouly
219b507808eSJoey Gouly return false;
220b507808eSJoey Gouly }
221b507808eSJoey Gouly
2221da177e4SLinus Torvalds #endif /* _LINUX_MMAN_H */
223