alpha 2.4.13, fix get_unmapped_area for 32-bit processes

From: Richard Henderson (rth@twiddle.net)
Date: Thu Oct 25 2001 - 02:47:18 EST


On Tue, Oct 23, 2001 at 09:03:46PM -0400, Jay Estabrook wrote:
> diff -ur LINUX/pre6-2.4.13/mm/mmap.c PATCH/pre6-2.4.13/mm/mmap.c
> --- LINUX/pre6-2.4.13/mm/mmap.c Thu Oct 11 17:31:55 2001
> +++ PATCH/pre6-2.4.13/mm/mmap.c Tue Oct 23 13:38:38 2001
> @@ -600,8 +600,11 @@ arch_get_unmapped_area

This should fix the problem, as discussed previously.

r~

diff -rup linux/include/asm-alpha/pgtable.h 2.4.13/include/asm-alpha/pgtable.h
--- linux/include/asm-alpha/pgtable.h Thu Oct 4 18:47:08 2001
+++ 2.4.13/include/asm-alpha/pgtable.h Wed Oct 24 16:21:38 2001
@@ -363,4 +363,7 @@ extern void paging_init(void);
  */
 #define pgtable_cache_init() do { } while (0)
 
+/* We have our own get_unmapped_area to cope with ADDR_LIMIT_32BIT. */
+#define HAVE_ARCH_UNMAPPED_AREA
+
 #endif /* _ALPHA_PGTABLE_H */
Only in 2.4.13/include/asm-alpha: pgtable.h.orig
diff -rup linux/arch/alpha/kernel/osf_sys.c 2.4.13/arch/alpha/kernel/osf_sys.c
--- linux/arch/alpha/kernel/osf_sys.c Sun Aug 12 15:04:07 2001
+++ 2.4.13/arch/alpha/kernel/osf_sys.c Wed Oct 24 17:05:17 2001
@@ -1320,3 +1320,62 @@ asmlinkage int sys_old_adjtimex(struct t
 
         return ret;
 }
+
+/* Get an address range which is currently unmapped. Similar to the
+ generic version except that we know how to honor ADDR_LIMIT_32BIT. */
+
+static unsigned long
+arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
+ unsigned long limit)
+{
+ struct vm_area_struct *vma = find_vma(current->mm, addr);
+
+ while (1) {
+ /* At this point: (!vma || addr < vma->vm_end). */
+ if (limit - len < addr)
+ return -ENOMEM;
+ if (!vma || addr + len <= vma->vm_start)
+ return addr;
+ addr = vma->vm_end;
+ vma = vma->vm_next;
+ }
+}
+
+unsigned long
+arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff,
+ unsigned long flags)
+{
+ unsigned long limit;
+
+ /* "32 bit" actually means 31 bit, since pointers sign extend. */
+ if (current->personality & ADDR_LIMIT_32BIT)
+ limit = 0x80000000;
+ else
+ limit = TASK_SIZE;
+
+ if (len > limit)
+ return -ENOMEM;
+
+ /* First, see if the given suggestion fits. */
+ if (addr) {
+ struct vm_area_struct *vma;
+
+ addr = PAGE_ALIGN(addr);
+ vma = find_vma(current->mm, addr);
+ if (limit - len >= addr &&
+ (!vma || addr + len <= vma->vm_start))
+ return addr;
+ }
+
+ /* Next, try allocating at TASK_UNMAPPED_BASE. */
+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
+ len, limit);
+ if (addr != -ENOMEM)
+ return addr;
+
+ /* Finally, try allocating in low memory. */
+ addr = arch_get_unmapped_area_1 (PAGE_SIZE, len, limit);
+
+ return addr;
+}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Oct 31 2001 - 21:00:25 EST