diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-02-09 15:41:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-02-09 15:41:14 -0500 |
commit | e8b50608f666cf5c314a9df3dc4b85789a6aeaa5 (patch) | |
tree | 880ece253ca5ef6bc27dc2e5fd2fb0e338259eab | |
parent | e5a8a1163211e2ab6f71c3545b26d55dc99ff1d3 (diff) | |
parent | 05dc6001af0630e200ad5ea08707187fe5537e6d (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/Kconfig | 15 | ||||
-rw-r--r-- | arch/mips/boot/dts/ingenic/ci20.dts | 8 | ||||
-rw-r--r-- | arch/mips/boot/dts/ingenic/jz4740.dtsi | 2 | ||||
-rw-r--r-- | arch/mips/boot/dts/xilfpga/nexys4ddr.dts | 8 | ||||
-rw-r--r-- | arch/mips/include/asm/atomic.h | 6 | ||||
-rw-r--r-- | arch/mips/include/asm/barrier.h | 36 | ||||
-rw-r--r-- | arch/mips/include/asm/bitops.h | 5 | ||||
-rw-r--r-- | arch/mips/include/asm/futex.h | 3 | ||||
-rw-r--r-- | arch/mips/include/asm/pgtable.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/mips-cm.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 7 | ||||
-rw-r--r-- | arch/mips/loongson64/Platform | 23 | ||||
-rw-r--r-- | arch/mips/loongson64/common/reset.c | 7 | ||||
-rw-r--r-- | arch/mips/mm/tlbex.c | 10 | ||||
-rw-r--r-- | arch/mips/pci/pci-octeon.c | 10 | ||||
-rw-r--r-- | arch/mips/vdso/Makefile | 5 |
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 | ||
1406 | config 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 | |||
1406 | config CPU_LOONGSON2E | 1421 | config 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) | |||
371 | static int get_frame_info(struct mips_frame_info *info) | 371 | static 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 | |||
23 | endif | 23 | endif |
24 | 24 | ||
25 | cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap | 25 | cflags-$(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 | # | ||
47 | cflags-$(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 | |||
1646 | iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) | 1648 | iPTE_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 | ||
13 | ifdef CONFIG_CC_IS_CLANG | 14 | ifdef 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 | ||