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 | ||