MIPS: Adjust set_pte() SMP fix to handle R10000_LLSC_WAR
authorJoshua Kinard <kumba@gentoo.org>
Mon, 7 Sep 2015 10:42:30 +0000 (06:42 -0400)
committerRalf Baechle <ralf@linux-mips.org>
Mon, 9 May 2016 10:00:05 +0000 (12:00 +0200)
Update the recent changes to set_pte() that were added in 46011e6ea392
to handle R10000_LLSC_WAR, and format the assembly to match other areas
of the MIPS tree using the same WAR.

This also incorporates a patch recently sent in my Markos Chandras,
"Remove local LL/SC preprocessor variants", so that patch doesn't need
to be applied if this one is accepted.

Signed-off-by: Joshua Kinard <kumba@gentoo.org>
Fixes: 46011e6ea392 ("MIPS: Make set_pte() SMP safe.)
Cc: David Daney <david.daney@cavium.com>
Cc: Linux/MIPS <linux-mips@linux-mips.org>
Patchwork: https://patchwork.linux-mips.org/patch/11103/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/pgtable.h

index 25b1c1c08cbc21ec9a3e10ff10a1567aeff2359b..75c29cff0f992758cec2c66c38961795f5962773 100644 (file)
@@ -190,20 +190,39 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
                unsigned long page_global = _PAGE_GLOBAL;
                unsigned long tmp;
 
-               __asm__ __volatile__ (
-                       "       .set    push\n"
-                       "       .set    noreorder\n"
-                       "1:     " __LL "        %[tmp], %[buddy]\n"
-                       "       bnez    %[tmp], 2f\n"
-                       "        or     %[tmp], %[tmp], %[global]\n"
-                       "       " __SC "        %[tmp], %[buddy]\n"
-                       "       beqz    %[tmp], 1b\n"
-                       "        nop\n"
-                       "2:\n"
-                       "       .set pop"
-                       : [buddy] "+m" (buddy->pte),
-                         [tmp] "=&r" (tmp)
+               if (kernel_uses_llsc && R10000_LLSC_WAR) {
+                       __asm__ __volatile__ (
+                       "       .set    arch=r4000                      \n"
+                       "       .set    push                            \n"
+                       "       .set    noreorder                       \n"
+                       "1:"    __LL    "%[tmp], %[buddy]               \n"
+                       "       bnez    %[tmp], 2f                      \n"
+                       "        or     %[tmp], %[tmp], %[global]       \n"
+                               __SC    "%[tmp], %[buddy]               \n"
+                       "       beqzl   %[tmp], 1b                      \n"
+                       "       nop                                     \n"
+                       "2:                                             \n"
+                       "       .set    pop                             \n"
+                       "       .set    mips0                           \n"
+                       : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
                        : [global] "r" (page_global));
+               } else if (kernel_uses_llsc) {
+                       __asm__ __volatile__ (
+                       "       .set    "MIPS_ISA_ARCH_LEVEL"           \n"
+                       "       .set    push                            \n"
+                       "       .set    noreorder                       \n"
+                       "1:"    __LL    "%[tmp], %[buddy]               \n"
+                       "       bnez    %[tmp], 2f                      \n"
+                       "        or     %[tmp], %[tmp], %[global]       \n"
+                               __SC    "%[tmp], %[buddy]               \n"
+                       "       beqz    %[tmp], 1b                      \n"
+                       "       nop                                     \n"
+                       "2:                                             \n"
+                       "       .set    pop                             \n"
+                       "       .set    mips0                           \n"
+                       : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
+                       : [global] "r" (page_global));
+               }
 #else /* !CONFIG_SMP */
                if (pte_none(*buddy))
                        pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;