diff options
| -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 | ||
