summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Simek <michal.simek@xilinx.com>2016-01-13 19:37:25 +0100
committerMichal Simek <michal.simek@xilinx.com>2017-06-22 15:36:52 +0200
commita753499d43603d7b882cdd835aea9bc7183457fc (patch)
tree10fb2454da121a943580921b24a263464d86b4e3
parent83f0124ad81e87b74c2f461b1794e57ab5e7fea0 (diff)
microblaze: mm: Flush TLB to ensure correct mapping when higmem ON
MMU contains invalid mapping which wasn't flushed and new mapping is using the same addresses as previous one. That's why TLB miss is not happening to get new correct TLB entry and MMU points to incorrect area. This is replicatable when large files(256MB and more) are copied and checked. Signed-off-by: Michal Simek <michal.simek@xilinx.com>
-rw-r--r--arch/microblaze/mm/highmem.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/arch/microblaze/mm/highmem.c b/arch/microblaze/mm/highmem.c
index 2fcc5a52d84d..ed4454c5ce35 100644
--- a/arch/microblaze/mm/highmem.c
+++ b/arch/microblaze/mm/highmem.c
@@ -60,6 +60,7 @@ void __kunmap_atomic(void *kvaddr)
{
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
int type;
+ unsigned int idx;
if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
pagefault_enable();
@@ -68,21 +69,18 @@ void __kunmap_atomic(void *kvaddr)
}
type = kmap_atomic_idx();
-#ifdef CONFIG_DEBUG_HIGHMEM
- {
- unsigned int idx;
-
- idx = type + KM_TYPE_NR * smp_processor_id();
- BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
- /*
- * force other mappings to Oops if they'll try to access
- * this pte without first remap it
- */
- pte_clear(&init_mm, vaddr, kmap_pte-idx);
- local_flush_tlb_page(NULL, vaddr);
- }
+ idx = type + KM_TYPE_NR * smp_processor_id();
+#ifdef CONFIG_DEBUG_HIGHMEM
+ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
#endif
+ /*
+ * force other mappings to Oops if they'll try to access
+ * this pte without first remap it
+ */
+ pte_clear(&init_mm, vaddr, kmap_pte-idx);
+ local_flush_tlb_page(NULL, vaddr);
+
kmap_atomic_idx_pop();
pagefault_enable();
preempt_enable();