diff options
| -rw-r--r-- | arch/sparc/kernel/sys_sparc_64.c | 10 | ||||
| -rw-r--r-- | ipc/shm.c | 31 |
2 files changed, 24 insertions, 17 deletions
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index ddda12fcbac..d498b32c75f 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
| @@ -317,10 +317,14 @@ bottomup: | |||
| 317 | unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) | 317 | unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) |
| 318 | { | 318 | { |
| 319 | unsigned long align_goal, addr = -ENOMEM; | 319 | unsigned long align_goal, addr = -ENOMEM; |
| 320 | unsigned long (*get_area)(struct file *, unsigned long, | ||
| 321 | unsigned long, unsigned long, unsigned long); | ||
| 322 | |||
| 323 | get_area = current->mm->get_unmapped_area; | ||
| 320 | 324 | ||
| 321 | if (flags & MAP_FIXED) { | 325 | if (flags & MAP_FIXED) { |
| 322 | /* Ok, don't mess with it. */ | 326 | /* Ok, don't mess with it. */ |
| 323 | return get_unmapped_area(NULL, orig_addr, len, pgoff, flags); | 327 | return get_area(NULL, orig_addr, len, pgoff, flags); |
| 324 | } | 328 | } |
| 325 | flags &= ~MAP_SHARED; | 329 | flags &= ~MAP_SHARED; |
| 326 | 330 | ||
| @@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u | |||
| 333 | align_goal = (64UL * 1024); | 337 | align_goal = (64UL * 1024); |
| 334 | 338 | ||
| 335 | do { | 339 | do { |
| 336 | addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); | 340 | addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); |
| 337 | if (!(addr & ~PAGE_MASK)) { | 341 | if (!(addr & ~PAGE_MASK)) { |
| 338 | addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); | 342 | addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); |
| 339 | break; | 343 | break; |
| @@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u | |||
| 351 | * be obtained. | 355 | * be obtained. |
| 352 | */ | 356 | */ |
| 353 | if (addr & ~PAGE_MASK) | 357 | if (addr & ~PAGE_MASK) |
| 354 | addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags); | 358 | addr = get_area(NULL, orig_addr, len, pgoff, flags); |
| 355 | 359 | ||
| 356 | return addr; | 360 | return addr; |
| 357 | } | 361 | } |
| @@ -290,28 +290,28 @@ static unsigned long shm_get_unmapped_area(struct file *file, | |||
| 290 | unsigned long flags) | 290 | unsigned long flags) |
| 291 | { | 291 | { |
| 292 | struct shm_file_data *sfd = shm_file_data(file); | 292 | struct shm_file_data *sfd = shm_file_data(file); |
| 293 | return get_unmapped_area(sfd->file, addr, len, pgoff, flags); | 293 | return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len, |
| 294 | } | 294 | pgoff, flags); |
| 295 | |||
| 296 | int is_file_shm_hugepages(struct file *file) | ||
| 297 | { | ||
| 298 | int ret = 0; | ||
| 299 | |||
| 300 | if (file->f_op == &shm_file_operations) { | ||
| 301 | struct shm_file_data *sfd; | ||
| 302 | sfd = shm_file_data(file); | ||
| 303 | ret = is_file_hugepages(sfd->file); | ||
| 304 | } | ||
| 305 | return ret; | ||
| 306 | } | 295 | } |
| 307 | 296 | ||
| 308 | static const struct file_operations shm_file_operations = { | 297 | static const struct file_operations shm_file_operations = { |
| 309 | .mmap = shm_mmap, | 298 | .mmap = shm_mmap, |
| 310 | .fsync = shm_fsync, | 299 | .fsync = shm_fsync, |
| 311 | .release = shm_release, | 300 | .release = shm_release, |
| 301 | }; | ||
| 302 | |||
| 303 | static const struct file_operations shm_file_operations_huge = { | ||
| 304 | .mmap = shm_mmap, | ||
| 305 | .fsync = shm_fsync, | ||
| 306 | .release = shm_release, | ||
| 312 | .get_unmapped_area = shm_get_unmapped_area, | 307 | .get_unmapped_area = shm_get_unmapped_area, |
| 313 | }; | 308 | }; |
| 314 | 309 | ||
| 310 | int is_file_shm_hugepages(struct file *file) | ||
| 311 | { | ||
| 312 | return file->f_op == &shm_file_operations_huge; | ||
| 313 | } | ||
| 314 | |||
| 315 | static const struct vm_operations_struct shm_vm_ops = { | 315 | static const struct vm_operations_struct shm_vm_ops = { |
| 316 | .open = shm_open, /* callback for a new vm-area open */ | 316 | .open = shm_open, /* callback for a new vm-area open */ |
| 317 | .close = shm_close, /* callback for when the vm-area is released */ | 317 | .close = shm_close, /* callback for when the vm-area is released */ |
| @@ -889,7 +889,10 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) | |||
| 889 | if (!sfd) | 889 | if (!sfd) |
| 890 | goto out_put_dentry; | 890 | goto out_put_dentry; |
| 891 | 891 | ||
| 892 | file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations); | 892 | file = alloc_file(path.mnt, path.dentry, f_mode, |
| 893 | is_file_hugepages(shp->shm_file) ? | ||
| 894 | &shm_file_operations_huge : | ||
| 895 | &shm_file_operations); | ||
| 893 | if (!file) | 896 | if (!file) |
| 894 | goto out_free; | 897 | goto out_free; |
| 895 | ima_counts_get(file); | 898 | ima_counts_get(file); |
