diff options
-rw-r--r-- | include/linux/mm.h | 3 | ||||
-rw-r--r-- | include/uapi/linux/prctl.h | 3 | ||||
-rw-r--r-- | kernel/fork.c | 11 | ||||
-rw-r--r-- | kernel/sys.c | 15 |
4 files changed, 29 insertions, 3 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 35300f390eb6..c270fa68a32b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -177,6 +177,9 @@ extern unsigned int kobjsize(const void *objp); | |||
177 | */ | 177 | */ |
178 | #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP) | 178 | #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP) |
179 | 179 | ||
180 | /* This mask defines which mm->def_flags a process can inherit its parent */ | ||
181 | #define VM_INIT_DEF_MASK VM_NOHUGEPAGE | ||
182 | |||
180 | /* | 183 | /* |
181 | * mapping from the currently active vm_flags protection bits (the | 184 | * mapping from the currently active vm_flags protection bits (the |
182 | * low four bits) to a page protection mask.. | 185 | * low four bits) to a page protection mask.. |
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index 289760f424aa..58afc04c107e 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h | |||
@@ -149,4 +149,7 @@ | |||
149 | 149 | ||
150 | #define PR_GET_TID_ADDRESS 40 | 150 | #define PR_GET_TID_ADDRESS 40 |
151 | 151 | ||
152 | #define PR_SET_THP_DISABLE 41 | ||
153 | #define PR_GET_THP_DISABLE 42 | ||
154 | |||
152 | #endif /* _LINUX_PRCTL_H */ | 155 | #endif /* _LINUX_PRCTL_H */ |
diff --git a/kernel/fork.c b/kernel/fork.c index abc45890f0a5..e40c0a01d5a6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -530,8 +530,6 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) | |||
530 | atomic_set(&mm->mm_count, 1); | 530 | atomic_set(&mm->mm_count, 1); |
531 | init_rwsem(&mm->mmap_sem); | 531 | init_rwsem(&mm->mmap_sem); |
532 | INIT_LIST_HEAD(&mm->mmlist); | 532 | INIT_LIST_HEAD(&mm->mmlist); |
533 | mm->flags = (current->mm) ? | ||
534 | (current->mm->flags & MMF_INIT_MASK) : default_dump_filter; | ||
535 | mm->core_state = NULL; | 533 | mm->core_state = NULL; |
536 | atomic_long_set(&mm->nr_ptes, 0); | 534 | atomic_long_set(&mm->nr_ptes, 0); |
537 | memset(&mm->rss_stat, 0, sizeof(mm->rss_stat)); | 535 | memset(&mm->rss_stat, 0, sizeof(mm->rss_stat)); |
@@ -540,8 +538,15 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) | |||
540 | mm_init_owner(mm, p); | 538 | mm_init_owner(mm, p); |
541 | clear_tlb_flush_pending(mm); | 539 | clear_tlb_flush_pending(mm); |
542 | 540 | ||
543 | if (likely(!mm_alloc_pgd(mm))) { | 541 | if (current->mm) { |
542 | mm->flags = current->mm->flags & MMF_INIT_MASK; | ||
543 | mm->def_flags = current->mm->def_flags & VM_INIT_DEF_MASK; | ||
544 | } else { | ||
545 | mm->flags = default_dump_filter; | ||
544 | mm->def_flags = 0; | 546 | mm->def_flags = 0; |
547 | } | ||
548 | |||
549 | if (likely(!mm_alloc_pgd(mm))) { | ||
545 | mmu_notifier_mm_init(mm); | 550 | mmu_notifier_mm_init(mm); |
546 | return mm; | 551 | return mm; |
547 | } | 552 | } |
diff --git a/kernel/sys.c b/kernel/sys.c index adaeab6f7a87..fba0f29401ea 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1996,6 +1996,21 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
1996 | if (arg2 || arg3 || arg4 || arg5) | 1996 | if (arg2 || arg3 || arg4 || arg5) |
1997 | return -EINVAL; | 1997 | return -EINVAL; |
1998 | return current->no_new_privs ? 1 : 0; | 1998 | return current->no_new_privs ? 1 : 0; |
1999 | case PR_GET_THP_DISABLE: | ||
2000 | if (arg2 || arg3 || arg4 || arg5) | ||
2001 | return -EINVAL; | ||
2002 | error = !!(me->mm->def_flags & VM_NOHUGEPAGE); | ||
2003 | break; | ||
2004 | case PR_SET_THP_DISABLE: | ||
2005 | if (arg3 || arg4 || arg5) | ||
2006 | return -EINVAL; | ||
2007 | down_write(&me->mm->mmap_sem); | ||
2008 | if (arg2) | ||
2009 | me->mm->def_flags |= VM_NOHUGEPAGE; | ||
2010 | else | ||
2011 | me->mm->def_flags &= ~VM_NOHUGEPAGE; | ||
2012 | up_write(&me->mm->mmap_sem); | ||
2013 | break; | ||
1999 | default: | 2014 | default: |
2000 | error = -EINVAL; | 2015 | error = -EINVAL; |
2001 | break; | 2016 | break; |