aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2016-04-19 04:25:10 -0400
committerRalf Baechle <ralf@linux-mips.org>2016-05-13 09:30:25 -0400
commit4b6f99d307ed6c7a28b952bfb7b66fb26a6a4cf0 (patch)
treeb3a82750ade7072f1c688d8232678ef51521adbb
parent2caa89b49b21737b2b7b6fce37cb323535188b06 (diff)
MIPS: mm: Don't do MTHC0 if XPA not present
Performing an MTHC0 instruction without XPA being present will trigger a reserved instruction exception, therefore conditionalise the use of this instruction when building TLB handlers (build_update_entries()), and in __update_tlb(). This allows an XPA kernel to run on non XPA hardware without that instruction implemented, just like it can run on XPA capable hardware without XPA in use (with the noxpa kernel argument) or with XPA not configured in hardware. [paul.burton@imgtec.com: - Rebase atop other TLB work. - Add "mm" to subject. - Handle the __kmap_pgprot case.] Fixes: c5b367835cfc ("MIPS: Add support for XPA.") Signed-off-by: James Hogan <james.hogan@imgtec.com> Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: David Hildenbrand <dahi@linux.vnet.ibm.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Jerome Marchand <jmarchan@redhat.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/13124/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/mm/init.c8
-rw-r--r--arch/mips/mm/tlb-r4k.c6
-rw-r--r--arch/mips/mm/tlbex.c16
3 files changed, 19 insertions, 11 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 134c988bc61f..9b58eb5fd0d5 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -112,9 +112,11 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
112 write_c0_entrylo0(entrylo); 112 write_c0_entrylo0(entrylo);
113 write_c0_entrylo1(entrylo); 113 write_c0_entrylo1(entrylo);
114#ifdef CONFIG_XPA 114#ifdef CONFIG_XPA
115 entrylo = (pte.pte_low & _PFNX_MASK); 115 if (cpu_has_xpa) {
116 writex_c0_entrylo0(entrylo); 116 entrylo = (pte.pte_low & _PFNX_MASK);
117 writex_c0_entrylo1(entrylo); 117 writex_c0_entrylo0(entrylo);
118 writex_c0_entrylo1(entrylo);
119 }
118#endif 120#endif
119 tlbidx = read_c0_wired(); 121 tlbidx = read_c0_wired();
120 write_c0_wired(tlbidx + 1); 122 write_c0_wired(tlbidx + 1);
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 61f1f1ba4a17..5a5c7fec645e 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -339,10 +339,12 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
339#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) 339#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
340#ifdef CONFIG_XPA 340#ifdef CONFIG_XPA
341 write_c0_entrylo0(pte_to_entrylo(ptep->pte_high)); 341 write_c0_entrylo0(pte_to_entrylo(ptep->pte_high));
342 writex_c0_entrylo0(ptep->pte_low & _PFNX_MASK); 342 if (cpu_has_xpa)
343 writex_c0_entrylo0(ptep->pte_low & _PFNX_MASK);
343 ptep++; 344 ptep++;
344 write_c0_entrylo1(pte_to_entrylo(ptep->pte_high)); 345 write_c0_entrylo1(pte_to_entrylo(ptep->pte_high));
345 writex_c0_entrylo1(ptep->pte_low & _PFNX_MASK); 346 if (cpu_has_xpa)
347 writex_c0_entrylo1(ptep->pte_low & _PFNX_MASK);
346#else 348#else
347 write_c0_entrylo0(ptep->pte_high); 349 write_c0_entrylo0(ptep->pte_high);
348 ptep++; 350 ptep++;
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 588bde3bdbe7..0efa6211cc40 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -1030,17 +1030,21 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
1030 UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); 1030 UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL));
1031 UASM_i_MTC0(p, tmp, C0_ENTRYLO0); 1031 UASM_i_MTC0(p, tmp, C0_ENTRYLO0);
1032 1032
1033 uasm_i_lw(p, tmp, 0, ptep); 1033 if (cpu_has_xpa && !mips_xpa_disabled) {
1034 uasm_i_ext(p, tmp, tmp, 0, 24); 1034 uasm_i_lw(p, tmp, 0, ptep);
1035 uasm_i_mthc0(p, tmp, C0_ENTRYLO0); 1035 uasm_i_ext(p, tmp, tmp, 0, 24);
1036 uasm_i_mthc0(p, tmp, C0_ENTRYLO0);
1037 }
1036 1038
1037 uasm_i_lw(p, tmp, pte_off_odd, ptep); /* odd pte */ 1039 uasm_i_lw(p, tmp, pte_off_odd, ptep); /* odd pte */
1038 UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); 1040 UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL));
1039 UASM_i_MTC0(p, tmp, C0_ENTRYLO1); 1041 UASM_i_MTC0(p, tmp, C0_ENTRYLO1);
1040 1042
1041 uasm_i_lw(p, tmp, sizeof(pte_t), ptep); 1043 if (cpu_has_xpa && !mips_xpa_disabled) {
1042 uasm_i_ext(p, tmp, tmp, 0, 24); 1044 uasm_i_lw(p, tmp, sizeof(pte_t), ptep);
1043 uasm_i_mthc0(p, tmp, C0_ENTRYLO1); 1045 uasm_i_ext(p, tmp, tmp, 0, 24);
1046 uasm_i_mthc0(p, tmp, C0_ENTRYLO1);
1047 }
1044 return; 1048 return;
1045 } 1049 }
1046 1050