MIPS: mm: Be more explicit about PTE mode bit handling
authorPaul Burton <paul.burton@imgtec.com>
Tue, 19 Apr 2016 08:25:08 +0000 (09:25 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 13 May 2016 13:30:25 +0000 (15:30 +0200)
The XPA case in iPTE_SW or's in software mode bits to the pte_low value
(which is what actually ends up in the high 32 bits of EntryLo...). It
does this presuming that only bits in the upper 16 bits of the 32 bit
pte_low value will be set. Make this assumption explicit with a BUG_ON.

A similar assumption is made for the hardware mode bits, which are or'd
in with a single ori instruction. Make that assumption explicit with a
BUG_ON too.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/13122/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/mm/tlbex.c

index 2e9b436377432d09da706269877facc9bbd6c0db..6f20b42be97989020a8ff816d9fcc4f862b10477 100644 (file)
@@ -1641,15 +1641,17 @@ static void
 iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
        unsigned int mode, unsigned int scratch)
 {
-#ifdef CONFIG_PHYS_ADDR_T_64BIT
        unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
+       unsigned int swmode = mode & ~hwmode;
 
        if (config_enabled(CONFIG_XPA) && !cpu_has_64bits) {
-               uasm_i_lui(p, scratch, (mode >> 16));
+               uasm_i_lui(p, scratch, swmode >> 16);
                uasm_i_or(p, pte, pte, scratch);
-       } else
-#endif
-       uasm_i_ori(p, pte, pte, mode);
+               BUG_ON(swmode & 0xffff);
+       } else {
+               uasm_i_ori(p, pte, pte, mode);
+       }
+
 #ifdef CONFIG_SMP
 # ifdef CONFIG_PHYS_ADDR_T_64BIT
        if (cpu_has_64bits)
@@ -1668,6 +1670,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
                /* no uasm_i_nop needed */
                uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr);
                uasm_i_ori(p, pte, pte, hwmode);
+               BUG_ON(hwmode & ~0xffff);
                uasm_i_sc(p, pte, sizeof(pte_t) / 2, ptr);
                uasm_il_beqz(p, r, pte, label_smp_pgtable_change);
                /* no uasm_i_nop needed */
@@ -1689,6 +1692,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
        if (!cpu_has_64bits) {
                uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr);
                uasm_i_ori(p, pte, pte, hwmode);
+               BUG_ON(hwmode & ~0xffff);
                uasm_i_sw(p, pte, sizeof(pte_t) / 2, ptr);
                uasm_i_lw(p, pte, 0, ptr);
        }