SysV IPC shared memory and virtual alising

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux