From 5b167c123b3c3582f62cf1896465019bc40fe526 Mon Sep 17 00:00:00 2001 From: Kamal Dasu Date: Fri, 14 Jun 2013 17:10:03 +0000 Subject: MIPS: Fix get_user_page_fast() for mips with cache alias get_user_pages_fast() is missing cache flushes for MIPS platforms with cache aliases. Filesystem failures observed with DirectIO operations due to missing flush_anon_page() that use page coloring logic to work with cache aliases. This fix falls through to take slow_irqon path that calls get_user_pages() that has required logic for platforms where cpu_has_dc_aliases is true. [ralf@linux-mips.org: Explicity include .] Signed-off-by: Kamal Dasu Cc: linux-mips@linux-mips.org Patchwork: http://patchwork.linux-mips.org/patch/5469/ Signed-off-by: Ralf Baechle --- arch/mips/mm/gup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/mips/mm') diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c index d4ea5c9c4a93..06ce17c2a905 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c @@ -12,6 +12,7 @@ #include #include +#include #include static inline pte_t gup_get_pte(pte_t *ptep) @@ -273,7 +274,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if (end < start) + if (end < start || cpu_has_dc_aliases) goto slow_irqon; /* XXX: batch / limit 'nr' */ -- cgit v1.2.3-58-ga151 From 774b6175f8f6547e2e7d4cf8b5fa60a01f39b03e Mon Sep 17 00:00:00 2001 From: Tony Wu Date: Thu, 18 Jul 2013 09:47:37 +0000 Subject: MIPS: tlbex: Guard tlbmiss_handler_setup_pgd tlbmiss_handler_setup_pgd* are only referenced when CONFIG_MIPS_PGD_C0_CONTEXT is defined. Signed-off-by: Tony Wu Cc: Jayachandran C. Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/5601/ Signed-off-by: Ralf Baechle --- arch/mips/mm/tlb-funcs.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/mips/mm') diff --git a/arch/mips/mm/tlb-funcs.S b/arch/mips/mm/tlb-funcs.S index 30a494db99c2..79bca3130bd1 100644 --- a/arch/mips/mm/tlb-funcs.S +++ b/arch/mips/mm/tlb-funcs.S @@ -16,10 +16,12 @@ #define FASTPATH_SIZE 128 +#ifdef CONFIG_MIPS_PGD_C0_CONTEXT LEAF(tlbmiss_handler_setup_pgd) .space 16 * 4 END(tlbmiss_handler_setup_pgd) EXPORT(tlbmiss_handler_setup_pgd_end) +#endif LEAF(handle_tlbm) .space FASTPATH_SIZE * 4 -- cgit v1.2.3-58-ga151 From 4723b20a381ae488d845f3e041ef1dd71c6f40f8 Mon Sep 17 00:00:00 2001 From: David Daney Date: Mon, 29 Jul 2013 15:07:03 -0700 Subject: MIPS: Generate OCTEON3 TLB handlers with the same features as OCTEON2. OCTEON2 need the same code. Signed-off-by: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/5637/ Signed-off-by: Ralf Baechle --- arch/mips/mm/tlbex.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/mips/mm') diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 556cb4815770..821b45175dc1 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -85,6 +85,7 @@ static int use_bbit_insns(void) case CPU_CAVIUM_OCTEON: case CPU_CAVIUM_OCTEON_PLUS: case CPU_CAVIUM_OCTEON2: + case CPU_CAVIUM_OCTEON3: return 1; default: return 0; @@ -95,6 +96,7 @@ static int use_lwx_insns(void) { switch (current_cpu_type()) { case CPU_CAVIUM_OCTEON2: + case CPU_CAVIUM_OCTEON3: return 1; default: return 0; -- cgit v1.2.3-58-ga151 From 62597c60816967100243338421782469b831563d Mon Sep 17 00:00:00 2001 From: David Daney Date: Mon, 29 Jul 2013 15:07:04 -0700 Subject: MIPS: OCTEON: Set L1 cache parameters for OCTEON3 CPUs. Signed-off-by: David Daney Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/5638/ Signed-off-by: Ralf Baechle --- arch/mips/mm/c-octeon.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch/mips/mm') diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c index a0bcdbb81d41..729e7702b1de 100644 --- a/arch/mips/mm/c-octeon.c +++ b/arch/mips/mm/c-octeon.c @@ -224,6 +224,20 @@ static void probe_octeon(void) c->options |= MIPS_CPU_PREFETCH; break; + case CPU_CAVIUM_OCTEON3: + c->icache.linesz = 128; + c->icache.sets = 16; + c->icache.ways = 39; + c->icache.flags |= MIPS_CACHE_VTAG; + icache_size = c->icache.sets * c->icache.ways * c->icache.linesz; + + c->dcache.linesz = 128; + c->dcache.ways = 32; + c->dcache.sets = 8; + dcache_size = c->dcache.sets * c->dcache.ways * c->dcache.linesz; + c->options |= MIPS_CPU_PREFETCH; + break; + default: panic("Unsupported Cavium Networks CPU type"); break; -- cgit v1.2.3-58-ga151 From f86f55d3ad21b21b736bdeb29bee0f0937b77138 Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Tue, 27 Aug 2013 16:57:51 -0400 Subject: MIPS: DMA: For BMIPS5000 cores flush region just like non-coherent R10000 The BMIPS5000 (Zephyr) processor utilizes instruction speculation. A stale misprediction address in either the JTB or the CRS may trigger a prefetch inside a region that is currently being used by a DMA engine, which is not IO-coherent. This prefetch will fetch a line into the scache, and that line will soon become stale (ie wrong) during/after the DMA. Mayhem ensues. In dma-default.c, the r10000 is handled as a special case in the same way that we want to handle Zephyr. So we generalize the exception cases into a function, and include Zephyr as one of the processors that needs this special care. Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: cernekee@gmail.com Patchwork: https://patchwork.linux-mips.org/patch/5776/ Signed-off-by: Ralf Baechle --- arch/mips/mm/dma-default.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'arch/mips/mm') diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index aaccf1c10699..468f7f967f97 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -50,16 +50,20 @@ static inline struct page *dma_addr_to_page(struct device *dev, } /* + * The affected CPUs below in 'cpu_needs_post_dma_flush()' can + * speculatively fill random cachelines with stale data at any time, + * requiring an extra flush post-DMA. + * * Warning on the terminology - Linux calls an uncached area coherent; * MIPS terminology calls memory areas with hardware maintained coherency * coherent. */ - -static inline int cpu_is_noncoherent_r10000(struct device *dev) +static inline int cpu_needs_post_dma_flush(struct device *dev) { return !plat_device_is_coherent(dev) && (current_cpu_type() == CPU_R10000 || - current_cpu_type() == CPU_R12000); + current_cpu_type() == CPU_R12000 || + current_cpu_type() == CPU_BMIPS5000); } static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) @@ -230,7 +234,7 @@ static inline void __dma_sync(struct page *page, static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs) { - if (cpu_is_noncoherent_r10000(dev)) + if (cpu_needs_post_dma_flush(dev)) __dma_sync(dma_addr_to_page(dev, dma_addr), dma_addr & ~PAGE_MASK, size, direction); @@ -284,7 +288,7 @@ static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg, static void mips_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { - if (cpu_is_noncoherent_r10000(dev)) + if (cpu_needs_post_dma_flush(dev)) __dma_sync(dma_addr_to_page(dev, dma_handle), dma_handle & ~PAGE_MASK, size, direction); } @@ -305,7 +309,7 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev, /* Make sure that gcc doesn't leave the empty loop body. */ for (i = 0; i < nelems; i++, sg++) { - if (cpu_is_noncoherent_r10000(dev)) + if (cpu_needs_post_dma_flush(dev)) __dma_sync(sg_page(sg), sg->offset, sg->length, direction); } -- cgit v1.2.3-58-ga151 From bf9621aaa0bb94dcd3b198ca14d3220310655eea Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 5 Sep 2013 11:22:45 +0200 Subject: MIPS: Export copy_from_user_page() (needed by lustre) ERROR: "copy_from_user_page" [drivers/staging/lustre/lustre/libcfs/libcfs.ko] undefined! Signed-off-by: Geert Uytterhoeven Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/5808/ Signed-off-by: Ralf Baechle --- arch/mips/mm/init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/mips/mm') diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 4e73f10a7519..e205ef598e97 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -254,6 +254,7 @@ void copy_from_user_page(struct vm_area_struct *vma, SetPageDcacheDirty(page); } } +EXPORT_SYMBOL_GPL(copy_from_user_page); void __init fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base) -- cgit v1.2.3-58-ga151 From d451e73496fc389ecbe2662aa07e6b77c63bf1fd Mon Sep 17 00:00:00 2001 From: Jerin Jacob Date: Tue, 3 Sep 2013 17:31:54 +0530 Subject: MIPS: DMA: Fix BUG due to smp_processor_id() in preemptible code The use of current_cpu_type() in cpu_is_noncoherent_r10000() is not preemption-safe. Use boot_cpu_type() instead to make it preemption-safe. / # insmod mtd_readtest.ko dev=4 mtd_readtest: MTD device: 4 mtd_readtest: MTD device size 996671488, eraseblock size 524288, page size 4096, count of eraseblocks 1901, pages per eraseblock 128, OOB size 224 mtd_readtest: scanning for bad eraseblocks mtd_readtest: scanned 1901 eraseblocks, 0 are bad mtd_readtest: testing page read BUG: using smp_processor_id() in preemptible [00000000] code: insmod/99 caller is mips_dma_sync_single_for_cpu+0x2c/0x128 CPU: 2 PID: 99 Comm: insmod Not tainted 3.10.4 #67 Stack : 00000006 69735f63 00000000 00000000 00000000 00000000 808273d6 00000032 80820000 00000002 8d700000 8de48fa0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8d6afb00 8d6afb24 80721f24 807b9927 8012c130 80820000 80721f24 00000002 00000063 8de48fa0 8082333c 807b98e6 8d6afaa0 ... Call Trace: [<80109984>] show_stack+0x64/0x7c [<80666230>] dump_stack+0x20/0x2c [<803a2210>] debug_smp_processor_id+0xe0/0xf0 [<801116f0>] mips_dma_sync_single_for_cpu+0x2c/0x128 [<8043456c>] nand_plat_read_page+0x16c/0x234 [<8042fad4>] nand_do_read_ops+0x194/0x480 [<804301dc>] nand_read+0x50/0x7c [<804261c8>] part_read+0x70/0xc0 [<804231dc>] mtd_read+0x80/0xe4 [] init_module+0x354/0x6f8 [mtd_readtest] [<8010057c>] do_one_initcall+0x140/0x1a4 [<80176d7c>] load_module+0x1b5c/0x2258 [<8017752c>] SyS_init_module+0xb4/0xec [<8010f3fc>] stack_done+0x20/0x44 BUG: using smp_processor_id() in preemptible [00000000] code: insmod/99 Signed-off-by: Jerin Jacob Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/5800/ Signed-off-by: Ralf Baechle --- arch/mips/mm/dma-default.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/mips/mm') diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index aaccf1c10699..2f26835803eb 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -58,8 +58,8 @@ static inline struct page *dma_addr_to_page(struct device *dev, static inline int cpu_is_noncoherent_r10000(struct device *dev) { return !plat_device_is_coherent(dev) && - (current_cpu_type() == CPU_R10000 || - current_cpu_type() == CPU_R12000); + (boot_cpu_type() == CPU_R10000 || + boot_cpu_type() == CPU_R12000); } static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) -- cgit v1.2.3-58-ga151