+/*
+ * Expand (or shrink) an existing mapping, potentially moving it at the
+ * same time (controlled by the MREMAP_MAYMOVE flag and available VM space)
+ *
+ * MREMAP_FIXED option added 5-Dec-1999 by Benjamin LaHaise
+ * This option implies MREMAP_MAYMOVE.
+ *
+ * on uClinux, we only permit changing a mapping's size, and only as long as it stays within the
+ * hole allocated by the kmalloc() call in do_mmap_pgoff() and the block is not shareable
+ */
+unsigned long do_mremap(unsigned long addr,
+ unsigned long old_len, unsigned long new_len,
+ unsigned long flags, unsigned long new_addr)
+{
+ struct vm_list_struct *vml = NULL;
+
+ /* insanity checks first */
+ if (new_len == 0)
+ return (unsigned long) -EINVAL;
+
+ if (flags & MREMAP_FIXED && new_addr != addr)
+ return (unsigned long) -EINVAL;
+
+ for (vml = current->mm->context.vmlist; vml; vml = vml->next)
+ if (vml->vma->vm_start == addr)
+ goto found;
+
+ return (unsigned long) -EINVAL;
+
+ found:
+ if (vml->vma->vm_end != vml->vma->vm_start + old_len)
+ return (unsigned long) -EFAULT;
+
+ if (vml->vma->vm_flags & VM_MAYSHARE)
+ return (unsigned long) -EPERM;
+
+ if (new_len > kobjsize((void *) addr))
+ return (unsigned long) -ENOMEM;
+
+ /* all checks complete - do it */
+ vml->vma->vm_end = vml->vma->vm_start + new_len;
+
+ askedalloc -= old_len;
+ askedalloc += new_len;
+
+ return vml->vma->vm_start;
+}
+
+/*
+ * Look up the first VMA which satisfies addr < vm_end, NULL if none
+ */
+struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)