From: Huacai Chen <chenhc@lemote.com>
To: Ralf Baechle <ralf@linux-mips.org>
Cc: John Crispin <john@phrozen.org>,
"Steven J . Hill" <Steven.Hill@cavium.com>,
linux-mips@linux-mips.org, Fuxin Zhang <zhangfx@lemote.com>,
Zhangjin Wu <wuzhangjin@gmail.com>,
Huacai Chen <chenhc@lemote.com>
Subject: [PATCH 8/8] MIPS: Loongson: Introduce and use WAR_LLSC_MB
Date: Thu, 10 Aug 2017 10:15:53 +0800 [thread overview]
Message-ID: <1502331353-17062-2-git-send-email-chenhc@lemote.com> (raw)
In-Reply-To: <1502331353-17062-1-git-send-email-chenhc@lemote.com>
On the Loongson-2G/2H/3A/3B there is a hardware flaw that ll/sc and
lld/scd is very weak ordering. We should add sync instructions before
each ll/lld and after the last sc/scd to workaround. Otherwise, this
flaw will cause deadlock occationally (e.g. when doing heavy load test
with LTP).
Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
arch/mips/include/asm/atomic.h | 18 ++++++++++++++++--
arch/mips/include/asm/barrier.h | 6 ++++++
arch/mips/include/asm/bitops.h | 15 +++++++++++++++
arch/mips/include/asm/cmpxchg.h | 9 +++++++--
arch/mips/include/asm/edac.h | 5 ++++-
arch/mips/include/asm/futex.h | 18 ++++++++++++------
arch/mips/include/asm/local.h | 10 ++++++++--
arch/mips/include/asm/pgtable.h | 5 ++++-
arch/mips/kernel/syscall.c | 2 ++
arch/mips/loongson64/Platform | 3 +++
arch/mips/mm/tlbex.c | 11 +++++++++++
11 files changed, 88 insertions(+), 14 deletions(-)
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index 0ab176b..99a6d01 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -62,6 +62,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \
do { \
__asm__ __volatile__( \
" .set "MIPS_ISA_LEVEL" \n" \
+ __WAR_LLSC_MB \
" ll %0, %1 # atomic_" #op "\n" \
" " #asm_op " %0, %2 \n" \
" sc %0, %1 \n" \
@@ -69,6 +70,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i)); \
} while (unlikely(!temp)); \
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory"); \
} else { \
unsigned long flags; \
\
@@ -103,6 +105,7 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \
do { \
__asm__ __volatile__( \
" .set "MIPS_ISA_LEVEL" \n" \
+ __WAR_LLSC_MB \
" ll %1, %2 # atomic_" #op "_return \n" \
" " #asm_op " %0, %1, %3 \n" \
" sc %0, %2 \n" \
@@ -151,6 +154,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
do { \
__asm__ __volatile__( \
" .set "MIPS_ISA_LEVEL" \n" \
+ __WAR_LLSC_MB \
" ll %1, %2 # atomic_fetch_" #op " \n" \
" " #asm_op " %0, %1, %3 \n" \
" sc %0, %2 \n" \
@@ -159,6 +163,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
"+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i)); \
} while (unlikely(!result)); \
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory"); \
\
result = temp; \
} else { \
@@ -242,7 +247,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
__asm__ __volatile__(
" .set "MIPS_ISA_LEVEL" \n"
- "1: ll %1, %2 # atomic_sub_if_positive\n"
+ "1: # atomic_sub_if_positive \n"
+ __WAR_LLSC_MB
+ " ll %1, %2 \n"
" subu %0, %1, %3 \n"
" bltz %0, 1f \n"
" sc %0, %2 \n"
@@ -404,6 +411,7 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v) \
do { \
__asm__ __volatile__( \
" .set "MIPS_ISA_LEVEL" \n" \
+ __WAR_LLSC_MB \
" lld %0, %1 # atomic64_" #op "\n" \
" " #asm_op " %0, %2 \n" \
" scd %0, %1 \n" \
@@ -411,6 +419,7 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v) \
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
: "Ir" (i)); \
} while (unlikely(!temp)); \
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory"); \
} else { \
unsigned long flags; \
\
@@ -445,6 +454,7 @@ static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \
do { \
__asm__ __volatile__( \
" .set "MIPS_ISA_LEVEL" \n" \
+ __WAR_LLSC_MB \
" lld %1, %2 # atomic64_" #op "_return\n" \
" " #asm_op " %0, %1, %3 \n" \
" scd %0, %2 \n" \
@@ -494,6 +504,7 @@ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v) \
do { \
__asm__ __volatile__( \
" .set "MIPS_ISA_LEVEL" \n" \
+ __WAR_LLSC_MB \
" lld %1, %2 # atomic64_fetch_" #op "\n" \
" " #asm_op " %0, %1, %3 \n" \
" scd %0, %2 \n" \
@@ -503,6 +514,7 @@ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v) \
: "Ir" (i), GCC_OFF_SMALL_ASM() (v->counter) \
: "memory"); \
} while (unlikely(!result)); \
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory"); \
\
result = temp; \
} else { \
@@ -587,7 +599,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
__asm__ __volatile__(
" .set "MIPS_ISA_LEVEL" \n"
- "1: lld %1, %2 # atomic64_sub_if_positive\n"
+ "1: # atomic64_sub_if_positive \n"
+ __WAR_LLSC_MB
+ " lld %1, %2 \n"
" dsubu %0, %1, %3 \n"
" bltz %0, 1f \n"
" scd %0, %2 \n"
diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
index a5eb1bb..d892094 100644
--- a/arch/mips/include/asm/barrier.h
+++ b/arch/mips/include/asm/barrier.h
@@ -203,6 +203,12 @@
#define __WEAK_LLSC_MB " \n"
#endif
+#if defined(CONFIG_LOONGSON3) && defined(CONFIG_SMP) /* Loongson-3's LLSC workaround */
+#define __WAR_LLSC_MB " sync \n"
+#else
+#define __WAR_LLSC_MB " \n"
+#endif
+
#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
#ifdef CONFIG_CPU_CAVIUM_OCTEON
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index fa57cef..7f39180 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -70,17 +70,20 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
do {
__asm__ __volatile__(
+ __WAR_LLSC_MB
" " __LL "%0, %1 # set_bit \n"
" " __INS "%0, %3, %2, 1 \n"
" " __SC "%0, %1 \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (bit), "r" (~0));
} while (unlikely(!temp));
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
} else if (kernel_uses_llsc) {
do {
__asm__ __volatile__(
" .set "MIPS_ISA_ARCH_LEVEL" \n"
+ __WAR_LLSC_MB
" " __LL "%0, %1 # set_bit \n"
" or %0, %2 \n"
" " __SC "%0, %1 \n"
@@ -88,6 +91,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (1UL << bit));
} while (unlikely(!temp));
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
} else
__mips_set_bit(nr, addr);
}
@@ -122,17 +126,20 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
do {
__asm__ __volatile__(
+ __WAR_LLSC_MB
" " __LL "%0, %1 # clear_bit \n"
" " __INS "%0, $0, %2, 1 \n"
" " __SC "%0, %1 \n"
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (bit));
} while (unlikely(!temp));
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
} else if (kernel_uses_llsc) {
do {
__asm__ __volatile__(
" .set "MIPS_ISA_ARCH_LEVEL" \n"
+ __WAR_LLSC_MB
" " __LL "%0, %1 # clear_bit \n"
" and %0, %2 \n"
" " __SC "%0, %1 \n"
@@ -140,6 +147,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (~(1UL << bit)));
} while (unlikely(!temp));
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
} else
__mips_clear_bit(nr, addr);
}
@@ -191,6 +199,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
do {
__asm__ __volatile__(
" .set "MIPS_ISA_ARCH_LEVEL" \n"
+ __WAR_LLSC_MB
" " __LL "%0, %1 # change_bit \n"
" xor %0, %2 \n"
" " __SC "%0, %1 \n"
@@ -198,6 +207,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
: "ir" (1UL << bit));
} while (unlikely(!temp));
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
} else
__mips_change_bit(nr, addr);
}
@@ -240,6 +250,7 @@ static inline int test_and_set_bit(unsigned long nr,
do {
__asm__ __volatile__(
" .set "MIPS_ISA_ARCH_LEVEL" \n"
+ __WAR_LLSC_MB
" " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
@@ -294,6 +305,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
do {
__asm__ __volatile__(
" .set "MIPS_ISA_ARCH_LEVEL" \n"
+ __WAR_LLSC_MB
" " __LL "%0, %1 # test_and_set_bit \n"
" or %2, %0, %3 \n"
" " __SC "%2, %1 \n"
@@ -350,6 +362,7 @@ static inline int test_and_clear_bit(unsigned long nr,
do {
__asm__ __volatile__(
+ __WAR_LLSC_MB
" " __LL "%0, %1 # test_and_clear_bit \n"
" " __EXT "%2, %0, %3, 1 \n"
" " __INS "%0, $0, %3, 1 \n"
@@ -366,6 +379,7 @@ static inline int test_and_clear_bit(unsigned long nr,
do {
__asm__ __volatile__(
" .set "MIPS_ISA_ARCH_LEVEL" \n"
+ __WAR_LLSC_MB
" " __LL "%0, %1 # test_and_clear_bit \n"
" or %2, %0, %3 \n"
" xor %2, %3 \n"
@@ -423,6 +437,7 @@ static inline int test_and_change_bit(unsigned long nr,
do {
__asm__ __volatile__(
" .set "MIPS_ISA_ARCH_LEVEL" \n"
+ __WAR_LLSC_MB
" " __LL "%0, %1 # test_and_change_bit \n"
" xor %2, %0, %3 \n"
" " __SC "\t%2, %1 \n"
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h
index 903f3bf..744723e 100644
--- a/arch/mips/include/asm/cmpxchg.h
+++ b/arch/mips/include/asm/cmpxchg.h
@@ -48,7 +48,9 @@ extern unsigned long __xchg_called_with_bad_pointer(void)
" .set push \n" \
" .set noat \n" \
" .set " MIPS_ISA_ARCH_LEVEL " \n" \
- "1: " ld " %0, %2 # __xchg_asm \n" \
+ "1: # __xchg_asm \n" \
+ __WAR_LLSC_MB \
+ " " ld " %0, %2 \n" \
" .set mips0 \n" \
" move $1, %z3 \n" \
" .set " MIPS_ISA_ARCH_LEVEL " \n" \
@@ -118,7 +120,9 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
" .set push \n" \
" .set noat \n" \
" .set "MIPS_ISA_ARCH_LEVEL" \n" \
- "1: " ld " %0, %2 # __cmpxchg_asm \n" \
+ "1: # __cmpxchg_asm \n" \
+ __WAR_LLSC_MB \
+ " " ld " %0, %2 \n" \
" bne %0, %z3, 2f \n" \
" .set mips0 \n" \
" move $1, %z4 \n" \
@@ -127,6 +131,7 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
"\t" __scbeqz " $1, 1b \n" \
" .set pop \n" \
"2: \n" \
+ __WAR_LLSC_MB \
: "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \
: GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \
: "memory"); \
diff --git a/arch/mips/include/asm/edac.h b/arch/mips/include/asm/edac.h
index 980b165..ecf1a76 100644
--- a/arch/mips/include/asm/edac.h
+++ b/arch/mips/include/asm/edac.h
@@ -21,13 +21,16 @@ static inline void edac_atomic_scrub(void *va, u32 size)
__asm__ __volatile__ (
" .set mips2 \n"
- "1: ll %0, %1 # edac_atomic_scrub \n"
+ "1: # edac_atomic_scrub \n"
+ __WAR_LLSC_MB
+ " ll %0, %1 \n"
" addu %0, $0 \n"
" sc %0, %1 \n"
" beqz %0, 1b \n"
" .set mips0 \n"
: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*virt_addr)
: GCC_OFF_SMALL_ASM() (*virt_addr));
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
virt_addr++;
}
diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h
index 1de190b..39a3566 100644
--- a/arch/mips/include/asm/futex.h
+++ b/arch/mips/include/asm/futex.h
@@ -54,7 +54,9 @@
" .set push \n" \
" .set noat \n" \
" .set "MIPS_ISA_ARCH_LEVEL" \n" \
- "1: "user_ll("%1", "%4")" # __futex_atomic_op\n" \
+ "1: # __futex_atomic_op\n" \
+ __WAR_LLSC_MB \
+ " "user_ll("%1", "%4")" \n" \
" .set mips0 \n" \
" " insn " \n" \
" .set "MIPS_ISA_ARCH_LEVEL" \n" \
@@ -70,8 +72,9 @@
" j 3b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
- " "__UA_ADDR "\t1b, 4b \n" \
- " "__UA_ADDR "\t2b, 4b \n" \
+ " "__UA_ADDR "\t(1b + 0), 4b \n" \
+ " "__UA_ADDR "\t(1b + 4), 4b \n" \
+ " "__UA_ADDR "\t(2b + 0), 4b \n" \
" .previous \n" \
: "=r" (ret), "=&r" (oldval), \
"=" GCC_OFF_SMALL_ASM() (*uaddr) \
@@ -184,7 +187,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
" .set push \n"
" .set noat \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
- "1: "user_ll("%1", "%3")" \n"
+ "1: \n"
+ __WAR_LLSC_MB
+ " "user_ll("%1", "%3")" \n"
" bne %1, %z4, 3f \n"
" .set mips0 \n"
" move $1, %z5 \n"
@@ -200,8 +205,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
" j 3b \n"
" .previous \n"
" .section __ex_table,\"a\" \n"
- " "__UA_ADDR "\t1b, 4b \n"
- " "__UA_ADDR "\t2b, 4b \n"
+ " "__UA_ADDR "\t(1b + 0), 4b \n"
+ " "__UA_ADDR "\t(1b + 4), 4b \n"
+ " "__UA_ADDR "\t(2b + 0), 4b \n"
" .previous \n"
: "+r" (ret), "=&r" (val), "=" GCC_OFF_SMALL_ASM() (*uaddr)
: GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h
index 8feaed6..9ba7a54 100644
--- a/arch/mips/include/asm/local.h
+++ b/arch/mips/include/asm/local.h
@@ -49,7 +49,9 @@ static __inline__ long local_add_return(long i, local_t * l)
__asm__ __volatile__(
" .set "MIPS_ISA_ARCH_LEVEL" \n"
- "1:" __LL "%1, %2 # local_add_return \n"
+ "1: # local_add_return \n"
+ __WAR_LLSC_MB
+ __LL "%1, %2 \n"
" addu %0, %1, %3 \n"
__SC "%0, %2 \n"
" beqz %0, 1b \n"
@@ -58,6 +60,7 @@ static __inline__ long local_add_return(long i, local_t * l)
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
: "Ir" (i), "m" (l->a.counter)
: "memory");
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
} else {
unsigned long flags;
@@ -94,7 +97,9 @@ static __inline__ long local_sub_return(long i, local_t * l)
__asm__ __volatile__(
" .set "MIPS_ISA_ARCH_LEVEL" \n"
- "1:" __LL "%1, %2 # local_sub_return \n"
+ "1: # local_sub_return \n"
+ __WAR_LLSC_MB
+ __LL "%1, %2 \n"
" subu %0, %1, %3 \n"
__SC "%0, %2 \n"
" beqz %0, 1b \n"
@@ -103,6 +108,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
: "Ir" (i), "m" (l->a.counter)
: "memory");
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
} else {
unsigned long flags;
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 9e9e944..8af0dac 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -233,7 +233,9 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" .set push \n"
" .set noreorder \n"
- "1:" __LL "%[tmp], %[buddy] \n"
+ "1: \n"
+ __WAR_LLSC_MB
+ __LL "%[tmp], %[buddy] \n"
" bnez %[tmp], 2f \n"
" or %[tmp], %[tmp], %[global] \n"
__SC "%[tmp], %[buddy] \n"
@@ -244,6 +246,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
" .set mips0 \n"
: [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
: [global] "r" (page_global));
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
}
#else /* !CONFIG_SMP */
if (pte_none(*buddy))
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 58c6f63..342fbff 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -133,6 +133,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
" .set "MIPS_ISA_ARCH_LEVEL" \n"
" li %[err], 0 \n"
"1: \n"
+ __WAR_LLSC_MB
user_ll("%[old]", "(%[addr])")
" move %[tmp], %[new] \n"
"2: \n"
@@ -156,6 +157,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
[new] "r" (new),
[efault] "i" (-EFAULT)
: "memory");
+ __asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
} else {
do {
preempt_disable();
diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform
index 0fce460..3700dcf 100644
--- a/arch/mips/loongson64/Platform
+++ b/arch/mips/loongson64/Platform
@@ -23,6 +23,9 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
endif
cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap
+ifneq ($(call as-option,-Wa$(comma)-mfix-loongson3-llsc,),)
+ cflags-$(CONFIG_CPU_LOONGSON3) += -Wa$(comma)-mno-fix-loongson3-llsc
+endif
#
# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
# as MIPS64 R2; older versions as just R1. This leaves the possibility open
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 5aadc69..b05e734 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -935,6 +935,8 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
* to mimic that here by taking a load/istream page
* fault.
*/
+ if (current_cpu_type() == CPU_LOONGSON3)
+ uasm_i_sync(p, 0);
UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
uasm_i_jr(p, ptr);
@@ -1560,6 +1562,7 @@ static void build_loongson3_tlb_refill_handler(void)
if (check_for_high_segbits) {
uasm_l_large_segbits_fault(&l, p);
+ uasm_i_sync(&p, 0);
UASM_i_LA(&p, K1, (unsigned long)tlb_do_page_fault_0);
uasm_i_jr(&p, K1);
uasm_i_nop(&p);
@@ -1660,6 +1663,8 @@ static void
iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
{
#ifdef CONFIG_SMP
+ if (current_cpu_type() == CPU_LOONGSON3)
+ uasm_i_sync(p, 0);
# ifdef CONFIG_PHYS_ADDR_T_64BIT
if (cpu_has_64bits)
uasm_i_lld(p, pte, 0, ptr);
@@ -2277,6 +2282,8 @@ static void build_r4000_tlb_load_handler(void)
#endif
uasm_l_nopage_tlbl(&l, p);
+ if (current_cpu_type() == CPU_LOONGSON3)
+ uasm_i_sync(&p, 0);
build_restore_work_registers(&p);
#ifdef CONFIG_CPU_MICROMIPS
if ((unsigned long)tlb_do_page_fault_0 & 1) {
@@ -2332,6 +2339,8 @@ static void build_r4000_tlb_store_handler(void)
#endif
uasm_l_nopage_tlbs(&l, p);
+ if (current_cpu_type() == CPU_LOONGSON3)
+ uasm_i_sync(&p, 0);
build_restore_work_registers(&p);
#ifdef CONFIG_CPU_MICROMIPS
if ((unsigned long)tlb_do_page_fault_1 & 1) {
@@ -2388,6 +2397,8 @@ static void build_r4000_tlb_modify_handler(void)
#endif
uasm_l_nopage_tlbm(&l, p);
+ if (current_cpu_type() == CPU_LOONGSON3)
+ uasm_i_sync(&p, 0);
build_restore_work_registers(&p);
#ifdef CONFIG_CPU_MICROMIPS
if ((unsigned long)tlb_do_page_fault_1 & 1) {
--
2.7.0
prev parent reply other threads:[~2017-08-10 2:17 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-10 2:00 [PATCH 0/8] MIPS: Loongson: new features and improvements Huacai Chen
2017-08-10 2:00 ` [PATCH 1/8] MIPS: Loongson-3: Enable Store Fill Buffer at runtime Huacai Chen
2018-01-24 20:54 ` James Hogan
2017-08-10 2:04 ` [PATCH 2/8] MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3 Huacai Chen
2017-08-10 2:04 ` [PATCH 3/8] MIPS: Ensure pmd_present() returns false after pmd_mknotpresent() Huacai Chen
2018-01-24 21:47 ` James Hogan
2017-08-10 2:04 ` [PATCH 4/8] MIPS: Add __cpu_full_name[] to make CPU names more human-readable Huacai Chen
2018-01-24 22:14 ` James Hogan
2017-08-10 2:04 ` [PATCH 5/8] MIPS: Align kernel load address to 64KB Huacai Chen
2017-08-10 2:04 ` [PATCH 6/8] MIPS: Loongson: Add kexec/kdump support Huacai Chen
2018-01-24 21:22 ` [PATCH 2/8] MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3 James Hogan
2017-08-10 2:15 ` [PATCH 7/8] MIPS: Loongson: Make CPUFreq usable " Huacai Chen
2017-08-10 2:15 ` Huacai Chen [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1502331353-17062-2-git-send-email-chenhc@lemote.com \
--to=chenhc@lemote.com \
--cc=Steven.Hill@cavium.com \
--cc=john@phrozen.org \
--cc=linux-mips@linux-mips.org \
--cc=ralf@linux-mips.org \
--cc=wuzhangjin@gmail.com \
--cc=zhangfx@lemote.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox