|
@@ -35,22 +35,17 @@
|
|
|
|
|
|
static unsigned long get_unshared_area(unsigned long addr, unsigned long len)
|
|
|
{
|
|
|
- struct vm_area_struct *vma;
|
|
|
+ struct vm_unmapped_area_info info;
|
|
|
|
|
|
- addr = PAGE_ALIGN(addr);
|
|
|
-
|
|
|
- for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
|
|
|
- /* At this point: (!vma || addr < vma->vm_end). */
|
|
|
- if (TASK_SIZE - len < addr)
|
|
|
- return -ENOMEM;
|
|
|
- if (!vma || addr + len <= vma->vm_start)
|
|
|
- return addr;
|
|
|
- addr = vma->vm_end;
|
|
|
- }
|
|
|
+ info.flags = 0;
|
|
|
+ info.length = len;
|
|
|
+ info.low_limit = PAGE_ALIGN(addr);
|
|
|
+ info.high_limit = TASK_SIZE;
|
|
|
+ info.align_mask = 0;
|
|
|
+ info.align_offset = 0;
|
|
|
+ return vm_unmapped_area(&info);
|
|
|
}
|
|
|
|
|
|
-#define DCACHE_ALIGN(addr) (((addr) + (SHMLBA - 1)) &~ (SHMLBA - 1))
|
|
|
-
|
|
|
/*
|
|
|
* We need to know the offset to use. Old scheme was to look for
|
|
|
* existing mapping and use the same offset. New scheme is to use the
|
|
@@ -63,30 +58,21 @@ static unsigned long get_unshared_area(unsigned long addr, unsigned long len)
|
|
|
*/
|
|
|
static int get_offset(struct address_space *mapping)
|
|
|
{
|
|
|
- int offset = (unsigned long) mapping << (PAGE_SHIFT - 8);
|
|
|
- return offset & 0x3FF000;
|
|
|
+ return (unsigned long) mapping >> 8;
|
|
|
}
|
|
|
|
|
|
static unsigned long get_shared_area(struct address_space *mapping,
|
|
|
unsigned long addr, unsigned long len, unsigned long pgoff)
|
|
|
{
|
|
|
- struct vm_area_struct *vma;
|
|
|
- int offset = mapping ? get_offset(mapping) : 0;
|
|
|
+ struct vm_unmapped_area_info info;
|
|
|
|
|
|
- offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000;
|
|
|
-
|
|
|
- addr = DCACHE_ALIGN(addr - offset) + offset;
|
|
|
-
|
|
|
- for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
|
|
|
- /* At this point: (!vma || addr < vma->vm_end). */
|
|
|
- if (TASK_SIZE - len < addr)
|
|
|
- return -ENOMEM;
|
|
|
- if (!vma || addr + len <= vma->vm_start)
|
|
|
- return addr;
|
|
|
- addr = DCACHE_ALIGN(vma->vm_end - offset) + offset;
|
|
|
- if (addr < vma->vm_end) /* handle wraparound */
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
+ info.flags = 0;
|
|
|
+ info.length = len;
|
|
|
+ info.low_limit = PAGE_ALIGN(addr);
|
|
|
+ info.high_limit = TASK_SIZE;
|
|
|
+ info.align_mask = PAGE_MASK & (SHMLBA - 1);
|
|
|
+ info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT;
|
|
|
+ return vm_unmapped_area(&info);
|
|
|
}
|
|
|
|
|
|
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
|