diff options
Diffstat (limited to 'arch/parisc/kernel/sys_parisc.c')
| -rw-r--r-- | arch/parisc/kernel/sys_parisc.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 5dfd248e3f1a..0d3a9d4927b5 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
| @@ -61,8 +61,15 @@ static int get_offset(struct address_space *mapping) | |||
| 61 | return (unsigned long) mapping >> 8; | 61 | return (unsigned long) mapping >> 8; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static unsigned long get_shared_area(struct address_space *mapping, | 64 | static unsigned long shared_align_offset(struct file *filp, unsigned long pgoff) |
| 65 | unsigned long addr, unsigned long len, unsigned long pgoff) | 65 | { |
| 66 | struct address_space *mapping = filp ? filp->f_mapping : NULL; | ||
| 67 | |||
| 68 | return (get_offset(mapping) + pgoff) << PAGE_SHIFT; | ||
| 69 | } | ||
| 70 | |||
| 71 | static unsigned long get_shared_area(struct file *filp, unsigned long addr, | ||
| 72 | unsigned long len, unsigned long pgoff) | ||
| 66 | { | 73 | { |
| 67 | struct vm_unmapped_area_info info; | 74 | struct vm_unmapped_area_info info; |
| 68 | 75 | ||
| @@ -71,7 +78,7 @@ static unsigned long get_shared_area(struct address_space *mapping, | |||
| 71 | info.low_limit = PAGE_ALIGN(addr); | 78 | info.low_limit = PAGE_ALIGN(addr); |
| 72 | info.high_limit = TASK_SIZE; | 79 | info.high_limit = TASK_SIZE; |
| 73 | info.align_mask = PAGE_MASK & (SHMLBA - 1); | 80 | info.align_mask = PAGE_MASK & (SHMLBA - 1); |
| 74 | info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT; | 81 | info.align_offset = shared_align_offset(filp, pgoff); |
| 75 | return vm_unmapped_area(&info); | 82 | return vm_unmapped_area(&info); |
| 76 | } | 83 | } |
| 77 | 84 | ||
| @@ -82,20 +89,18 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
| 82 | return -ENOMEM; | 89 | return -ENOMEM; |
| 83 | if (flags & MAP_FIXED) { | 90 | if (flags & MAP_FIXED) { |
| 84 | if ((flags & MAP_SHARED) && | 91 | if ((flags & MAP_SHARED) && |
| 85 | (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) | 92 | (addr - shared_align_offset(filp, pgoff)) & (SHMLBA - 1)) |
| 86 | return -EINVAL; | 93 | return -EINVAL; |
| 87 | return addr; | 94 | return addr; |
| 88 | } | 95 | } |
| 89 | if (!addr) | 96 | if (!addr) |
| 90 | addr = TASK_UNMAPPED_BASE; | 97 | addr = TASK_UNMAPPED_BASE; |
| 91 | 98 | ||
| 92 | if (filp) { | 99 | if (filp || (flags & MAP_SHARED)) |
| 93 | addr = get_shared_area(filp->f_mapping, addr, len, pgoff); | 100 | addr = get_shared_area(filp, addr, len, pgoff); |
| 94 | } else if(flags & MAP_SHARED) { | 101 | else |
| 95 | addr = get_shared_area(NULL, addr, len, pgoff); | ||
| 96 | } else { | ||
| 97 | addr = get_unshared_area(addr, len); | 102 | addr = get_unshared_area(addr, len); |
| 98 | } | 103 | |
| 99 | return addr; | 104 | return addr; |
| 100 | } | 105 | } |
| 101 | 106 | ||
