aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>2013-05-07 19:18:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-07 21:38:27 -0400
commitaf73e4d9506d3b797509f3c030e7dcd554f7d9c4 (patch)
treef9f1bf7483495b66b6cf2cfb3c676791133733b1 /ipc
parent1ab4ce762370b82870834899e49c08129d7ae271 (diff)
hugetlbfs: fix mmap failure in unaligned size request
The current kernel returns -EINVAL unless a given mmap length is "almost" hugepage aligned. This is because in sys_mmap_pgoff() the given length is passed to vm_mmap_pgoff() as it is without being aligned with hugepage boundary. This is a regression introduced in commit 40716e29243d ("hugetlbfs: fix alignment of huge page requests"), where alignment code is pushed into hugetlb_file_setup() and the variable len in caller side is not changed. To fix this, this patch partially reverts that commit, and adds alignment code in caller side. And it also introduces hstate_sizelog() in order to get proper hstate to specified hugepage size. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=56881 [akpm@linux-foundation.org: fix warning when CONFIG_HUGETLB_PAGE=n] Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reported-by: <iceman_dvd@yahoo.com> Cc: Steven Truelove <steven.truelove@utoronto.ca> Cc: Jianguo Wu <wujianguo@huawei.com> Cc: Hugh Dickins <hughd@google.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc')
-rw-r--r--ipc/shm.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index 8247c49ec073..34af1fe34701 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -491,10 +491,14 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
491 491
492 sprintf (name, "SYSV%08x", key); 492 sprintf (name, "SYSV%08x", key);
493 if (shmflg & SHM_HUGETLB) { 493 if (shmflg & SHM_HUGETLB) {
494 struct hstate *hs = hstate_sizelog((shmflg >> SHM_HUGE_SHIFT)
495 & SHM_HUGE_MASK);
496 size_t hugesize = ALIGN(size, huge_page_size(hs));
497
494 /* hugetlb_file_setup applies strict accounting */ 498 /* hugetlb_file_setup applies strict accounting */
495 if (shmflg & SHM_NORESERVE) 499 if (shmflg & SHM_NORESERVE)
496 acctflag = VM_NORESERVE; 500 acctflag = VM_NORESERVE;
497 file = hugetlb_file_setup(name, 0, size, acctflag, 501 file = hugetlb_file_setup(name, hugesize, acctflag,
498 &shp->mlock_user, HUGETLB_SHMFS_INODE, 502 &shp->mlock_user, HUGETLB_SHMFS_INODE,
499 (shmflg >> SHM_HUGE_SHIFT) & SHM_HUGE_MASK); 503 (shmflg >> SHM_HUGE_SHIFT) & SHM_HUGE_MASK);
500 } else { 504 } else {