diff options
author | Joshua Kinard <kumba@gentoo.org> | 2015-09-07 12:42:30 +0200 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-05-09 12:00:05 +0200 |
commit | 128639395b2ceacc6a56a0141d0261012bfe04d3 (patch) | |
tree | d6f6e234b9b8fcc18c21a692fa437286cc9a8035 /arch/mips/include/asm/pgtable.h | |
parent | MIPS: Move definitions for 32/64-bit agonstic inline assembler to new file. (diff) | |
download | linux-128639395b2ceacc6a56a0141d0261012bfe04d3.tar.xz linux-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.h | 45 |
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; |