aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/include/asm/pgtable.h
diff options
context:
space:
mode:
authorJoshua Kinard <kumba@gentoo.org>2015-09-07 06:42:30 -0400
committerRalf Baechle <ralf@linux-mips.org>2016-05-09 12:00:05 +0200
commit128639395b2ceacc6a56a0141d0261012bfe04d3 (patch)
treed6f6e234b9b8fcc18c21a692fa437286cc9a8035 /arch/mips/include/asm/pgtable.h
parentMIPS: Move definitions for 32/64-bit agonstic inline assembler to new file. (diff)
downloadlinux-dev-128639395b2ceacc6a56a0141d0261012bfe04d3.tar.xz
linux-dev-128639395b2ceacc6a56a0141d0261012bfe04d3.zip
MIPS: Adjust set_pte() SMP fix to handle R10000_LLSC_WAR
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>
Diffstat (limited to 'arch/mips/include/asm/pgtable.h')
-rw-r--r--arch/mips/include/asm/pgtable.h45
1 files changed, 32 insertions, 13 deletions
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 25b1c1c08cbc..75c29cff0f99 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -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;