diff options
| author | Vineet Gupta <vgupta@synopsys.com> | 2013-05-09 09:50:43 -0400 |
|---|---|---|
| committer | Vineet Gupta <vgupta@synopsys.com> | 2013-05-09 12:30:57 -0400 |
| commit | 5bba49f5397c012d873c73860ad7b50c526e613b (patch) | |
| tree | bcea4107858b117c7bd063ca3e90c0cc1773f636 | |
| parent | de2a852cc0d4c4d6a9c22a597c9cc231f2e6ceb4 (diff) | |
ARC: [mm] Aliasing VIPT dcache support 4/4
Enforce congruency of userspace shared mappings
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
| -rw-r--r-- | arch/arc/include/asm/Kbuild | 1 | ||||
| -rw-r--r-- | arch/arc/include/asm/cache.h | 3 | ||||
| -rw-r--r-- | arch/arc/include/asm/cacheflush.h | 1 | ||||
| -rw-r--r-- | arch/arc/include/asm/pgtable.h | 3 | ||||
| -rw-r--r-- | arch/arc/include/asm/shmparam.h | 18 | ||||
| -rw-r--r-- | arch/arc/mm/Makefile | 2 | ||||
| -rw-r--r-- | arch/arc/mm/mmap.c | 78 |
7 files changed, 101 insertions, 5 deletions
diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index 48af742f8b5a..d8dd660898b9 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild | |||
| @@ -32,7 +32,6 @@ generic-y += resource.h | |||
| 32 | generic-y += scatterlist.h | 32 | generic-y += scatterlist.h |
| 33 | generic-y += sembuf.h | 33 | generic-y += sembuf.h |
| 34 | generic-y += shmbuf.h | 34 | generic-y += shmbuf.h |
| 35 | generic-y += shmparam.h | ||
| 36 | generic-y += siginfo.h | 35 | generic-y += siginfo.h |
| 37 | generic-y += socket.h | 36 | generic-y += socket.h |
| 38 | generic-y += sockios.h | 37 | generic-y += sockios.h |
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 6632273861fd..d5555fe4742a 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h | |||
| @@ -55,9 +55,6 @@ | |||
| 55 | : "r"(data), "r"(ptr)); \ | 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 | #define ARCH_DMA_MINALIGN L1_CACHE_BYTES | 58 | #define ARCH_DMA_MINALIGN L1_CACHE_BYTES |
| 62 | 59 | ||
| 63 | /* | 60 | /* |
diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h index 14a0fea0029e..9f841af41092 100644 --- a/arch/arc/include/asm/cacheflush.h +++ b/arch/arc/include/asm/cacheflush.h | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #define _ASM_CACHEFLUSH_H | 19 | #define _ASM_CACHEFLUSH_H |
| 20 | 20 | ||
| 21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
| 22 | #include <asm/shmparam.h> | ||
| 22 | 23 | ||
| 23 | /* | 24 | /* |
| 24 | * Semantically we need this because icache doesn't snoop dcache/dma. | 25 | * Semantically we need this because icache doesn't snoop dcache/dma. |
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index b7e36684c091..1cc4720faccb 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h | |||
| @@ -395,6 +395,9 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, | |||
| 395 | 395 | ||
| 396 | #include <asm-generic/pgtable.h> | 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 | * No page table caches to initialise | 402 | * No page table caches to initialise |
| 400 | */ | 403 | */ |
diff --git a/arch/arc/include/asm/shmparam.h b/arch/arc/include/asm/shmparam.h new file mode 100644 index 000000000000..fffeecc04270 --- /dev/null +++ b/arch/arc/include/asm/shmparam.h | |||
| @@ -0,0 +1,18 @@ | |||
| 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 | ||
diff --git a/arch/arc/mm/Makefile b/arch/arc/mm/Makefile index 168dc146a8f6..ac95cc239c1e 100644 --- a/arch/arc/mm/Makefile +++ b/arch/arc/mm/Makefile | |||
| @@ -7,4 +7,4 @@ | |||
| 7 | # | 7 | # |
| 8 | 8 | ||
| 9 | obj-y := extable.o ioremap.o dma.o fault.o init.o | 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 |
diff --git a/arch/arc/mm/mmap.c b/arch/arc/mm/mmap.c new file mode 100644 index 000000000000..2e06d56e987b --- /dev/null +++ b/arch/arc/mm/mmap.c | |||
| @@ -0,0 +1,78 @@ | |||
| 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 | } | ||
