aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-02-09 15:41:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-02-09 15:41:14 -0500
commite8b50608f666cf5c314a9df3dc4b85789a6aeaa5 (patch)
tree880ece253ca5ef6bc27dc2e5fd2fb0e338259eab
parente5a8a1163211e2ab6f71c3545b26d55dc99ff1d3 (diff)
parent05dc6001af0630e200ad5ea08707187fe5537e6d (diff)
Merge tag 'mips_fixes_5.0_3' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
Pull MIPS fixes from Paul Burton: "A batch of MIPS fixes for 5.0, nothing too scary. - A workaround for a Loongson 3 CPU bug is the biggest change, but still fairly straightforward. It adds extra memory barriers (sync instructions) around atomics to avoid a CPU bug that can break atomicity. - Loongson64 also sees a fix for powering off some systems which would incorrectly reboot rather than waiting for the power down sequence to complete. - We have DT fixes for the Ingenic JZ4740 SoC & the JZ4780-based Ci20 board, and a DT warning fix for the Nexsys4/MIPSfpga board. - The Cavium Octeon platform sees a further fix to the behaviour of the pcie_disable command line argument that was introduced in v3.3. - The VDSO, introduced in v4.4, sees build fixes for configurations of GCC that were built using the --with-fp-32= flag to specify a default 32-bit floating point ABI. - get_frame_info() sees a fix for configurations with CONFIG_KALLSYMS=n, for which it previously always returned an error. - If the MIPS Coherence Manager (CM) reports an error then we'll now clear that error correctly so that the GCR_ERROR_CAUSE register will be updated with information about any future errors" * tag 'mips_fixes_5.0_3' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: mips: cm: reprime error cause mips: loongson64: remove unreachable(), fix loongson_poweroff(). MIPS: Remove function size check in get_frame_info() MIPS: Use lower case for addresses in nexys4ddr.dts MIPS: Loongson: Introduce and use loongson_llsc_mb() MIPS: VDSO: Include $(ccflags-vdso) in o32,n32 .lds builds MIPS: VDSO: Use same -m%-float cflag as the kernel proper MIPS: OCTEON: don't set octeon_dma_bar_type if PCI is disabled DTS: CI20: Fix bugs in ci20's device tree. MIPS: DTS: jz4740: Correct interrupt number of DMA core
-rw-r--r--arch/mips/Kconfig15
-rw-r--r--arch/mips/boot/dts/ingenic/ci20.dts8
-rw-r--r--arch/mips/boot/dts/ingenic/jz4740.dtsi2
-rw-r--r--arch/mips/boot/dts/xilfpga/nexys4ddr.dts8
-rw-r--r--arch/mips/include/asm/atomic.h6
-rw-r--r--arch/mips/include/asm/barrier.h36
-rw-r--r--arch/mips/include/asm/bitops.h5
-rw-r--r--arch/mips/include/asm/futex.h3
-rw-r--r--arch/mips/include/asm/pgtable.h2
-rw-r--r--arch/mips/kernel/mips-cm.c2
-rw-r--r--arch/mips/kernel/process.c7
-rw-r--r--arch/mips/loongson64/Platform23
-rw-r--r--arch/mips/loongson64/common/reset.c7
-rw-r--r--arch/mips/mm/tlbex.c10
-rw-r--r--arch/mips/pci/pci-octeon.c10
-rw-r--r--arch/mips/vdso/Makefile5
16 files changed, 127 insertions, 22 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 0d14f51d0002..a84c24d894aa 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1403,6 +1403,21 @@ config LOONGSON3_ENHANCEMENT
1403 please say 'N' here. If you want a high-performance kernel to run on 1403 please say 'N' here. If you want a high-performance kernel to run on
1404 new Loongson 3 machines only, please say 'Y' here. 1404 new Loongson 3 machines only, please say 'Y' here.
1405 1405
1406config CPU_LOONGSON3_WORKAROUNDS
1407 bool "Old Loongson 3 LLSC Workarounds"
1408 default y if SMP
1409 depends on CPU_LOONGSON3
1410 help
1411 Loongson 3 processors have the llsc issues which require workarounds.
1412 Without workarounds the system may hang unexpectedly.
1413
1414 Newer Loongson 3 will fix these issues and no workarounds are needed.
1415 The workarounds have no significant side effect on them but may
1416 decrease the performance of the system so this option should be
1417 disabled unless the kernel is intended to be run on old systems.
1418
1419 If unsure, please say Y.
1420
1406config CPU_LOONGSON2E 1421config CPU_LOONGSON2E
1407 bool "Loongson 2E" 1422 bool "Loongson 2E"
1408 depends on SYS_HAS_CPU_LOONGSON2E 1423 depends on SYS_HAS_CPU_LOONGSON2E
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
index 50cff3cbcc6d..4f7b1fa31cf5 100644
--- a/arch/mips/boot/dts/ingenic/ci20.dts
+++ b/arch/mips/boot/dts/ingenic/ci20.dts
@@ -76,7 +76,7 @@
76 status = "okay"; 76 status = "okay";
77 77
78 pinctrl-names = "default"; 78 pinctrl-names = "default";
79 pinctrl-0 = <&pins_uart2>; 79 pinctrl-0 = <&pins_uart3>;
80}; 80};
81 81
82&uart4 { 82&uart4 {
@@ -196,9 +196,9 @@
196 bias-disable; 196 bias-disable;
197 }; 197 };
198 198
199 pins_uart2: uart2 { 199 pins_uart3: uart3 {
200 function = "uart2"; 200 function = "uart3";
201 groups = "uart2-data", "uart2-hwflow"; 201 groups = "uart3-data", "uart3-hwflow";
202 bias-disable; 202 bias-disable;
203 }; 203 };
204 204
diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi
index 6fb16fd24035..2beb78a62b7d 100644
--- a/arch/mips/boot/dts/ingenic/jz4740.dtsi
+++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi
@@ -161,7 +161,7 @@
161 #dma-cells = <2>; 161 #dma-cells = <2>;
162 162
163 interrupt-parent = <&intc>; 163 interrupt-parent = <&intc>;
164 interrupts = <29>; 164 interrupts = <20>;
165 165
166 clocks = <&cgu JZ4740_CLK_DMA>; 166 clocks = <&cgu JZ4740_CLK_DMA>;
167 167
diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
index 2152b7ba65fb..cc8dbea0911f 100644
--- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
+++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts
@@ -90,11 +90,11 @@
90 interrupts = <0>; 90 interrupts = <0>;
91 }; 91 };
92 92
93 axi_i2c: i2c@10A00000 { 93 axi_i2c: i2c@10a00000 {
94 compatible = "xlnx,xps-iic-2.00.a"; 94 compatible = "xlnx,xps-iic-2.00.a";
95 interrupt-parent = <&axi_intc>; 95 interrupt-parent = <&axi_intc>;
96 interrupts = <4>; 96 interrupts = <4>;
97 reg = < 0x10A00000 0x10000 >; 97 reg = < 0x10a00000 0x10000 >;
98 clocks = <&ext>; 98 clocks = <&ext>;
99 xlnx,clk-freq = <0x5f5e100>; 99 xlnx,clk-freq = <0x5f5e100>;
100 xlnx,family = "Artix7"; 100 xlnx,family = "Artix7";
@@ -106,9 +106,9 @@
106 #address-cells = <1>; 106 #address-cells = <1>;
107 #size-cells = <0>; 107 #size-cells = <0>;
108 108
109 ad7420@4B { 109 ad7420@4b {
110 compatible = "adi,adt7420"; 110 compatible = "adi,adt7420";
111 reg = <0x4B>; 111 reg = <0x4b>;
112 }; 112 };
113 } ; 113 } ;
114}; 114};
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index 43fcd35e2957..94096299fc56 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -58,6 +58,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \
58 if (kernel_uses_llsc) { \ 58 if (kernel_uses_llsc) { \
59 int temp; \ 59 int temp; \
60 \ 60 \
61 loongson_llsc_mb(); \
61 __asm__ __volatile__( \ 62 __asm__ __volatile__( \
62 " .set push \n" \ 63 " .set push \n" \
63 " .set "MIPS_ISA_LEVEL" \n" \ 64 " .set "MIPS_ISA_LEVEL" \n" \
@@ -85,6 +86,7 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \
85 if (kernel_uses_llsc) { \ 86 if (kernel_uses_llsc) { \
86 int temp; \ 87 int temp; \
87 \ 88 \
89 loongson_llsc_mb(); \
88 __asm__ __volatile__( \ 90 __asm__ __volatile__( \
89 " .set push \n" \ 91 " .set push \n" \
90 " .set "MIPS_ISA_LEVEL" \n" \ 92 " .set "MIPS_ISA_LEVEL" \n" \
@@ -118,6 +120,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
118 if (kernel_uses_llsc) { \ 120 if (kernel_uses_llsc) { \
119 int temp; \ 121 int temp; \
120 \ 122 \
123 loongson_llsc_mb(); \
121 __asm__ __volatile__( \ 124 __asm__ __volatile__( \
122 " .set push \n" \ 125 " .set push \n" \
123 " .set "MIPS_ISA_LEVEL" \n" \ 126 " .set "MIPS_ISA_LEVEL" \n" \
@@ -256,6 +259,7 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v) \
256 if (kernel_uses_llsc) { \ 259 if (kernel_uses_llsc) { \
257 long temp; \ 260 long temp; \
258 \ 261 \
262 loongson_llsc_mb(); \
259 __asm__ __volatile__( \ 263 __asm__ __volatile__( \
260 " .set push \n" \ 264 " .set push \n" \
261 " .set "MIPS_ISA_LEVEL" \n" \ 265 " .set "MIPS_ISA_LEVEL" \n" \
@@ -283,6 +287,7 @@ static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \
283 if (kernel_uses_llsc) { \ 287 if (kernel_uses_llsc) { \
284 long temp; \ 288 long temp; \
285 \ 289 \
290 loongson_llsc_mb(); \
286 __asm__ __volatile__( \ 291 __asm__ __volatile__( \
287 " .set push \n" \ 292 " .set push \n" \
288 " .set "MIPS_ISA_LEVEL" \n" \ 293 " .set "MIPS_ISA_LEVEL" \n" \
@@ -316,6 +321,7 @@ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v) \
316 if (kernel_uses_llsc) { \ 321 if (kernel_uses_llsc) { \
317 long temp; \ 322 long temp; \
318 \ 323 \
324 loongson_llsc_mb(); \
319 __asm__ __volatile__( \ 325 __asm__ __volatile__( \
320 " .set push \n" \ 326 " .set push \n" \
321 " .set "MIPS_ISA_LEVEL" \n" \ 327 " .set "MIPS_ISA_LEVEL" \n" \
diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
index a5eb1bb199a7..b7f6ac5e513c 100644
--- a/arch/mips/include/asm/barrier.h
+++ b/arch/mips/include/asm/barrier.h
@@ -222,6 +222,42 @@
222#define __smp_mb__before_atomic() __smp_mb__before_llsc() 222#define __smp_mb__before_atomic() __smp_mb__before_llsc()
223#define __smp_mb__after_atomic() smp_llsc_mb() 223#define __smp_mb__after_atomic() smp_llsc_mb()
224 224
225/*
226 * Some Loongson 3 CPUs have a bug wherein execution of a memory access (load,
227 * store or pref) in between an ll & sc can cause the sc instruction to
228 * erroneously succeed, breaking atomicity. Whilst it's unusual to write code
229 * containing such sequences, this bug bites harder than we might otherwise
230 * expect due to reordering & speculation:
231 *
232 * 1) A memory access appearing prior to the ll in program order may actually
233 * be executed after the ll - this is the reordering case.
234 *
235 * In order to avoid this we need to place a memory barrier (ie. a sync
236 * instruction) prior to every ll instruction, in between it & any earlier
237 * memory access instructions. Many of these cases are already covered by
238 * smp_mb__before_llsc() but for the remaining cases, typically ones in
239 * which multiple CPUs may operate on a memory location but ordering is not
240 * usually guaranteed, we use loongson_llsc_mb() below.
241 *
242 * This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later.
243 *
244 * 2) If a conditional branch exists between an ll & sc with a target outside
245 * of the ll-sc loop, for example an exit upon value mismatch in cmpxchg()
246 * or similar, then misprediction of the branch may allow speculative
247 * execution of memory accesses from outside of the ll-sc loop.
248 *
249 * In order to avoid this we need a memory barrier (ie. a sync instruction)
250 * at each affected branch target, for which we also use loongson_llsc_mb()
251 * defined below.
252 *
253 * This case affects all current Loongson 3 CPUs.
254 */
255#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */
256#define loongson_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
257#else
258#define loongson_llsc_mb() do { } while (0)
259#endif
260
225#include <asm-generic/barrier.h> 261#include <asm-generic/barrier.h>
226 262
227#endif /* __ASM_BARRIER_H */ 263#endif /* __ASM_BARRIER_H */
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index c4675957b21b..830c93a010c3 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -69,6 +69,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
69 : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m)); 69 : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m));
70#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) 70#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
71 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { 71 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
72 loongson_llsc_mb();
72 do { 73 do {
73 __asm__ __volatile__( 74 __asm__ __volatile__(
74 " " __LL "%0, %1 # set_bit \n" 75 " " __LL "%0, %1 # set_bit \n"
@@ -79,6 +80,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
79 } while (unlikely(!temp)); 80 } while (unlikely(!temp));
80#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ 81#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
81 } else if (kernel_uses_llsc) { 82 } else if (kernel_uses_llsc) {
83 loongson_llsc_mb();
82 do { 84 do {
83 __asm__ __volatile__( 85 __asm__ __volatile__(
84 " .set push \n" 86 " .set push \n"
@@ -123,6 +125,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
123 : "ir" (~(1UL << bit))); 125 : "ir" (~(1UL << bit)));
124#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) 126#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
125 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { 127 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
128 loongson_llsc_mb();
126 do { 129 do {
127 __asm__ __volatile__( 130 __asm__ __volatile__(
128 " " __LL "%0, %1 # clear_bit \n" 131 " " __LL "%0, %1 # clear_bit \n"
@@ -133,6 +136,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
133 } while (unlikely(!temp)); 136 } while (unlikely(!temp));
134#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ 137#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
135 } else if (kernel_uses_llsc) { 138 } else if (kernel_uses_llsc) {
139 loongson_llsc_mb();
136 do { 140 do {
137 __asm__ __volatile__( 141 __asm__ __volatile__(
138 " .set push \n" 142 " .set push \n"
@@ -193,6 +197,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
193 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 197 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
194 unsigned long temp; 198 unsigned long temp;
195 199
200 loongson_llsc_mb();
196 do { 201 do {
197 __asm__ __volatile__( 202 __asm__ __volatile__(
198 " .set push \n" 203 " .set push \n"
diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h
index c14d798f3888..b83b0397462d 100644
--- a/arch/mips/include/asm/futex.h
+++ b/arch/mips/include/asm/futex.h
@@ -50,6 +50,7 @@
50 "i" (-EFAULT) \ 50 "i" (-EFAULT) \
51 : "memory"); \ 51 : "memory"); \
52 } else if (cpu_has_llsc) { \ 52 } else if (cpu_has_llsc) { \
53 loongson_llsc_mb(); \
53 __asm__ __volatile__( \ 54 __asm__ __volatile__( \
54 " .set push \n" \ 55 " .set push \n" \
55 " .set noat \n" \ 56 " .set noat \n" \
@@ -163,6 +164,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
163 "i" (-EFAULT) 164 "i" (-EFAULT)
164 : "memory"); 165 : "memory");
165 } else if (cpu_has_llsc) { 166 } else if (cpu_has_llsc) {
167 loongson_llsc_mb();
166 __asm__ __volatile__( 168 __asm__ __volatile__(
167 "# futex_atomic_cmpxchg_inatomic \n" 169 "# futex_atomic_cmpxchg_inatomic \n"
168 " .set push \n" 170 " .set push \n"
@@ -192,6 +194,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
192 : GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), 194 : GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
193 "i" (-EFAULT) 195 "i" (-EFAULT)
194 : "memory"); 196 : "memory");
197 loongson_llsc_mb();
195 } else 198 } else
196 return -ENOSYS; 199 return -ENOSYS;
197 200
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 57933fc8fd98..910851c62db3 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -228,6 +228,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
228 : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) 228 : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
229 : [global] "r" (page_global)); 229 : [global] "r" (page_global));
230 } else if (kernel_uses_llsc) { 230 } else if (kernel_uses_llsc) {
231 loongson_llsc_mb();
231 __asm__ __volatile__ ( 232 __asm__ __volatile__ (
232 " .set push \n" 233 " .set push \n"
233 " .set "MIPS_ISA_ARCH_LEVEL" \n" 234 " .set "MIPS_ISA_ARCH_LEVEL" \n"
@@ -242,6 +243,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
242 " .set pop \n" 243 " .set pop \n"
243 : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) 244 : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
244 : [global] "r" (page_global)); 245 : [global] "r" (page_global));
246 loongson_llsc_mb();
245 } 247 }
246#else /* !CONFIG_SMP */ 248#else /* !CONFIG_SMP */
247 if (pte_none(*buddy)) 249 if (pte_none(*buddy))
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 8f5bd04f320a..7f3f136572de 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -457,5 +457,5 @@ void mips_cm_error_report(void)
457 } 457 }
458 458
459 /* reprime cause register */ 459 /* reprime cause register */
460 write_gcr_error_cause(0); 460 write_gcr_error_cause(cm_error);
461} 461}
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 6829a064aac8..339870ed92f7 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -371,7 +371,7 @@ static inline int is_sp_move_ins(union mips_instruction *ip, int *frame_size)
371static int get_frame_info(struct mips_frame_info *info) 371static int get_frame_info(struct mips_frame_info *info)
372{ 372{
373 bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS); 373 bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
374 union mips_instruction insn, *ip, *ip_end; 374 union mips_instruction insn, *ip;
375 const unsigned int max_insns = 128; 375 const unsigned int max_insns = 128;
376 unsigned int last_insn_size = 0; 376 unsigned int last_insn_size = 0;
377 unsigned int i; 377 unsigned int i;
@@ -384,10 +384,9 @@ static int get_frame_info(struct mips_frame_info *info)
384 if (!ip) 384 if (!ip)
385 goto err; 385 goto err;
386 386
387 ip_end = (void *)ip + info->func_size; 387 for (i = 0; i < max_insns; i++) {
388
389 for (i = 0; i < max_insns && ip < ip_end; i++) {
390 ip = (void *)ip + last_insn_size; 388 ip = (void *)ip + last_insn_size;
389
391 if (is_mmips && mm_insn_16bit(ip->halfword[0])) { 390 if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
392 insn.word = ip->halfword[0] << 16; 391 insn.word = ip->halfword[0] << 16;
393 last_insn_size = 2; 392 last_insn_size = 2;
diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform
index 0fce4608aa88..c1a4d4dc4665 100644
--- a/arch/mips/loongson64/Platform
+++ b/arch/mips/loongson64/Platform
@@ -23,6 +23,29 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
23endif 23endif
24 24
25cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap 25cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap
26
27#
28# Some versions of binutils, not currently mainline as of 2019/02/04, support
29# an -mfix-loongson3-llsc flag which emits a sync prior to each ll instruction
30# to work around a CPU bug (see loongson_llsc_mb() in asm/barrier.h for a
31# description).
32#
33# We disable this in order to prevent the assembler meddling with the
34# instruction that labels refer to, ie. if we label an ll instruction:
35#
36# 1: ll v0, 0(a0)
37#
38# ...then with the assembler fix applied the label may actually point at a sync
39# instruction inserted by the assembler, and if we were using the label in an
40# exception table the table would no longer contain the address of the ll
41# instruction.
42#
43# Avoid this by explicitly disabling that assembler behaviour. If upstream
44# binutils does not merge support for the flag then we can revisit & remove
45# this later - for now it ensures vendor toolchains don't cause problems.
46#
47cflags-$(CONFIG_CPU_LOONGSON3) += $(call as-option,-Wa$(comma)-mno-fix-loongson3-llsc,)
48
26# 49#
27# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a 50# binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
28# as MIPS64 R2; older versions as just R1. This leaves the possibility open 51# as MIPS64 R2; older versions as just R1. This leaves the possibility open
diff --git a/arch/mips/loongson64/common/reset.c b/arch/mips/loongson64/common/reset.c
index a60715e11306..b26892ce871c 100644
--- a/arch/mips/loongson64/common/reset.c
+++ b/arch/mips/loongson64/common/reset.c
@@ -59,7 +59,12 @@ static void loongson_poweroff(void)
59{ 59{
60#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE 60#ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
61 mach_prepare_shutdown(); 61 mach_prepare_shutdown();
62 unreachable(); 62
63 /*
64 * It needs a wait loop here, but mips/kernel/reset.c already calls
65 * a generic delay loop, machine_hang(), so simply return.
66 */
67 return;
63#else 68#else
64 void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr; 69 void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr;
65 70
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 37b1cb246332..65b6e85447b1 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -932,6 +932,8 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
932 * to mimic that here by taking a load/istream page 932 * to mimic that here by taking a load/istream page
933 * fault. 933 * fault.
934 */ 934 */
935 if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
936 uasm_i_sync(p, 0);
935 UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0); 937 UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
936 uasm_i_jr(p, ptr); 938 uasm_i_jr(p, ptr);
937 939
@@ -1646,6 +1648,8 @@ static void
1646iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) 1648iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
1647{ 1649{
1648#ifdef CONFIG_SMP 1650#ifdef CONFIG_SMP
1651 if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
1652 uasm_i_sync(p, 0);
1649# ifdef CONFIG_PHYS_ADDR_T_64BIT 1653# ifdef CONFIG_PHYS_ADDR_T_64BIT
1650 if (cpu_has_64bits) 1654 if (cpu_has_64bits)
1651 uasm_i_lld(p, pte, 0, ptr); 1655 uasm_i_lld(p, pte, 0, ptr);
@@ -2259,6 +2263,8 @@ static void build_r4000_tlb_load_handler(void)
2259#endif 2263#endif
2260 2264
2261 uasm_l_nopage_tlbl(&l, p); 2265 uasm_l_nopage_tlbl(&l, p);
2266 if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
2267 uasm_i_sync(&p, 0);
2262 build_restore_work_registers(&p); 2268 build_restore_work_registers(&p);
2263#ifdef CONFIG_CPU_MICROMIPS 2269#ifdef CONFIG_CPU_MICROMIPS
2264 if ((unsigned long)tlb_do_page_fault_0 & 1) { 2270 if ((unsigned long)tlb_do_page_fault_0 & 1) {
@@ -2313,6 +2319,8 @@ static void build_r4000_tlb_store_handler(void)
2313#endif 2319#endif
2314 2320
2315 uasm_l_nopage_tlbs(&l, p); 2321 uasm_l_nopage_tlbs(&l, p);
2322 if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
2323 uasm_i_sync(&p, 0);
2316 build_restore_work_registers(&p); 2324 build_restore_work_registers(&p);
2317#ifdef CONFIG_CPU_MICROMIPS 2325#ifdef CONFIG_CPU_MICROMIPS
2318 if ((unsigned long)tlb_do_page_fault_1 & 1) { 2326 if ((unsigned long)tlb_do_page_fault_1 & 1) {
@@ -2368,6 +2376,8 @@ static void build_r4000_tlb_modify_handler(void)
2368#endif 2376#endif
2369 2377
2370 uasm_l_nopage_tlbm(&l, p); 2378 uasm_l_nopage_tlbm(&l, p);
2379 if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
2380 uasm_i_sync(&p, 0);
2371 build_restore_work_registers(&p); 2381 build_restore_work_registers(&p);
2372#ifdef CONFIG_CPU_MICROMIPS 2382#ifdef CONFIG_CPU_MICROMIPS
2373 if ((unsigned long)tlb_do_page_fault_1 & 1) { 2383 if ((unsigned long)tlb_do_page_fault_1 & 1) {
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
index 5017d5843c5a..fc29b85cfa92 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -568,6 +568,11 @@ static int __init octeon_pci_setup(void)
568 if (octeon_has_feature(OCTEON_FEATURE_PCIE)) 568 if (octeon_has_feature(OCTEON_FEATURE_PCIE))
569 return 0; 569 return 0;
570 570
571 if (!octeon_is_pci_host()) {
572 pr_notice("Not in host mode, PCI Controller not initialized\n");
573 return 0;
574 }
575
571 /* Point pcibios_map_irq() to the PCI version of it */ 576 /* Point pcibios_map_irq() to the PCI version of it */
572 octeon_pcibios_map_irq = octeon_pci_pcibios_map_irq; 577 octeon_pcibios_map_irq = octeon_pci_pcibios_map_irq;
573 578
@@ -579,11 +584,6 @@ static int __init octeon_pci_setup(void)
579 else 584 else
580 octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_BIG; 585 octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_BIG;
581 586
582 if (!octeon_is_pci_host()) {
583 pr_notice("Not in host mode, PCI Controller not initialized\n");
584 return 0;
585 }
586
587 /* PCI I/O and PCI MEM values */ 587 /* PCI I/O and PCI MEM values */
588 set_io_port_base(OCTEON_PCI_IOSPACE_BASE); 588 set_io_port_base(OCTEON_PCI_IOSPACE_BASE);
589 ioport_resource.start = 0; 589 ioport_resource.start = 0;
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index f6fd340e39c2..0ede4deb8181 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -8,6 +8,7 @@ ccflags-vdso := \
8 $(filter -E%,$(KBUILD_CFLAGS)) \ 8 $(filter -E%,$(KBUILD_CFLAGS)) \
9 $(filter -mmicromips,$(KBUILD_CFLAGS)) \ 9 $(filter -mmicromips,$(KBUILD_CFLAGS)) \
10 $(filter -march=%,$(KBUILD_CFLAGS)) \ 10 $(filter -march=%,$(KBUILD_CFLAGS)) \
11 $(filter -m%-float,$(KBUILD_CFLAGS)) \
11 -D__VDSO__ 12 -D__VDSO__
12 13
13ifdef CONFIG_CC_IS_CLANG 14ifdef CONFIG_CC_IS_CLANG
@@ -129,7 +130,7 @@ $(obj)/%-o32.o: $(src)/%.c FORCE
129 $(call cmd,force_checksrc) 130 $(call cmd,force_checksrc)
130 $(call if_changed_rule,cc_o_c) 131 $(call if_changed_rule,cc_o_c)
131 132
132$(obj)/vdso-o32.lds: KBUILD_CPPFLAGS := -mabi=32 133$(obj)/vdso-o32.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) -mabi=32
133$(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE 134$(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE
134 $(call if_changed_dep,cpp_lds_S) 135 $(call if_changed_dep,cpp_lds_S)
135 136
@@ -169,7 +170,7 @@ $(obj)/%-n32.o: $(src)/%.c FORCE
169 $(call cmd,force_checksrc) 170 $(call cmd,force_checksrc)
170 $(call if_changed_rule,cc_o_c) 171 $(call if_changed_rule,cc_o_c)
171 172
172$(obj)/vdso-n32.lds: KBUILD_CPPFLAGS := -mabi=n32 173$(obj)/vdso-n32.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) -mabi=n32
173$(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE 174$(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE
174 $(call if_changed_dep,cpp_lds_S) 175 $(call if_changed_dep,cpp_lds_S)
175 176