diff options
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/c-octeon.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/c-r3k.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/c-r4k.c | 61 | ||||
-rw-r--r-- | arch/mips/mm/c-tx39.c | 3 | ||||
-rw-r--r-- | arch/mips/mm/cache.c | 8 | ||||
-rw-r--r-- | arch/mips/mm/dma-default.c | 18 | ||||
-rw-r--r-- | arch/mips/mm/extable.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/fault.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/highmem.c | 3 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/ioremap.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/mmap.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/page.c | 1 | ||||
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 9 |
14 files changed, 76 insertions, 40 deletions
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c index 05b1d7cf9514..0e45b061e514 100644 --- a/arch/mips/mm/c-octeon.c +++ b/arch/mips/mm/c-octeon.c @@ -294,6 +294,8 @@ void octeon_cache_init(void) flush_data_cache_page = octeon_flush_data_cache_page; flush_icache_range = octeon_flush_icache_range; local_flush_icache_range = local_octeon_flush_icache_range; + __flush_icache_user_range = octeon_flush_icache_range; + __local_flush_icache_user_range = local_octeon_flush_icache_range; __flush_kernel_vmap_range = octeon_flush_kernel_vmap_range; diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 135ec313c1f6..21e4e662c1fa 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -325,6 +325,8 @@ void r3k_cache_init(void) flush_cache_page = r3k_flush_cache_page; flush_icache_range = r3k_flush_icache_range; local_flush_icache_range = r3k_flush_icache_range; + __flush_icache_user_range = r3k_flush_icache_range; + __local_flush_icache_user_range = r3k_flush_icache_range; __flush_kernel_vmap_range = r3k_flush_kernel_vmap_range; diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index fa7d8d3790bf..88cfaf81c958 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -17,7 +17,7 @@ #include <linux/sched.h> #include <linux/smp.h> #include <linux/mm.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/bitops.h> #include <asm/bcache.h> @@ -722,11 +722,13 @@ struct flush_icache_range_args { unsigned long start; unsigned long end; unsigned int type; + bool user; }; static inline void __local_r4k_flush_icache_range(unsigned long start, unsigned long end, - unsigned int type) + unsigned int type, + bool user) { if (!cpu_has_ic_fills_f_dc) { if (type == R4K_INDEX || @@ -734,7 +736,10 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; - protected_blast_dcache_range(start, end); + if (user) + protected_blast_dcache_range(start, end); + else + blast_dcache_range(start, end); } } @@ -748,27 +753,25 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, break; default: - protected_blast_icache_range(start, end); + if (user) + protected_blast_icache_range(start, end); + else + blast_icache_range(start, end); break; } } -#ifdef CONFIG_EVA - /* - * Due to all possible segment mappings, there might cache aliases - * caused by the bootloader being in non-EVA mode, and the CPU switching - * to EVA during early kernel init. It's best to flush the scache - * to avoid having secondary cores fetching stale data and lead to - * kernel crashes. - */ - bc_wback_inv(start, (end - start)); - __sync(); -#endif } static inline void local_r4k_flush_icache_range(unsigned long start, unsigned long end) { - __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX); + __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX, false); +} + +static inline void local_r4k_flush_icache_user_range(unsigned long start, + unsigned long end) +{ + __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX, true); } static inline void local_r4k_flush_icache_range_ipi(void *args) @@ -777,11 +780,13 @@ static inline void local_r4k_flush_icache_range_ipi(void *args) unsigned long start = fir_args->start; unsigned long end = fir_args->end; unsigned int type = fir_args->type; + bool user = fir_args->user; - __local_r4k_flush_icache_range(start, end, type); + __local_r4k_flush_icache_range(start, end, type, user); } -static void r4k_flush_icache_range(unsigned long start, unsigned long end) +static void __r4k_flush_icache_range(unsigned long start, unsigned long end, + bool user) { struct flush_icache_range_args args; unsigned long size, cache_size; @@ -789,6 +794,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) args.start = start; args.end = end; args.type = R4K_HIT | R4K_INDEX; + args.user = user; /* * Indexed cache ops require an SMP call. @@ -814,6 +820,16 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) instruction_hazard(); } +static void r4k_flush_icache_range(unsigned long start, unsigned long end) +{ + return __r4k_flush_icache_range(start, end, false); +} + +static void r4k_flush_icache_user_range(unsigned long start, unsigned long end) +{ + return __r4k_flush_icache_range(start, end, true); +} + #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) @@ -1915,9 +1931,16 @@ void r4k_cache_init(void) flush_data_cache_page = r4k_flush_data_cache_page; flush_icache_range = r4k_flush_icache_range; local_flush_icache_range = local_r4k_flush_icache_range; + __flush_icache_user_range = r4k_flush_icache_user_range; + __local_flush_icache_user_range = local_r4k_flush_icache_user_range; #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) - if (coherentio) { +# if defined(CONFIG_DMA_PERDEV_COHERENT) + if (0) { +# else + if ((coherentio == IO_COHERENCE_ENABLED) || + ((coherentio == IO_COHERENCE_DEFAULT) && hw_coherentio)) { +# endif _dma_cache_wback_inv = (void *)cache_noop; _dma_cache_wback = (void *)cache_noop; _dma_cache_inv = (void *)cache_noop; diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 596e18458e04..5c282583edf1 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c @@ -411,6 +411,9 @@ void tx39_cache_init(void) break; } + __flush_icache_user_range = flush_icache_range; + __local_flush_icache_user_range = local_flush_icache_range; + current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways; current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways; diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index bf04c6c479a4..6db341347202 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -10,7 +10,7 @@ #include <linux/fcntl.h> #include <linux/kernel.h> #include <linux/linkage.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/sched.h> #include <linux/syscalls.h> #include <linux/mm.h> @@ -33,6 +33,10 @@ void (*flush_icache_range)(unsigned long start, unsigned long end); EXPORT_SYMBOL_GPL(flush_icache_range); void (*local_flush_icache_range)(unsigned long start, unsigned long end); EXPORT_SYMBOL_GPL(local_flush_icache_range); +void (*__flush_icache_user_range)(unsigned long start, unsigned long end); +EXPORT_SYMBOL_GPL(__flush_icache_user_range); +void (*__local_flush_icache_user_range)(unsigned long start, unsigned long end); +EXPORT_SYMBOL_GPL(__local_flush_icache_user_range); void (*__flush_cache_vmap)(void); void (*__flush_cache_vunmap)(void); @@ -74,7 +78,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes)) return -EFAULT; - flush_icache_range(addr, addr + bytes); + __flush_icache_user_range(addr, addr + bytes); return 0; } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index b2eadd6fa9a1..46d5696c4f27 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -11,7 +11,7 @@ #include <linux/types.h> #include <linux/dma-mapping.h> #include <linux/mm.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/scatterlist.h> #include <linux/string.h> #include <linux/gfp.h> @@ -24,14 +24,15 @@ #include <dma-coherence.h> -#ifdef CONFIG_DMA_MAYBE_COHERENT -int coherentio = 0; /* User defined DMA coherency from command line. */ +#if defined(CONFIG_DMA_MAYBE_COHERENT) && !defined(CONFIG_DMA_PERDEV_COHERENT) +/* User defined DMA coherency from command line. */ +enum coherent_io_user_state coherentio = IO_COHERENCE_DEFAULT; EXPORT_SYMBOL_GPL(coherentio); int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */ static int __init setcoherentio(char *str) { - coherentio = 1; + coherentio = IO_COHERENCE_ENABLED; pr_info("Hardware DMA cache coherency (command line)\n"); return 0; } @@ -39,7 +40,7 @@ early_param("coherentio", setcoherentio); static int __init setnocoherentio(char *str) { - coherentio = 0; + coherentio = IO_COHERENCE_DISABLED; pr_info("Software DMA cache coherency (command line)\n"); return 0; } @@ -160,8 +161,7 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, *dma_handle = plat_map_dma_mem(dev, ret, size); if (!plat_device_is_coherent(dev)) { dma_cache_wback_inv((unsigned long) ret, size); - if (!hw_coherentio) - ret = UNCAC_ADDR(ret); + ret = UNCAC_ADDR(ret); } return ret; @@ -189,7 +189,7 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); - if (!plat_device_is_coherent(dev) && !hw_coherentio) + if (!plat_device_is_coherent(dev)) addr = CAC_ADDR(addr); page = virt_to_page((void *) addr); @@ -209,7 +209,7 @@ static int mips_dma_mmap(struct device *dev, struct vm_area_struct *vma, unsigned long pfn; int ret = -ENXIO; - if (!plat_device_is_coherent(dev) && !hw_coherentio) + if (!plat_device_is_coherent(dev)) addr = CAC_ADDR(addr); pfn = page_to_pfn(virt_to_page((void *)addr)); diff --git a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c index 9d25d2ba4b9e..e474fa2efed4 100644 --- a/arch/mips/mm/extable.c +++ b/arch/mips/mm/extable.c @@ -5,7 +5,7 @@ * * Copyright (C) 1997, 99, 2001 - 2004 Ralf Baechle <ralf@linux-mips.org> */ -#include <linux/module.h> +#include <linux/extable.h> #include <linux/spinlock.h> #include <asm/branch.h> #include <asm/uaccess.h> diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 9560ad731120..d56a855828c2 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -18,7 +18,6 @@ #include <linux/mman.h> #include <linux/mm.h> #include <linux/smp.h> -#include <linux/module.h> #include <linux/kprobes.h> #include <linux/perf_event.h> #include <linux/uaccess.h> diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index d7258a103439..f13f51003bd8 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -1,5 +1,6 @@ #include <linux/compiler.h> -#include <linux/module.h> +#include <linux/init.h> +#include <linux/export.h> #include <linux/highmem.h> #include <linux/sched.h> #include <linux/smp.h> diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 72f7478ee068..3a6edecc3f38 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -10,7 +10,7 @@ */ #include <linux/bug.h> #include <linux/init.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/smp.h> diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 8d5008cbdc0f..1f189627440f 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c @@ -6,7 +6,7 @@ * (C) Copyright 1995 1996 Linus Torvalds * (C) Copyright 2001, 2002 Ralf Baechle */ -#include <linux/module.h> +#include <linux/export.h> #include <asm/addrspace.h> #include <asm/byteorder.h> #include <linux/sched.h> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index 353037699512..d08ea3ff0f53 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -10,7 +10,7 @@ #include <linux/errno.h> #include <linux/mm.h> #include <linux/mman.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/personality.h> #include <linux/random.h> #include <linux/sched.h> diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index c41953ca6605..6f804f5960ab 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c @@ -12,7 +12,6 @@ #include <linux/sched.h> #include <linux/smp.h> #include <linux/mm.h> -#include <linux/module.h> #include <linux/proc_fs.h> #include <asm/bugs.h> diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index e8b335c16295..bba9c1484b41 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -14,7 +14,7 @@ #include <linux/smp.h> #include <linux/mm.h> #include <linux/hugetlb.h> -#include <linux/module.h> +#include <linux/export.h> #include <asm/cpu.h> #include <asm/cpu-type.h> @@ -67,8 +67,11 @@ void local_flush_tlb_all(void) entry = read_c0_wired(); - /* Blast 'em all away. */ - if (cpu_has_tlbinv) { + /* + * Blast 'em all away. + * If there are any wired entries, fall back to iterating + */ + if (cpu_has_tlbinv && !entry) { if (current_cpu_data.tlbsizevtlb) { write_c0_index(0); mtc0_tlbw_hazard(); |