>>>>> On Mon, 6 May 2002 13:04:58 +0200 (MET DST), "Maciej W. Rozycki"
>>>>> <macro@ds2.pg.gda.pl> said:
macro> Check it doesn't break static executables -- there were a few
macro> arch_get_unmapped_area() updates in mm/mmap.c that you don't
macro> include in the patch it would seem.
I have yet another arch_get_unmapped_area which includes it.
My arch_get_unmapped_area is a hybrid of one in mm/mmap.c and one in
arch/sparc64/sys_sparc64.c. Also, I am using MY_SHMLBA to avoid
wasting address space. I got following comments from Ralf when I
posted my previous patch.
>>>>> On Tue, 14 Aug 2001 10:49:41 +0200, Ralf Baechle <ralf@oss.sgi.com> said:
ralf> It's wasting huge amounts of address space. That can be
ralf> prohibitive if you want to run something such as electric fence.
ralf> Technically the worst case of any CPU that's required is 32kb on
ralf> R4000 / R4400 SC and MC versions, so I don't want to go beyond
ralf> that.
Here is my arch_get_unmapped_area.
#ifdef HAVE_ARCH_UNMAPPED_AREA
/* solve cache aliasing problem (see Documentation/cachetlb.txt and
arch/sparc64/kernel/sys_sparc.c */
#if SHMLBA > 0x10000
/* avoid overkill... */
#define MY_SHMLBA 0x10000
#else
#define MY_SHMLBA SHMLBA
#endif
#define COLOUR_ALIGN(addr,pgoff) \
((((addr)+MY_SHMLBA-1)&~(MY_SHMLBA-1)) + \
(((pgoff)<<PAGE_SHIFT) & (MY_SHMLBA-1)))
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct vm_area_struct * vmm;
int do_color_align;
if (flags & MAP_FIXED) {
/* We do not accept a shared mapping if it would violate
* cache aliasing constraints.
*/
if ((flags & MAP_SHARED) && (addr & (MY_SHMLBA - 1)))
return -EINVAL;
return addr;
}
if (len > TASK_SIZE)
return -ENOMEM;
do_color_align = 0;
if (filp || (flags & MAP_SHARED))
do_color_align = 1;
if (addr) {
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
else
addr = PAGE_ALIGN(addr);
vmm = find_vma(current->mm, addr);
if (TASK_SIZE - len >= addr &&
(!vmm || addr + len <= vmm->vm_start))
return addr;
}
addr = TASK_UNMAPPED_BASE;
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
else
addr = PAGE_ALIGN(addr);
for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
/* At this point: (!vmm || addr < vmm->vm_end). */
if (TASK_SIZE - len < addr)
return -ENOMEM;
if (!vmm || addr + len <= vmm->vm_start)
return addr;
addr = vmm->vm_end;
if (do_color_align)
addr = COLOUR_ALIGN(addr, pgoff);
}
}
#endif /* HAVE_ARCH_UNMAPPED_AREA */
---
Atsushi Nemoto
|