Here is an patch to fix virtual aliasing problem with SysV IPC shared memory. I tested this patch on a r4k cpu with 32Kb D-cache. If D-cache is smaller than PAGE_SIZE this patch is not needed at all, but I think it is not so bad unconditionally forcing alignment to SHMLBA. --- Atsushi Nemoto
diff -ur linux.sgi/arch/mips/kernel/syscall.c linux/arch/mips/kernel/syscall.c --- linux.sgi/arch/mips/kernel/syscall.c Thu Apr 5 13:56:09 2001 +++ linux/arch/mips/kernel/syscall.c Mon Aug 6 16:16:36 2001 @@ -30,6 +30,7 @@ #include <asm/signal.h> #include <asm/stackframe.h> #include <asm/uaccess.h> +#include <asm/shmparam.h> extern asmlinkage void syscall_trace(void); typedef asmlinkage int (*syscall_t)(void *a0,...); @@ -91,6 +92,47 @@ { return do_mmap2(addr, len, prot, flags, fd, pgoff); } + +#ifdef HAVE_ARCH_UNMAPPED_AREA +/* solve cache aliasing problem (see Documentation/cache.txt and + arch/sparc64/kernel/sys_sparc.c */ +#define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(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; + + if (flags & MAP_FIXED) { + /* We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ + if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1))) + return -EINVAL; + return addr; + } + + if (len > TASK_SIZE) + return -ENOMEM; + if (!addr) + addr = TASK_UNMAPPED_BASE; + + if (flags & MAP_SHARED) + addr = COLOUR_ALIGN(addr); + 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 (flags & MAP_SHARED) + addr = COLOUR_ALIGN(addr); + } +} +#endif /* HAVE_ARCH_UNMAPPED_AREA */ save_static_function(sys_fork); static_unused int _sys_fork(struct pt_regs regs) diff -ur linux.sgi/include/asm-mips/pgtable.h linux/include/asm-mips/pgtable.h --- linux.sgi/include/asm-mips/pgtable.h Sun Aug 5 23:41:28 2001 +++ linux/include/asm-mips/pgtable.h Mon Aug 6 16:17:11 2001 @@ -740,6 +740,9 @@ #include <asm-generic/pgtable.h> +/* We provide our own get_unmapped_area to cope with VA holes for userland */ +#define HAVE_ARCH_UNMAPPED_AREA + #endif /* !defined (_LANGUAGE_ASSEMBLY) */ #define io_remap_page_range remap_page_range