Skip to content

Commit

Permalink
mm/vma: introduce VM_ACCESS_FLAGS
Browse files Browse the repository at this point in the history
There are many places where all basic VMA access flags (read, write,
exec) are initialized or checked against as a group.  One such example
is during page fault.  Existing vma_is_accessible() wrapper already
creates the notion of VMA accessibility as a group access permissions.

Hence lets just create VM_ACCESS_FLAGS (VM_READ|VM_WRITE|VM_EXEC) which
will not only reduce code duplication but also extend the VMA
accessibility concept in general.

Signed-off-by: Anshuman Khandual <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Reviewed-by: Vlastimil Babka <[email protected]>
Cc: Russell King <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Mark Salter <[email protected]>
Cc: Nick Hu <[email protected]>
Cc: Ley Foon Tan <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Yoshinori Sato <[email protected]>
Cc: Guan Xuetao <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Rob Springer <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Anshuman Khandual authored and torvalds committed Apr 10, 2020
1 parent c62da0c commit 6cb4d9a
Show file tree
Hide file tree
Showing 11 changed files with 16 additions and 12 deletions.
2 changes: 1 addition & 1 deletion arch/arm/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
*/
static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
{
unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
unsigned int mask = VM_ACCESS_FLAGS;

if ((fsr & FSR_WRITE) && !(fsr & FSR_CM))
mask = VM_WRITE;
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
const struct fault_info *inf;
struct mm_struct *mm = current->mm;
vm_fault_t fault, major = 0;
unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC;
unsigned long vm_flags = VM_ACCESS_FLAGS;
unsigned int mm_flags = FAULT_FLAG_DEFAULT;

if (kprobe_page_fault(regs, esr))
Expand Down
2 changes: 1 addition & 1 deletion arch/nds32/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
struct vm_area_struct *vma;
int si_code;
vm_fault_t fault;
unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
unsigned int mask = VM_ACCESS_FLAGS;
unsigned int flags = FAULT_FLAG_DEFAULT;

error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE);
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/mm/book3s64/pkeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ int __execute_only_pkey(struct mm_struct *mm)
static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma)
{
/* Do this check first since the vm_flags should be hot */
if ((vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) != VM_EXEC)
if ((vma->vm_flags & VM_ACCESS_FLAGS) != VM_EXEC)
return false;

return (vma_pkey(vma) == vma->vm_mm->context.execute_only_pkey);
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ void do_dat_exception(struct pt_regs *regs)
int access;
vm_fault_t fault;

access = VM_READ | VM_EXEC | VM_WRITE;
access = VM_ACCESS_FLAGS;
fault = do_exception(regs, access);
if (unlikely(fault))
do_fault_error(regs, access, fault);
Expand Down
2 changes: 1 addition & 1 deletion arch/unicore32/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
*/
static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
{
unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
unsigned int mask = VM_ACCESS_FLAGS;

if (!(fsr ^ 0x12)) /* write? */
mask = VM_WRITE;
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/mm/pkeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ int __execute_only_pkey(struct mm_struct *mm)
static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma)
{
/* Do this check first since the vm_flags should be hot */
if ((vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) != VM_EXEC)
if ((vma->vm_flags & VM_ACCESS_FLAGS) != VM_EXEC)
return false;
if (vma_pkey(vma) != vma->vm_mm->context.execute_only_pkey)
return false;
Expand Down
2 changes: 1 addition & 1 deletion drivers/staging/gasket/gasket_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ static bool gasket_mmap_has_permissions(struct gasket_dev *gasket_dev,

/* Make sure that no wrong flags are set. */
requested_permissions =
(vma->vm_flags & (VM_WRITE | VM_READ | VM_EXEC));
(vma->vm_flags & VM_ACCESS_FLAGS);
if (requested_permissions & ~(bar_permissions)) {
dev_dbg(gasket_dev->dev,
"Attempting to map a region with requested permissions 0x%x, but region has permissions 0x%x.\n",
Expand Down
6 changes: 5 additions & 1 deletion include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ extern unsigned int kobjsize(const void *objp);

#define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)

/* VMA basic access permission flags */
#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC)


/*
* Special vmas that are non-mergable, non-mlock()able.
*/
Expand Down Expand Up @@ -646,7 +650,7 @@ static inline bool vma_is_foreign(struct vm_area_struct *vma)

static inline bool vma_is_accessible(struct vm_area_struct *vma)
{
return vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC);
return vma->vm_flags & VM_ACCESS_FLAGS;
}

#ifdef CONFIG_SHMEM
Expand Down
2 changes: 1 addition & 1 deletion mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,7 @@ static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *
return a->vm_end == b->vm_start &&
mpol_equal(vma_policy(a), vma_policy(b)) &&
a->vm_file == b->vm_file &&
!((a->vm_flags ^ b->vm_flags) & ~(VM_READ|VM_WRITE|VM_EXEC|VM_SOFTDIRTY)) &&
!((a->vm_flags ^ b->vm_flags) & ~(VM_ACCESS_FLAGS | VM_SOFTDIRTY)) &&
b->vm_pgoff == a->vm_pgoff + ((b->vm_start - a->vm_start) >> PAGE_SHIFT);
}

Expand Down
4 changes: 2 additions & 2 deletions mm/mprotect.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
*/
if (arch_has_pfn_modify_check() &&
(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) &&
(newflags & (VM_READ|VM_WRITE|VM_EXEC)) == 0) {
(newflags & VM_ACCESS_FLAGS) == 0) {
pgprot_t new_pgprot = vm_get_page_prot(newflags);

error = walk_page_range(current->mm, start, end,
Expand Down Expand Up @@ -598,7 +598,7 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
newflags |= (vma->vm_flags & ~mask_off_old_flags);

/* newflags >> 4 shift VM_MAY% in place of VM_% */
if ((newflags & ~(newflags >> 4)) & (VM_READ | VM_WRITE | VM_EXEC)) {
if ((newflags & ~(newflags >> 4)) & VM_ACCESS_FLAGS) {
error = -EACCES;
goto out;
}
Expand Down

0 comments on commit 6cb4d9a

Please sign in to comment.