Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARC: [mm] Aliasing VIPT dcache support 4/4

Enforce congruency of userspace shared mappings

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>

+101 -5
-1
arch/arc/include/asm/Kbuild
··· 32 32 generic-y += scatterlist.h 33 33 generic-y += sembuf.h 34 34 generic-y += shmbuf.h 35 - generic-y += shmparam.h 36 35 generic-y += siginfo.h 37 36 generic-y += socket.h 38 37 generic-y += sockios.h
-3
arch/arc/include/asm/cache.h
··· 55 55 : "r"(data), "r"(ptr)); \ 56 56 }) 57 57 58 - /* used to give SHMLBA a value to avoid Cache Aliasing */ 59 - extern unsigned int ARC_shmlba; 60 - 61 58 #define ARCH_DMA_MINALIGN L1_CACHE_BYTES 62 59 63 60 /*
+1
arch/arc/include/asm/cacheflush.h
··· 19 19 #define _ASM_CACHEFLUSH_H 20 20 21 21 #include <linux/mm.h> 22 + #include <asm/shmparam.h> 22 23 23 24 /* 24 25 * Semantically we need this because icache doesn't snoop dcache/dma.
+3
arch/arc/include/asm/pgtable.h
··· 395 395 396 396 #include <asm-generic/pgtable.h> 397 397 398 + /* to cope with aliasing VIPT cache */ 399 + #define HAVE_ARCH_UNMAPPED_AREA 400 + 398 401 /* 399 402 * No page table caches to initialise 400 403 */
+18
arch/arc/include/asm/shmparam.h
··· 1 + /* 2 + * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef __ARC_ASM_SHMPARAM_H 10 + #define __ARC_ASM_SHMPARAM_H 11 + 12 + /* Handle upto 2 cache bins */ 13 + #define SHMLBA (2 * PAGE_SIZE) 14 + 15 + /* Enforce SHMLBA in shmat */ 16 + #define __ARCH_FORCE_SHMLBA 17 + 18 + #endif
+1 -1
arch/arc/mm/Makefile
··· 7 7 # 8 8 9 9 obj-y := extable.o ioremap.o dma.o fault.o init.o 10 - obj-y += tlb.o tlbex.o cache_arc700.o 10 + obj-y += tlb.o tlbex.o cache_arc700.o mmap.o
+78
arch/arc/mm/mmap.c
··· 1 + /* 2 + * ARC700 mmap 3 + * 4 + * (started from arm version - for VIPT alias handling) 5 + * 6 + * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com) 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/fs.h> 14 + #include <linux/mm.h> 15 + #include <linux/mman.h> 16 + #include <linux/sched.h> 17 + #include <asm/cacheflush.h> 18 + 19 + #define COLOUR_ALIGN(addr, pgoff) \ 20 + ((((addr) + SHMLBA - 1) & ~(SHMLBA - 1)) + \ 21 + (((pgoff) << PAGE_SHIFT) & (SHMLBA - 1))) 22 + 23 + /* 24 + * Ensure that shared mappings are correctly aligned to 25 + * avoid aliasing issues with VIPT caches. 26 + * We need to ensure that 27 + * a specific page of an object is always mapped at a multiple of 28 + * SHMLBA bytes. 29 + */ 30 + unsigned long 31 + arch_get_unmapped_area(struct file *filp, unsigned long addr, 32 + unsigned long len, unsigned long pgoff, unsigned long flags) 33 + { 34 + struct mm_struct *mm = current->mm; 35 + struct vm_area_struct *vma; 36 + int do_align = 0; 37 + int aliasing = cache_is_vipt_aliasing(); 38 + struct vm_unmapped_area_info info; 39 + 40 + /* 41 + * We only need to do colour alignment if D cache aliases. 42 + */ 43 + if (aliasing) 44 + do_align = filp || (flags & MAP_SHARED); 45 + 46 + /* 47 + * We enforce the MAP_FIXED case. 48 + */ 49 + if (flags & MAP_FIXED) { 50 + if (aliasing && flags & MAP_SHARED && 51 + (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)) 52 + return -EINVAL; 53 + return addr; 54 + } 55 + 56 + if (len > TASK_SIZE) 57 + return -ENOMEM; 58 + 59 + if (addr) { 60 + if (do_align) 61 + addr = COLOUR_ALIGN(addr, pgoff); 62 + else 63 + addr = PAGE_ALIGN(addr); 64 + 65 + vma = find_vma(mm, addr); 66 + if (TASK_SIZE - len >= addr && 67 + (!vma || addr + len <= vma->vm_start)) 68 + return addr; 69 + } 70 + 71 + info.flags = 0; 72 + info.length = len; 73 + info.low_limit = mm->mmap_base; 74 + info.high_limit = TASK_SIZE; 75 + info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; 76 + info.align_offset = pgoff << PAGE_SHIFT; 77 + return vm_unmapped_area(&info); 78 + }