Skip to content

Commit f025072

Browse files
mjkravetzgregkh
authored andcommitted
ipc/shm.c: add split function to shm_vm_ops
commit 3d942ee upstream. If System V shmget/shmat operations are used to create a hugetlbfs backed mapping, it is possible to munmap part of the mapping and split the underlying vma such that it is not huge page aligned. This will untimately result in the following BUG: kernel BUG at /build/linux-jWa1Fv/linux-4.15.0/mm/hugetlb.c:3310! Oops: Exception in kernel mode, sig: 5 [#1] LE SMP NR_CPUS=2048 NUMA PowerNV Modules linked in: kcm nfc af_alg caif_socket caif phonet fcrypt CPU: 18 PID: 43243 Comm: trinity-subchil Tainted: G C E 4.15.0-10-generic #11-Ubuntu NIP: c00000000036e764 LR: c00000000036ee48 CTR: 0000000000000009 REGS: c000003fbcdcf810 TRAP: 0700 Tainted: G C E (4.15.0-10-generic) MSR: 9000000000029033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 24002222 XER: 20040000 CFAR: c00000000036ee44 SOFTE: 1 NIP __unmap_hugepage_range+0xa4/0x760 LR __unmap_hugepage_range_final+0x28/0x50 Call Trace: 0x7115e4e00000 (unreliable) __unmap_hugepage_range_final+0x28/0x50 unmap_single_vma+0x11c/0x190 unmap_vmas+0x94/0x140 exit_mmap+0x9c/0x1d0 mmput+0xa8/0x1d0 do_exit+0x360/0xc80 do_group_exit+0x60/0x100 SyS_exit_group+0x24/0x30 system_call+0x58/0x6c ---[ end trace ee88f958a1c62605 ]--- This bug was introduced by commit 31383c6 ("mm, hugetlbfs: introduce ->split() to vm_operations_struct"). A split function was added to vm_operations_struct to determine if a mapping can be split. This was mostly for device-dax and hugetlbfs mappings which have specific alignment constraints. Mappings initiated via shmget/shmat have their original vm_ops overwritten with shm_vm_ops. shm_vm_ops functions will call back to the original vm_ops if needed. Add such a split function to shm_vm_ops. Link: http://lkml.kernel.org/r/[email protected] Fixes: 31383c6 ("mm, hugetlbfs: introduce ->split() to vm_operations_struct") Signed-off-by: Mike Kravetz <[email protected]> Reported-by: Laurent Dufour <[email protected]> Reviewed-by: Laurent Dufour <[email protected]> Tested-by: Laurent Dufour <[email protected]> Reviewed-by: Dan Williams <[email protected]> Acked-by: Michal Hocko <[email protected]> Cc: Davidlohr Bueso <[email protected]> Cc: Manfred Spraul <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent f00a344 commit f025072

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

ipc/shm.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,17 @@ static int shm_fault(struct vm_fault *vmf)
386386
return sfd->vm_ops->fault(vmf);
387387
}
388388

389+
static int shm_split(struct vm_area_struct *vma, unsigned long addr)
390+
{
391+
struct file *file = vma->vm_file;
392+
struct shm_file_data *sfd = shm_file_data(file);
393+
394+
if (sfd->vm_ops && sfd->vm_ops->split)
395+
return sfd->vm_ops->split(vma, addr);
396+
397+
return 0;
398+
}
399+
389400
#ifdef CONFIG_NUMA
390401
static int shm_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
391402
{
@@ -510,6 +521,7 @@ static const struct vm_operations_struct shm_vm_ops = {
510521
.open = shm_open, /* callback for a new vm-area open */
511522
.close = shm_close, /* callback for when the vm-area is released */
512523
.fault = shm_fault,
524+
.split = shm_split,
513525
#if defined(CONFIG_NUMA)
514526
.set_policy = shm_set_policy,
515527
.get_policy = shm_get_policy,

0 commit comments

Comments
 (0)