diff options
Diffstat (limited to 'arch/parisc/kernel/sys_parisc.c')
-rw-r--r-- | arch/parisc/kernel/sys_parisc.c | 64 |
1 files changed, 29 insertions, 35 deletions
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index f76c10863c6..5dfd248e3f1 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -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; - - offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; - - addr = DCACHE_ALIGN(addr - offset) + offset; + struct vm_unmapped_area_info info; - 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, @@ -94,11 +80,12 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, { if (len > TASK_SIZE) return -ENOMEM; - /* Might want to check for cache aliasing issues for MAP_FIXED case - * like ARM or MIPS ??? --BenH. - */ - if (flags & MAP_FIXED) + if (flags & MAP_FIXED) { + if ((flags & MAP_SHARED) && + (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) + return -EINVAL; return addr; + } if (!addr) addr = TASK_UNMAPPED_BASE; @@ -212,6 +199,13 @@ asmlinkage long parisc_sync_file_range(int fd, (loff_t)hi_nbytes << 32 | lo_nbytes, flags); } +asmlinkage long parisc_fallocate(int fd, int mode, u32 offhi, u32 offlo, + u32 lenhi, u32 lenlo) +{ + return sys_fallocate(fd, mode, ((u64)offhi << 32) | offlo, + ((u64)lenhi << 32) | lenlo); +} + asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag) { return -ENOMEM; |