diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-14 18:03:17 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-14 18:03:17 -0500 |
| commit | 6bb821193b6e8b9cc40714f700da27b4688cbc22 (patch) | |
| tree | e39c057559700cba4ad38a1dafab1079ccba7f61 | |
| parent | 9443c168505d308f5ecd8c0db249f6f62a39c448 (diff) | |
| parent | 6e032b350cd1fdb830f18f8320ef0e13b4e24094 (diff) | |
Merge tag 'powerpc-4.15-7' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman:
"One fix for an oops at boot if we take a hotplug interrupt before we
are ready to handle it.
The bulk is patches to implement mitigation for Meltdown, see the
change logs for more details.
Thanks to: Nicholas Piggin, Michael Neuling, Oliver O'Halloran, Jon
Masters, Jose Ricardo Ziviani, David Gibson"
* tag 'powerpc-4.15-7' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/powernv: Check device-tree for RFI flush settings
powerpc/pseries: Query hypervisor for RFI flush settings
powerpc/64s: Support disabling RFI flush with no_rfi_flush and nopti
powerpc/64s: Add support for RFI flush of L1-D cache
powerpc/64s: Convert slb_miss_common to use RFI_TO_USER/KERNEL
powerpc/64: Convert fast_exception_return to use RFI_TO_USER/KERNEL
powerpc/64: Convert the syscall exit path to use RFI_TO_USER/KERNEL
powerpc/64s: Simple RFI macro conversions
powerpc/64: Add macros for annotating the destination of rfid/hrfid
powerpc/pseries: Add H_GET_CPU_CHARACTERISTICS flags & wrapper
powerpc/pseries: Make RAS IRQ explicitly dependent on DLPAR WQ
21 files changed, 561 insertions, 36 deletions
diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h index a703452d67b6..555e22d5e07f 100644 --- a/arch/powerpc/include/asm/exception-64e.h +++ b/arch/powerpc/include/asm/exception-64e.h | |||
| @@ -209,5 +209,11 @@ exc_##label##_book3e: | |||
| 209 | ori r3,r3,vector_offset@l; \ | 209 | ori r3,r3,vector_offset@l; \ |
| 210 | mtspr SPRN_IVOR##vector_number,r3; | 210 | mtspr SPRN_IVOR##vector_number,r3; |
| 211 | 211 | ||
| 212 | #define RFI_TO_KERNEL \ | ||
| 213 | rfi | ||
| 214 | |||
| 215 | #define RFI_TO_USER \ | ||
| 216 | rfi | ||
| 217 | |||
| 212 | #endif /* _ASM_POWERPC_EXCEPTION_64E_H */ | 218 | #endif /* _ASM_POWERPC_EXCEPTION_64E_H */ |
| 213 | 219 | ||
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index b27205297e1d..7197b179c1b1 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h | |||
| @@ -74,6 +74,59 @@ | |||
| 74 | */ | 74 | */ |
| 75 | #define EX_R3 EX_DAR | 75 | #define EX_R3 EX_DAR |
| 76 | 76 | ||
| 77 | /* | ||
| 78 | * Macros for annotating the expected destination of (h)rfid | ||
| 79 | * | ||
| 80 | * The nop instructions allow us to insert one or more instructions to flush the | ||
| 81 | * L1-D cache when returning to userspace or a guest. | ||
| 82 | */ | ||
| 83 | #define RFI_FLUSH_SLOT \ | ||
| 84 | RFI_FLUSH_FIXUP_SECTION; \ | ||
| 85 | nop; \ | ||
| 86 | nop; \ | ||
| 87 | nop | ||
| 88 | |||
| 89 | #define RFI_TO_KERNEL \ | ||
| 90 | rfid | ||
| 91 | |||
| 92 | #define RFI_TO_USER \ | ||
| 93 | RFI_FLUSH_SLOT; \ | ||
| 94 | rfid; \ | ||
| 95 | b rfi_flush_fallback | ||
| 96 | |||
| 97 | #define RFI_TO_USER_OR_KERNEL \ | ||
| 98 | RFI_FLUSH_SLOT; \ | ||
| 99 | rfid; \ | ||
| 100 | b rfi_flush_fallback | ||
| 101 | |||
| 102 | #define RFI_TO_GUEST \ | ||
| 103 | RFI_FLUSH_SLOT; \ | ||
| 104 | rfid; \ | ||
| 105 | b rfi_flush_fallback | ||
| 106 | |||
| 107 | #define HRFI_TO_KERNEL \ | ||
| 108 | hrfid | ||
| 109 | |||
| 110 | #define HRFI_TO_USER \ | ||
| 111 | RFI_FLUSH_SLOT; \ | ||
| 112 | hrfid; \ | ||
| 113 | b hrfi_flush_fallback | ||
| 114 | |||
| 115 | #define HRFI_TO_USER_OR_KERNEL \ | ||
| 116 | RFI_FLUSH_SLOT; \ | ||
| 117 | hrfid; \ | ||
| 118 | b hrfi_flush_fallback | ||
| 119 | |||
| 120 | #define HRFI_TO_GUEST \ | ||
| 121 | RFI_FLUSH_SLOT; \ | ||
| 122 | hrfid; \ | ||
| 123 | b hrfi_flush_fallback | ||
| 124 | |||
| 125 | #define HRFI_TO_UNKNOWN \ | ||
| 126 | RFI_FLUSH_SLOT; \ | ||
| 127 | hrfid; \ | ||
| 128 | b hrfi_flush_fallback | ||
| 129 | |||
| 77 | #ifdef CONFIG_RELOCATABLE | 130 | #ifdef CONFIG_RELOCATABLE |
| 78 | #define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \ | 131 | #define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \ |
| 79 | mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ | 132 | mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ |
| @@ -218,7 +271,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) | |||
| 218 | mtspr SPRN_##h##SRR0,r12; \ | 271 | mtspr SPRN_##h##SRR0,r12; \ |
| 219 | mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ | 272 | mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ |
| 220 | mtspr SPRN_##h##SRR1,r10; \ | 273 | mtspr SPRN_##h##SRR1,r10; \ |
| 221 | h##rfid; \ | 274 | h##RFI_TO_KERNEL; \ |
| 222 | b . /* prevent speculative execution */ | 275 | b . /* prevent speculative execution */ |
| 223 | #define EXCEPTION_PROLOG_PSERIES_1(label, h) \ | 276 | #define EXCEPTION_PROLOG_PSERIES_1(label, h) \ |
| 224 | __EXCEPTION_PROLOG_PSERIES_1(label, h) | 277 | __EXCEPTION_PROLOG_PSERIES_1(label, h) |
| @@ -232,7 +285,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) | |||
| 232 | mtspr SPRN_##h##SRR0,r12; \ | 285 | mtspr SPRN_##h##SRR0,r12; \ |
| 233 | mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ | 286 | mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ |
| 234 | mtspr SPRN_##h##SRR1,r10; \ | 287 | mtspr SPRN_##h##SRR1,r10; \ |
| 235 | h##rfid; \ | 288 | h##RFI_TO_KERNEL; \ |
| 236 | b . /* prevent speculative execution */ | 289 | b . /* prevent speculative execution */ |
| 237 | 290 | ||
| 238 | #define EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \ | 291 | #define EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \ |
diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h index 8f88f771cc55..1e82eb3caabd 100644 --- a/arch/powerpc/include/asm/feature-fixups.h +++ b/arch/powerpc/include/asm/feature-fixups.h | |||
| @@ -187,7 +187,20 @@ label##3: \ | |||
| 187 | FTR_ENTRY_OFFSET label##1b-label##3b; \ | 187 | FTR_ENTRY_OFFSET label##1b-label##3b; \ |
| 188 | .popsection; | 188 | .popsection; |
| 189 | 189 | ||
| 190 | #define RFI_FLUSH_FIXUP_SECTION \ | ||
| 191 | 951: \ | ||
| 192 | .pushsection __rfi_flush_fixup,"a"; \ | ||
| 193 | .align 2; \ | ||
| 194 | 952: \ | ||
| 195 | FTR_ENTRY_OFFSET 951b-952b; \ | ||
| 196 | .popsection; | ||
| 197 | |||
| 198 | |||
| 190 | #ifndef __ASSEMBLY__ | 199 | #ifndef __ASSEMBLY__ |
| 200 | #include <linux/types.h> | ||
| 201 | |||
| 202 | extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; | ||
| 203 | |||
| 191 | void apply_feature_fixups(void); | 204 | void apply_feature_fixups(void); |
| 192 | void setup_feature_keys(void); | 205 | void setup_feature_keys(void); |
| 193 | #endif | 206 | #endif |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index a409177be8bd..f0461618bf7b 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
| @@ -241,6 +241,7 @@ | |||
| 241 | #define H_GET_HCA_INFO 0x1B8 | 241 | #define H_GET_HCA_INFO 0x1B8 |
| 242 | #define H_GET_PERF_COUNT 0x1BC | 242 | #define H_GET_PERF_COUNT 0x1BC |
| 243 | #define H_MANAGE_TRACE 0x1C0 | 243 | #define H_MANAGE_TRACE 0x1C0 |
| 244 | #define H_GET_CPU_CHARACTERISTICS 0x1C8 | ||
| 244 | #define H_FREE_LOGICAL_LAN_BUFFER 0x1D4 | 245 | #define H_FREE_LOGICAL_LAN_BUFFER 0x1D4 |
| 245 | #define H_QUERY_INT_STATE 0x1E4 | 246 | #define H_QUERY_INT_STATE 0x1E4 |
| 246 | #define H_POLL_PENDING 0x1D8 | 247 | #define H_POLL_PENDING 0x1D8 |
| @@ -330,6 +331,17 @@ | |||
| 330 | #define H_SIGNAL_SYS_RESET_ALL_OTHERS -2 | 331 | #define H_SIGNAL_SYS_RESET_ALL_OTHERS -2 |
| 331 | /* >= 0 values are CPU number */ | 332 | /* >= 0 values are CPU number */ |
| 332 | 333 | ||
| 334 | /* H_GET_CPU_CHARACTERISTICS return values */ | ||
| 335 | #define H_CPU_CHAR_SPEC_BAR_ORI31 (1ull << 63) // IBM bit 0 | ||
| 336 | #define H_CPU_CHAR_BCCTRL_SERIALISED (1ull << 62) // IBM bit 1 | ||
| 337 | #define H_CPU_CHAR_L1D_FLUSH_ORI30 (1ull << 61) // IBM bit 2 | ||
| 338 | #define H_CPU_CHAR_L1D_FLUSH_TRIG2 (1ull << 60) // IBM bit 3 | ||
| 339 | #define H_CPU_CHAR_L1D_THREAD_PRIV (1ull << 59) // IBM bit 4 | ||
| 340 | |||
| 341 | #define H_CPU_BEHAV_FAVOUR_SECURITY (1ull << 63) // IBM bit 0 | ||
| 342 | #define H_CPU_BEHAV_L1D_FLUSH_PR (1ull << 62) // IBM bit 1 | ||
| 343 | #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ull << 61) // IBM bit 2 | ||
| 344 | |||
| 333 | /* Flag values used in H_REGISTER_PROC_TBL hcall */ | 345 | /* Flag values used in H_REGISTER_PROC_TBL hcall */ |
| 334 | #define PROC_TABLE_OP_MASK 0x18 | 346 | #define PROC_TABLE_OP_MASK 0x18 |
| 335 | #define PROC_TABLE_DEREG 0x10 | 347 | #define PROC_TABLE_DEREG 0x10 |
| @@ -436,6 +448,11 @@ static inline unsigned int get_longbusy_msecs(int longbusy_rc) | |||
| 436 | } | 448 | } |
| 437 | } | 449 | } |
| 438 | 450 | ||
| 451 | struct h_cpu_char_result { | ||
| 452 | u64 character; | ||
| 453 | u64 behaviour; | ||
| 454 | }; | ||
| 455 | |||
| 439 | #endif /* __ASSEMBLY__ */ | 456 | #endif /* __ASSEMBLY__ */ |
| 440 | #endif /* __KERNEL__ */ | 457 | #endif /* __KERNEL__ */ |
| 441 | #endif /* _ASM_POWERPC_HVCALL_H */ | 458 | #endif /* _ASM_POWERPC_HVCALL_H */ |
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 3892db93b837..23ac7fc0af23 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h | |||
| @@ -232,6 +232,16 @@ struct paca_struct { | |||
| 232 | struct sibling_subcore_state *sibling_subcore_state; | 232 | struct sibling_subcore_state *sibling_subcore_state; |
| 233 | #endif | 233 | #endif |
| 234 | #endif | 234 | #endif |
| 235 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 236 | /* | ||
| 237 | * rfi fallback flush must be in its own cacheline to prevent | ||
| 238 | * other paca data leaking into the L1d | ||
| 239 | */ | ||
| 240 | u64 exrfi[EX_SIZE] __aligned(0x80); | ||
| 241 | void *rfi_flush_fallback_area; | ||
| 242 | u64 l1d_flush_congruence; | ||
| 243 | u64 l1d_flush_sets; | ||
| 244 | #endif | ||
| 235 | }; | 245 | }; |
| 236 | 246 | ||
| 237 | extern void copy_mm_to_paca(struct mm_struct *mm); | 247 | extern void copy_mm_to_paca(struct mm_struct *mm); |
diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h index 7f01b22fa6cb..55eddf50d149 100644 --- a/arch/powerpc/include/asm/plpar_wrappers.h +++ b/arch/powerpc/include/asm/plpar_wrappers.h | |||
| @@ -326,4 +326,18 @@ static inline long plapr_signal_sys_reset(long cpu) | |||
| 326 | return plpar_hcall_norets(H_SIGNAL_SYS_RESET, cpu); | 326 | return plpar_hcall_norets(H_SIGNAL_SYS_RESET, cpu); |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result *p) | ||
| 330 | { | ||
| 331 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
| 332 | long rc; | ||
| 333 | |||
| 334 | rc = plpar_hcall(H_GET_CPU_CHARACTERISTICS, retbuf); | ||
| 335 | if (rc == H_SUCCESS) { | ||
| 336 | p->character = retbuf[0]; | ||
| 337 | p->behaviour = retbuf[1]; | ||
| 338 | } | ||
| 339 | |||
| 340 | return rc; | ||
| 341 | } | ||
| 342 | |||
| 329 | #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */ | 343 | #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */ |
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h index cf00ec26303a..469b7fdc9be4 100644 --- a/arch/powerpc/include/asm/setup.h +++ b/arch/powerpc/include/asm/setup.h | |||
| @@ -39,6 +39,19 @@ static inline void pseries_big_endian_exceptions(void) {} | |||
| 39 | static inline void pseries_little_endian_exceptions(void) {} | 39 | static inline void pseries_little_endian_exceptions(void) {} |
| 40 | #endif /* CONFIG_PPC_PSERIES */ | 40 | #endif /* CONFIG_PPC_PSERIES */ |
| 41 | 41 | ||
| 42 | void rfi_flush_enable(bool enable); | ||
| 43 | |||
| 44 | /* These are bit flags */ | ||
| 45 | enum l1d_flush_type { | ||
| 46 | L1D_FLUSH_NONE = 0x1, | ||
| 47 | L1D_FLUSH_FALLBACK = 0x2, | ||
| 48 | L1D_FLUSH_ORI = 0x4, | ||
| 49 | L1D_FLUSH_MTTRIG = 0x8, | ||
| 50 | }; | ||
| 51 | |||
| 52 | void __init setup_rfi_flush(enum l1d_flush_type, bool enable); | ||
| 53 | void do_rfi_flush_fixups(enum l1d_flush_type types); | ||
| 54 | |||
| 42 | #endif /* !__ASSEMBLY__ */ | 55 | #endif /* !__ASSEMBLY__ */ |
| 43 | 56 | ||
| 44 | #endif /* _ASM_POWERPC_SETUP_H */ | 57 | #endif /* _ASM_POWERPC_SETUP_H */ |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 6b958414b4e0..f390d57cf2e1 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -237,6 +237,11 @@ int main(void) | |||
| 237 | OFFSET(PACA_NMI_EMERG_SP, paca_struct, nmi_emergency_sp); | 237 | OFFSET(PACA_NMI_EMERG_SP, paca_struct, nmi_emergency_sp); |
| 238 | OFFSET(PACA_IN_MCE, paca_struct, in_mce); | 238 | OFFSET(PACA_IN_MCE, paca_struct, in_mce); |
| 239 | OFFSET(PACA_IN_NMI, paca_struct, in_nmi); | 239 | OFFSET(PACA_IN_NMI, paca_struct, in_nmi); |
| 240 | OFFSET(PACA_RFI_FLUSH_FALLBACK_AREA, paca_struct, rfi_flush_fallback_area); | ||
| 241 | OFFSET(PACA_EXRFI, paca_struct, exrfi); | ||
| 242 | OFFSET(PACA_L1D_FLUSH_CONGRUENCE, paca_struct, l1d_flush_congruence); | ||
| 243 | OFFSET(PACA_L1D_FLUSH_SETS, paca_struct, l1d_flush_sets); | ||
| 244 | |||
| 240 | #endif | 245 | #endif |
| 241 | OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id); | 246 | OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id); |
| 242 | OFFSET(PACAKEXECSTATE, paca_struct, kexec_state); | 247 | OFFSET(PACAKEXECSTATE, paca_struct, kexec_state); |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 3320bcac7192..2748584b767d 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
| @@ -37,6 +37,11 @@ | |||
| 37 | #include <asm/tm.h> | 37 | #include <asm/tm.h> |
| 38 | #include <asm/ppc-opcode.h> | 38 | #include <asm/ppc-opcode.h> |
| 39 | #include <asm/export.h> | 39 | #include <asm/export.h> |
| 40 | #ifdef CONFIG_PPC_BOOK3S | ||
| 41 | #include <asm/exception-64s.h> | ||
| 42 | #else | ||
| 43 | #include <asm/exception-64e.h> | ||
| 44 | #endif | ||
| 40 | 45 | ||
| 41 | /* | 46 | /* |
| 42 | * System calls. | 47 | * System calls. |
| @@ -262,13 +267,23 @@ BEGIN_FTR_SECTION | |||
| 262 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | 267 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) |
| 263 | 268 | ||
| 264 | ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ | 269 | ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ |
| 270 | ld r2,GPR2(r1) | ||
| 271 | ld r1,GPR1(r1) | ||
| 272 | mtlr r4 | ||
| 273 | mtcr r5 | ||
| 274 | mtspr SPRN_SRR0,r7 | ||
| 275 | mtspr SPRN_SRR1,r8 | ||
| 276 | RFI_TO_USER | ||
| 277 | b . /* prevent speculative execution */ | ||
| 278 | |||
| 279 | /* exit to kernel */ | ||
| 265 | 1: ld r2,GPR2(r1) | 280 | 1: ld r2,GPR2(r1) |
| 266 | ld r1,GPR1(r1) | 281 | ld r1,GPR1(r1) |
| 267 | mtlr r4 | 282 | mtlr r4 |
| 268 | mtcr r5 | 283 | mtcr r5 |
| 269 | mtspr SPRN_SRR0,r7 | 284 | mtspr SPRN_SRR0,r7 |
| 270 | mtspr SPRN_SRR1,r8 | 285 | mtspr SPRN_SRR1,r8 |
| 271 | RFI | 286 | RFI_TO_KERNEL |
| 272 | b . /* prevent speculative execution */ | 287 | b . /* prevent speculative execution */ |
| 273 | 288 | ||
| 274 | .Lsyscall_error: | 289 | .Lsyscall_error: |
| @@ -397,8 +412,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | |||
| 397 | mtmsrd r10, 1 | 412 | mtmsrd r10, 1 |
| 398 | mtspr SPRN_SRR0, r11 | 413 | mtspr SPRN_SRR0, r11 |
| 399 | mtspr SPRN_SRR1, r12 | 414 | mtspr SPRN_SRR1, r12 |
| 400 | 415 | RFI_TO_USER | |
| 401 | rfid | ||
| 402 | b . /* prevent speculative execution */ | 416 | b . /* prevent speculative execution */ |
| 403 | #endif | 417 | #endif |
| 404 | _ASM_NOKPROBE_SYMBOL(system_call_common); | 418 | _ASM_NOKPROBE_SYMBOL(system_call_common); |
| @@ -878,7 +892,7 @@ BEGIN_FTR_SECTION | |||
| 878 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | 892 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) |
| 879 | ACCOUNT_CPU_USER_EXIT(r13, r2, r4) | 893 | ACCOUNT_CPU_USER_EXIT(r13, r2, r4) |
| 880 | REST_GPR(13, r1) | 894 | REST_GPR(13, r1) |
| 881 | 1: | 895 | |
| 882 | mtspr SPRN_SRR1,r3 | 896 | mtspr SPRN_SRR1,r3 |
| 883 | 897 | ||
| 884 | ld r2,_CCR(r1) | 898 | ld r2,_CCR(r1) |
| @@ -891,8 +905,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) | |||
| 891 | ld r3,GPR3(r1) | 905 | ld r3,GPR3(r1) |
| 892 | ld r4,GPR4(r1) | 906 | ld r4,GPR4(r1) |
| 893 | ld r1,GPR1(r1) | 907 | ld r1,GPR1(r1) |
| 908 | RFI_TO_USER | ||
| 909 | b . /* prevent speculative execution */ | ||
| 894 | 910 | ||
| 895 | rfid | 911 | 1: mtspr SPRN_SRR1,r3 |
| 912 | |||
| 913 | ld r2,_CCR(r1) | ||
| 914 | mtcrf 0xFF,r2 | ||
| 915 | ld r2,_NIP(r1) | ||
| 916 | mtspr SPRN_SRR0,r2 | ||
| 917 | |||
| 918 | ld r0,GPR0(r1) | ||
| 919 | ld r2,GPR2(r1) | ||
| 920 | ld r3,GPR3(r1) | ||
| 921 | ld r4,GPR4(r1) | ||
| 922 | ld r1,GPR1(r1) | ||
| 923 | RFI_TO_KERNEL | ||
| 896 | b . /* prevent speculative execution */ | 924 | b . /* prevent speculative execution */ |
| 897 | 925 | ||
| 898 | #endif /* CONFIG_PPC_BOOK3E */ | 926 | #endif /* CONFIG_PPC_BOOK3E */ |
| @@ -1073,7 +1101,7 @@ __enter_rtas: | |||
| 1073 | 1101 | ||
| 1074 | mtspr SPRN_SRR0,r5 | 1102 | mtspr SPRN_SRR0,r5 |
| 1075 | mtspr SPRN_SRR1,r6 | 1103 | mtspr SPRN_SRR1,r6 |
| 1076 | rfid | 1104 | RFI_TO_KERNEL |
| 1077 | b . /* prevent speculative execution */ | 1105 | b . /* prevent speculative execution */ |
| 1078 | 1106 | ||
| 1079 | rtas_return_loc: | 1107 | rtas_return_loc: |
| @@ -1098,7 +1126,7 @@ rtas_return_loc: | |||
| 1098 | 1126 | ||
| 1099 | mtspr SPRN_SRR0,r3 | 1127 | mtspr SPRN_SRR0,r3 |
| 1100 | mtspr SPRN_SRR1,r4 | 1128 | mtspr SPRN_SRR1,r4 |
| 1101 | rfid | 1129 | RFI_TO_KERNEL |
| 1102 | b . /* prevent speculative execution */ | 1130 | b . /* prevent speculative execution */ |
| 1103 | _ASM_NOKPROBE_SYMBOL(__enter_rtas) | 1131 | _ASM_NOKPROBE_SYMBOL(__enter_rtas) |
| 1104 | _ASM_NOKPROBE_SYMBOL(rtas_return_loc) | 1132 | _ASM_NOKPROBE_SYMBOL(rtas_return_loc) |
| @@ -1171,7 +1199,7 @@ _GLOBAL(enter_prom) | |||
| 1171 | LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE) | 1199 | LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE) |
| 1172 | andc r11,r11,r12 | 1200 | andc r11,r11,r12 |
| 1173 | mtsrr1 r11 | 1201 | mtsrr1 r11 |
| 1174 | rfid | 1202 | RFI_TO_KERNEL |
| 1175 | #endif /* CONFIG_PPC_BOOK3E */ | 1203 | #endif /* CONFIG_PPC_BOOK3E */ |
| 1176 | 1204 | ||
| 1177 | 1: /* Return from OF */ | 1205 | 1: /* Return from OF */ |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e441b469dc8f..2dc10bf646b8 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
| @@ -256,7 +256,7 @@ BEGIN_FTR_SECTION | |||
| 256 | LOAD_HANDLER(r12, machine_check_handle_early) | 256 | LOAD_HANDLER(r12, machine_check_handle_early) |
| 257 | 1: mtspr SPRN_SRR0,r12 | 257 | 1: mtspr SPRN_SRR0,r12 |
| 258 | mtspr SPRN_SRR1,r11 | 258 | mtspr SPRN_SRR1,r11 |
| 259 | rfid | 259 | RFI_TO_KERNEL |
| 260 | b . /* prevent speculative execution */ | 260 | b . /* prevent speculative execution */ |
| 261 | 2: | 261 | 2: |
| 262 | /* Stack overflow. Stay on emergency stack and panic. | 262 | /* Stack overflow. Stay on emergency stack and panic. |
| @@ -445,7 +445,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) | |||
| 445 | li r3,MSR_ME | 445 | li r3,MSR_ME |
| 446 | andc r10,r10,r3 /* Turn off MSR_ME */ | 446 | andc r10,r10,r3 /* Turn off MSR_ME */ |
| 447 | mtspr SPRN_SRR1,r10 | 447 | mtspr SPRN_SRR1,r10 |
| 448 | rfid | 448 | RFI_TO_KERNEL |
| 449 | b . | 449 | b . |
| 450 | 2: | 450 | 2: |
| 451 | /* | 451 | /* |
| @@ -463,7 +463,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) | |||
| 463 | */ | 463 | */ |
| 464 | bl machine_check_queue_event | 464 | bl machine_check_queue_event |
| 465 | MACHINE_CHECK_HANDLER_WINDUP | 465 | MACHINE_CHECK_HANDLER_WINDUP |
| 466 | rfid | 466 | RFI_TO_USER_OR_KERNEL |
| 467 | 9: | 467 | 9: |
| 468 | /* Deliver the machine check to host kernel in V mode. */ | 468 | /* Deliver the machine check to host kernel in V mode. */ |
| 469 | MACHINE_CHECK_HANDLER_WINDUP | 469 | MACHINE_CHECK_HANDLER_WINDUP |
| @@ -598,6 +598,9 @@ EXC_COMMON_BEGIN(slb_miss_common) | |||
| 598 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ | 598 | stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ |
| 599 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ | 599 | std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ |
| 600 | 600 | ||
| 601 | andi. r9,r11,MSR_PR // Check for exception from userspace | ||
| 602 | cmpdi cr4,r9,MSR_PR // And save the result in CR4 for later | ||
| 603 | |||
| 601 | /* | 604 | /* |
| 602 | * Test MSR_RI before calling slb_allocate_realmode, because the | 605 | * Test MSR_RI before calling slb_allocate_realmode, because the |
| 603 | * MSR in r11 gets clobbered. However we still want to allocate | 606 | * MSR in r11 gets clobbered. However we still want to allocate |
| @@ -624,9 +627,12 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
| 624 | 627 | ||
| 625 | /* All done -- return from exception. */ | 628 | /* All done -- return from exception. */ |
| 626 | 629 | ||
| 630 | bne cr4,1f /* returning to kernel */ | ||
| 631 | |||
| 627 | .machine push | 632 | .machine push |
| 628 | .machine "power4" | 633 | .machine "power4" |
| 629 | mtcrf 0x80,r9 | 634 | mtcrf 0x80,r9 |
| 635 | mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */ | ||
| 630 | mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */ | 636 | mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */ |
| 631 | mtcrf 0x02,r9 /* I/D indication is in cr6 */ | 637 | mtcrf 0x02,r9 /* I/D indication is in cr6 */ |
| 632 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ | 638 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ |
| @@ -640,9 +646,30 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
| 640 | ld r11,PACA_EXSLB+EX_R11(r13) | 646 | ld r11,PACA_EXSLB+EX_R11(r13) |
| 641 | ld r12,PACA_EXSLB+EX_R12(r13) | 647 | ld r12,PACA_EXSLB+EX_R12(r13) |
| 642 | ld r13,PACA_EXSLB+EX_R13(r13) | 648 | ld r13,PACA_EXSLB+EX_R13(r13) |
| 643 | rfid | 649 | RFI_TO_USER |
| 650 | b . /* prevent speculative execution */ | ||
| 651 | 1: | ||
| 652 | .machine push | ||
| 653 | .machine "power4" | ||
| 654 | mtcrf 0x80,r9 | ||
| 655 | mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */ | ||
| 656 | mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */ | ||
| 657 | mtcrf 0x02,r9 /* I/D indication is in cr6 */ | ||
| 658 | mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ | ||
| 659 | .machine pop | ||
| 660 | |||
| 661 | RESTORE_CTR(r9, PACA_EXSLB) | ||
| 662 | RESTORE_PPR_PACA(PACA_EXSLB, r9) | ||
| 663 | mr r3,r12 | ||
| 664 | ld r9,PACA_EXSLB+EX_R9(r13) | ||
| 665 | ld r10,PACA_EXSLB+EX_R10(r13) | ||
| 666 | ld r11,PACA_EXSLB+EX_R11(r13) | ||
| 667 | ld r12,PACA_EXSLB+EX_R12(r13) | ||
| 668 | ld r13,PACA_EXSLB+EX_R13(r13) | ||
| 669 | RFI_TO_KERNEL | ||
| 644 | b . /* prevent speculative execution */ | 670 | b . /* prevent speculative execution */ |
| 645 | 671 | ||
| 672 | |||
| 646 | 2: std r3,PACA_EXSLB+EX_DAR(r13) | 673 | 2: std r3,PACA_EXSLB+EX_DAR(r13) |
| 647 | mr r3,r12 | 674 | mr r3,r12 |
| 648 | mfspr r11,SPRN_SRR0 | 675 | mfspr r11,SPRN_SRR0 |
| @@ -651,7 +678,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
| 651 | mtspr SPRN_SRR0,r10 | 678 | mtspr SPRN_SRR0,r10 |
| 652 | ld r10,PACAKMSR(r13) | 679 | ld r10,PACAKMSR(r13) |
| 653 | mtspr SPRN_SRR1,r10 | 680 | mtspr SPRN_SRR1,r10 |
| 654 | rfid | 681 | RFI_TO_KERNEL |
| 655 | b . | 682 | b . |
| 656 | 683 | ||
| 657 | 8: std r3,PACA_EXSLB+EX_DAR(r13) | 684 | 8: std r3,PACA_EXSLB+EX_DAR(r13) |
| @@ -662,7 +689,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) | |||
| 662 | mtspr SPRN_SRR0,r10 | 689 | mtspr SPRN_SRR0,r10 |
| 663 | ld r10,PACAKMSR(r13) | 690 | ld r10,PACAKMSR(r13) |
| 664 | mtspr SPRN_SRR1,r10 | 691 | mtspr SPRN_SRR1,r10 |
| 665 | rfid | 692 | RFI_TO_KERNEL |
| 666 | b . | 693 | b . |
| 667 | 694 | ||
| 668 | EXC_COMMON_BEGIN(unrecov_slb) | 695 | EXC_COMMON_BEGIN(unrecov_slb) |
| @@ -901,7 +928,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception) | |||
| 901 | mtspr SPRN_SRR0,r10 ; \ | 928 | mtspr SPRN_SRR0,r10 ; \ |
| 902 | ld r10,PACAKMSR(r13) ; \ | 929 | ld r10,PACAKMSR(r13) ; \ |
| 903 | mtspr SPRN_SRR1,r10 ; \ | 930 | mtspr SPRN_SRR1,r10 ; \ |
| 904 | rfid ; \ | 931 | RFI_TO_KERNEL ; \ |
| 905 | b . ; /* prevent speculative execution */ | 932 | b . ; /* prevent speculative execution */ |
| 906 | 933 | ||
| 907 | #ifdef CONFIG_PPC_FAST_ENDIAN_SWITCH | 934 | #ifdef CONFIG_PPC_FAST_ENDIAN_SWITCH |
| @@ -917,7 +944,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \ | |||
| 917 | xori r12,r12,MSR_LE ; \ | 944 | xori r12,r12,MSR_LE ; \ |
| 918 | mtspr SPRN_SRR1,r12 ; \ | 945 | mtspr SPRN_SRR1,r12 ; \ |
| 919 | mr r13,r9 ; \ | 946 | mr r13,r9 ; \ |
| 920 | rfid ; /* return to userspace */ \ | 947 | RFI_TO_USER ; /* return to userspace */ \ |
| 921 | b . ; /* prevent speculative execution */ | 948 | b . ; /* prevent speculative execution */ |
| 922 | #else | 949 | #else |
| 923 | #define SYSCALL_FASTENDIAN_TEST | 950 | #define SYSCALL_FASTENDIAN_TEST |
| @@ -1063,7 +1090,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early) | |||
| 1063 | mtcr r11 | 1090 | mtcr r11 |
| 1064 | REST_GPR(11, r1) | 1091 | REST_GPR(11, r1) |
| 1065 | ld r1,GPR1(r1) | 1092 | ld r1,GPR1(r1) |
| 1066 | hrfid | 1093 | HRFI_TO_USER_OR_KERNEL |
| 1067 | 1094 | ||
| 1068 | 1: mtcr r11 | 1095 | 1: mtcr r11 |
| 1069 | REST_GPR(11, r1) | 1096 | REST_GPR(11, r1) |
| @@ -1314,7 +1341,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) | |||
| 1314 | ld r11,PACA_EXGEN+EX_R11(r13) | 1341 | ld r11,PACA_EXGEN+EX_R11(r13) |
| 1315 | ld r12,PACA_EXGEN+EX_R12(r13) | 1342 | ld r12,PACA_EXGEN+EX_R12(r13) |
| 1316 | ld r13,PACA_EXGEN+EX_R13(r13) | 1343 | ld r13,PACA_EXGEN+EX_R13(r13) |
| 1317 | HRFID | 1344 | HRFI_TO_UNKNOWN |
| 1318 | b . | 1345 | b . |
| 1319 | #endif | 1346 | #endif |
| 1320 | 1347 | ||
| @@ -1418,10 +1445,94 @@ masked_##_H##interrupt: \ | |||
| 1418 | ld r10,PACA_EXGEN+EX_R10(r13); \ | 1445 | ld r10,PACA_EXGEN+EX_R10(r13); \ |
| 1419 | ld r11,PACA_EXGEN+EX_R11(r13); \ | 1446 | ld r11,PACA_EXGEN+EX_R11(r13); \ |
| 1420 | /* returns to kernel where r13 must be set up, so don't restore it */ \ | 1447 | /* returns to kernel where r13 must be set up, so don't restore it */ \ |
| 1421 | ##_H##rfid; \ | 1448 | ##_H##RFI_TO_KERNEL; \ |
| 1422 | b .; \ | 1449 | b .; \ |
| 1423 | MASKED_DEC_HANDLER(_H) | 1450 | MASKED_DEC_HANDLER(_H) |
| 1424 | 1451 | ||
| 1452 | TRAMP_REAL_BEGIN(rfi_flush_fallback) | ||
| 1453 | SET_SCRATCH0(r13); | ||
| 1454 | GET_PACA(r13); | ||
| 1455 | std r9,PACA_EXRFI+EX_R9(r13) | ||
| 1456 | std r10,PACA_EXRFI+EX_R10(r13) | ||
| 1457 | std r11,PACA_EXRFI+EX_R11(r13) | ||
| 1458 | std r12,PACA_EXRFI+EX_R12(r13) | ||
| 1459 | std r8,PACA_EXRFI+EX_R13(r13) | ||
| 1460 | mfctr r9 | ||
| 1461 | ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) | ||
| 1462 | ld r11,PACA_L1D_FLUSH_SETS(r13) | ||
| 1463 | ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) | ||
| 1464 | /* | ||
| 1465 | * The load adresses are at staggered offsets within cachelines, | ||
| 1466 | * which suits some pipelines better (on others it should not | ||
| 1467 | * hurt). | ||
| 1468 | */ | ||
| 1469 | addi r12,r12,8 | ||
| 1470 | mtctr r11 | ||
| 1471 | DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ | ||
| 1472 | |||
| 1473 | /* order ld/st prior to dcbt stop all streams with flushing */ | ||
| 1474 | sync | ||
| 1475 | 1: li r8,0 | ||
| 1476 | .rept 8 /* 8-way set associative */ | ||
| 1477 | ldx r11,r10,r8 | ||
| 1478 | add r8,r8,r12 | ||
| 1479 | xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not | ||
| 1480 | add r8,r8,r11 // Add 0, this creates a dependency on the ldx | ||
| 1481 | .endr | ||
| 1482 | addi r10,r10,128 /* 128 byte cache line */ | ||
| 1483 | bdnz 1b | ||
| 1484 | |||
| 1485 | mtctr r9 | ||
| 1486 | ld r9,PACA_EXRFI+EX_R9(r13) | ||
| 1487 | ld r10,PACA_EXRFI+EX_R10(r13) | ||
| 1488 | ld r11,PACA_EXRFI+EX_R11(r13) | ||
| 1489 | ld r12,PACA_EXRFI+EX_R12(r13) | ||
| 1490 | ld r8,PACA_EXRFI+EX_R13(r13) | ||
| 1491 | GET_SCRATCH0(r13); | ||
| 1492 | rfid | ||
| 1493 | |||
| 1494 | TRAMP_REAL_BEGIN(hrfi_flush_fallback) | ||
| 1495 | SET_SCRATCH0(r13); | ||
| 1496 | GET_PACA(r13); | ||
| 1497 | std r9,PACA_EXRFI+EX_R9(r13) | ||
| 1498 | std r10,PACA_EXRFI+EX_R10(r13) | ||
| 1499 | std r11,PACA_EXRFI+EX_R11(r13) | ||
| 1500 | std r12,PACA_EXRFI+EX_R12(r13) | ||
| 1501 | std r8,PACA_EXRFI+EX_R13(r13) | ||
| 1502 | mfctr r9 | ||
| 1503 | ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) | ||
| 1504 | ld r11,PACA_L1D_FLUSH_SETS(r13) | ||
| 1505 | ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) | ||
| 1506 | /* | ||
| 1507 | * The load adresses are at staggered offsets within cachelines, | ||
| 1508 | * which suits some pipelines better (on others it should not | ||
| 1509 | * hurt). | ||
| 1510 | */ | ||
| 1511 | addi r12,r12,8 | ||
| 1512 | mtctr r11 | ||
| 1513 | DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ | ||
| 1514 | |||
| 1515 | /* order ld/st prior to dcbt stop all streams with flushing */ | ||
| 1516 | sync | ||
| 1517 | 1: li r8,0 | ||
| 1518 | .rept 8 /* 8-way set associative */ | ||
| 1519 | ldx r11,r10,r8 | ||
| 1520 | add r8,r8,r12 | ||
| 1521 | xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not | ||
| 1522 | add r8,r8,r11 // Add 0, this creates a dependency on the ldx | ||
| 1523 | .endr | ||
| 1524 | addi r10,r10,128 /* 128 byte cache line */ | ||
| 1525 | bdnz 1b | ||
| 1526 | |||
| 1527 | mtctr r9 | ||
| 1528 | ld r9,PACA_EXRFI+EX_R9(r13) | ||
| 1529 | ld r10,PACA_EXRFI+EX_R10(r13) | ||
| 1530 | ld r11,PACA_EXRFI+EX_R11(r13) | ||
| 1531 | ld r12,PACA_EXRFI+EX_R12(r13) | ||
| 1532 | ld r8,PACA_EXRFI+EX_R13(r13) | ||
| 1533 | GET_SCRATCH0(r13); | ||
| 1534 | hrfid | ||
| 1535 | |||
| 1425 | /* | 1536 | /* |
| 1426 | * Real mode exceptions actually use this too, but alternate | 1537 | * Real mode exceptions actually use this too, but alternate |
| 1427 | * instruction code patches (which end up in the common .text area) | 1538 | * instruction code patches (which end up in the common .text area) |
| @@ -1441,7 +1552,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_interrupt) | |||
| 1441 | addi r13, r13, 4 | 1552 | addi r13, r13, 4 |
| 1442 | mtspr SPRN_SRR0, r13 | 1553 | mtspr SPRN_SRR0, r13 |
| 1443 | GET_SCRATCH0(r13) | 1554 | GET_SCRATCH0(r13) |
| 1444 | rfid | 1555 | RFI_TO_KERNEL |
| 1445 | b . | 1556 | b . |
| 1446 | 1557 | ||
| 1447 | TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt) | 1558 | TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt) |
| @@ -1453,7 +1564,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt) | |||
| 1453 | addi r13, r13, 4 | 1564 | addi r13, r13, 4 |
| 1454 | mtspr SPRN_HSRR0, r13 | 1565 | mtspr SPRN_HSRR0, r13 |
| 1455 | GET_SCRATCH0(r13) | 1566 | GET_SCRATCH0(r13) |
| 1456 | hrfid | 1567 | HRFI_TO_KERNEL |
| 1457 | b . | 1568 | b . |
| 1458 | #endif | 1569 | #endif |
| 1459 | 1570 | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 8956a9856604..491be4179ddd 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
| @@ -801,3 +801,104 @@ static int __init disable_hardlockup_detector(void) | |||
| 801 | return 0; | 801 | return 0; |
| 802 | } | 802 | } |
| 803 | early_initcall(disable_hardlockup_detector); | 803 | early_initcall(disable_hardlockup_detector); |
| 804 | |||
| 805 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 806 | static enum l1d_flush_type enabled_flush_types; | ||
| 807 | static void *l1d_flush_fallback_area; | ||
| 808 | static bool no_rfi_flush; | ||
| 809 | bool rfi_flush; | ||
| 810 | |||
| 811 | static int __init handle_no_rfi_flush(char *p) | ||
| 812 | { | ||
| 813 | pr_info("rfi-flush: disabled on command line."); | ||
| 814 | no_rfi_flush = true; | ||
| 815 | return 0; | ||
| 816 | } | ||
| 817 | early_param("no_rfi_flush", handle_no_rfi_flush); | ||
| 818 | |||
| 819 | /* | ||
| 820 | * The RFI flush is not KPTI, but because users will see doco that says to use | ||
| 821 | * nopti we hijack that option here to also disable the RFI flush. | ||
| 822 | */ | ||
| 823 | static int __init handle_no_pti(char *p) | ||
| 824 | { | ||
| 825 | pr_info("rfi-flush: disabling due to 'nopti' on command line.\n"); | ||
| 826 | handle_no_rfi_flush(NULL); | ||
| 827 | return 0; | ||
| 828 | } | ||
| 829 | early_param("nopti", handle_no_pti); | ||
| 830 | |||
| 831 | static void do_nothing(void *unused) | ||
| 832 | { | ||
| 833 | /* | ||
| 834 | * We don't need to do the flush explicitly, just enter+exit kernel is | ||
| 835 | * sufficient, the RFI exit handlers will do the right thing. | ||
| 836 | */ | ||
| 837 | } | ||
| 838 | |||
| 839 | void rfi_flush_enable(bool enable) | ||
| 840 | { | ||
| 841 | if (rfi_flush == enable) | ||
| 842 | return; | ||
| 843 | |||
| 844 | if (enable) { | ||
| 845 | do_rfi_flush_fixups(enabled_flush_types); | ||
| 846 | on_each_cpu(do_nothing, NULL, 1); | ||
| 847 | } else | ||
| 848 | do_rfi_flush_fixups(L1D_FLUSH_NONE); | ||
| 849 | |||
| 850 | rfi_flush = enable; | ||
| 851 | } | ||
| 852 | |||
| 853 | static void init_fallback_flush(void) | ||
| 854 | { | ||
| 855 | u64 l1d_size, limit; | ||
| 856 | int cpu; | ||
| 857 | |||
| 858 | l1d_size = ppc64_caches.l1d.size; | ||
| 859 | limit = min(safe_stack_limit(), ppc64_rma_size); | ||
| 860 | |||
| 861 | /* | ||
| 862 | * Align to L1d size, and size it at 2x L1d size, to catch possible | ||
| 863 | * hardware prefetch runoff. We don't have a recipe for load patterns to | ||
| 864 | * reliably avoid the prefetcher. | ||
| 865 | */ | ||
| 866 | l1d_flush_fallback_area = __va(memblock_alloc_base(l1d_size * 2, l1d_size, limit)); | ||
| 867 | memset(l1d_flush_fallback_area, 0, l1d_size * 2); | ||
| 868 | |||
| 869 | for_each_possible_cpu(cpu) { | ||
| 870 | /* | ||
| 871 | * The fallback flush is currently coded for 8-way | ||
| 872 | * associativity. Different associativity is possible, but it | ||
| 873 | * will be treated as 8-way and may not evict the lines as | ||
| 874 | * effectively. | ||
| 875 | * | ||
| 876 | * 128 byte lines are mandatory. | ||
| 877 | */ | ||
| 878 | u64 c = l1d_size / 8; | ||
| 879 | |||
| 880 | paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area; | ||
| 881 | paca[cpu].l1d_flush_congruence = c; | ||
| 882 | paca[cpu].l1d_flush_sets = c / 128; | ||
| 883 | } | ||
| 884 | } | ||
| 885 | |||
| 886 | void __init setup_rfi_flush(enum l1d_flush_type types, bool enable) | ||
| 887 | { | ||
| 888 | if (types & L1D_FLUSH_FALLBACK) { | ||
| 889 | pr_info("rfi-flush: Using fallback displacement flush\n"); | ||
| 890 | init_fallback_flush(); | ||
| 891 | } | ||
| 892 | |||
| 893 | if (types & L1D_FLUSH_ORI) | ||
| 894 | pr_info("rfi-flush: Using ori type flush\n"); | ||
| 895 | |||
| 896 | if (types & L1D_FLUSH_MTTRIG) | ||
| 897 | pr_info("rfi-flush: Using mttrig type flush\n"); | ||
| 898 | |||
| 899 | enabled_flush_types = types; | ||
| 900 | |||
| 901 | if (!no_rfi_flush) | ||
| 902 | rfi_flush_enable(enable); | ||
| 903 | } | ||
| 904 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 0494e1566ee2..307843d23682 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S | |||
| @@ -132,6 +132,15 @@ SECTIONS | |||
| 132 | /* Read-only data */ | 132 | /* Read-only data */ |
| 133 | RO_DATA(PAGE_SIZE) | 133 | RO_DATA(PAGE_SIZE) |
| 134 | 134 | ||
| 135 | #ifdef CONFIG_PPC64 | ||
| 136 | . = ALIGN(8); | ||
| 137 | __rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) { | ||
| 138 | __start___rfi_flush_fixup = .; | ||
| 139 | *(__rfi_flush_fixup) | ||
| 140 | __stop___rfi_flush_fixup = .; | ||
| 141 | } | ||
| 142 | #endif | ||
| 143 | |||
| 135 | EXCEPTION_TABLE(0) | 144 | EXCEPTION_TABLE(0) |
| 136 | 145 | ||
| 137 | NOTES :kernel :notes | 146 | NOTES :kernel :notes |
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 2659844784b8..9c61f736c75b 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
| @@ -79,7 +79,7 @@ _GLOBAL_TOC(kvmppc_hv_entry_trampoline) | |||
| 79 | mtmsrd r0,1 /* clear RI in MSR */ | 79 | mtmsrd r0,1 /* clear RI in MSR */ |
| 80 | mtsrr0 r5 | 80 | mtsrr0 r5 |
| 81 | mtsrr1 r6 | 81 | mtsrr1 r6 |
| 82 | RFI | 82 | RFI_TO_KERNEL |
| 83 | 83 | ||
| 84 | kvmppc_call_hv_entry: | 84 | kvmppc_call_hv_entry: |
| 85 | BEGIN_FTR_SECTION | 85 | BEGIN_FTR_SECTION |
| @@ -199,7 +199,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | |||
| 199 | mtmsrd r6, 1 /* Clear RI in MSR */ | 199 | mtmsrd r6, 1 /* Clear RI in MSR */ |
| 200 | mtsrr0 r8 | 200 | mtsrr0 r8 |
| 201 | mtsrr1 r7 | 201 | mtsrr1 r7 |
| 202 | RFI | 202 | RFI_TO_KERNEL |
| 203 | 203 | ||
| 204 | /* Virtual-mode return */ | 204 | /* Virtual-mode return */ |
| 205 | .Lvirt_return: | 205 | .Lvirt_return: |
| @@ -1167,8 +1167,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) | |||
| 1167 | 1167 | ||
| 1168 | ld r0, VCPU_GPR(R0)(r4) | 1168 | ld r0, VCPU_GPR(R0)(r4) |
| 1169 | ld r4, VCPU_GPR(R4)(r4) | 1169 | ld r4, VCPU_GPR(R4)(r4) |
| 1170 | 1170 | HRFI_TO_GUEST | |
| 1171 | hrfid | ||
| 1172 | b . | 1171 | b . |
| 1173 | 1172 | ||
| 1174 | secondary_too_late: | 1173 | secondary_too_late: |
| @@ -3320,7 +3319,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX) | |||
| 3320 | ld r4, PACAKMSR(r13) | 3319 | ld r4, PACAKMSR(r13) |
| 3321 | mtspr SPRN_SRR0, r3 | 3320 | mtspr SPRN_SRR0, r3 |
| 3322 | mtspr SPRN_SRR1, r4 | 3321 | mtspr SPRN_SRR1, r4 |
| 3323 | rfid | 3322 | RFI_TO_KERNEL |
| 3324 | 9: addi r3, r1, STACK_FRAME_OVERHEAD | 3323 | 9: addi r3, r1, STACK_FRAME_OVERHEAD |
| 3325 | bl kvmppc_bad_interrupt | 3324 | bl kvmppc_bad_interrupt |
| 3326 | b 9b | 3325 | b 9b |
diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S index 42a4b237df5f..34a5adeff084 100644 --- a/arch/powerpc/kvm/book3s_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_rmhandlers.S | |||
| @@ -46,6 +46,9 @@ | |||
| 46 | 46 | ||
| 47 | #define FUNC(name) name | 47 | #define FUNC(name) name |
| 48 | 48 | ||
| 49 | #define RFI_TO_KERNEL RFI | ||
| 50 | #define RFI_TO_GUEST RFI | ||
| 51 | |||
| 49 | .macro INTERRUPT_TRAMPOLINE intno | 52 | .macro INTERRUPT_TRAMPOLINE intno |
| 50 | 53 | ||
| 51 | .global kvmppc_trampoline_\intno | 54 | .global kvmppc_trampoline_\intno |
| @@ -141,7 +144,7 @@ kvmppc_handler_skip_ins: | |||
| 141 | GET_SCRATCH0(r13) | 144 | GET_SCRATCH0(r13) |
| 142 | 145 | ||
| 143 | /* And get back into the code */ | 146 | /* And get back into the code */ |
| 144 | RFI | 147 | RFI_TO_KERNEL |
| 145 | #endif | 148 | #endif |
| 146 | 149 | ||
| 147 | /* | 150 | /* |
| @@ -164,6 +167,6 @@ _GLOBAL_TOC(kvmppc_entry_trampoline) | |||
| 164 | ori r5, r5, MSR_EE | 167 | ori r5, r5, MSR_EE |
| 165 | mtsrr0 r7 | 168 | mtsrr0 r7 |
| 166 | mtsrr1 r6 | 169 | mtsrr1 r6 |
| 167 | RFI | 170 | RFI_TO_KERNEL |
| 168 | 171 | ||
| 169 | #include "book3s_segment.S" | 172 | #include "book3s_segment.S" |
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S index 2a2b96d53999..93a180ceefad 100644 --- a/arch/powerpc/kvm/book3s_segment.S +++ b/arch/powerpc/kvm/book3s_segment.S | |||
| @@ -156,7 +156,7 @@ no_dcbz32_on: | |||
| 156 | PPC_LL r9, SVCPU_R9(r3) | 156 | PPC_LL r9, SVCPU_R9(r3) |
| 157 | PPC_LL r3, (SVCPU_R3)(r3) | 157 | PPC_LL r3, (SVCPU_R3)(r3) |
| 158 | 158 | ||
| 159 | RFI | 159 | RFI_TO_GUEST |
| 160 | kvmppc_handler_trampoline_enter_end: | 160 | kvmppc_handler_trampoline_enter_end: |
| 161 | 161 | ||
| 162 | 162 | ||
| @@ -407,5 +407,5 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) | |||
| 407 | cmpwi r12, BOOK3S_INTERRUPT_DOORBELL | 407 | cmpwi r12, BOOK3S_INTERRUPT_DOORBELL |
| 408 | beqa BOOK3S_INTERRUPT_DOORBELL | 408 | beqa BOOK3S_INTERRUPT_DOORBELL |
| 409 | 409 | ||
| 410 | RFI | 410 | RFI_TO_KERNEL |
| 411 | kvmppc_handler_trampoline_exit_end: | 411 | kvmppc_handler_trampoline_exit_end: |
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 41cf5ae273cf..a95ea007d654 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c | |||
| @@ -116,6 +116,47 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end) | |||
| 116 | } | 116 | } |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
| 120 | void do_rfi_flush_fixups(enum l1d_flush_type types) | ||
| 121 | { | ||
| 122 | unsigned int instrs[3], *dest; | ||
| 123 | long *start, *end; | ||
| 124 | int i; | ||
| 125 | |||
| 126 | start = PTRRELOC(&__start___rfi_flush_fixup), | ||
| 127 | end = PTRRELOC(&__stop___rfi_flush_fixup); | ||
| 128 | |||
| 129 | instrs[0] = 0x60000000; /* nop */ | ||
| 130 | instrs[1] = 0x60000000; /* nop */ | ||
| 131 | instrs[2] = 0x60000000; /* nop */ | ||
| 132 | |||
| 133 | if (types & L1D_FLUSH_FALLBACK) | ||
| 134 | /* b .+16 to fallback flush */ | ||
| 135 | instrs[0] = 0x48000010; | ||
| 136 | |||
| 137 | i = 0; | ||
| 138 | if (types & L1D_FLUSH_ORI) { | ||
| 139 | instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */ | ||
| 140 | instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/ | ||
| 141 | } | ||
| 142 | |||
| 143 | if (types & L1D_FLUSH_MTTRIG) | ||
| 144 | instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */ | ||
| 145 | |||
| 146 | for (i = 0; start < end; start++, i++) { | ||
| 147 | dest = (void *)start + *start; | ||
| 148 | |||
| 149 | pr_devel("patching dest %lx\n", (unsigned long)dest); | ||
| 150 | |||
| 151 | patch_instruction(dest, instrs[0]); | ||
| 152 | patch_instruction(dest + 1, instrs[1]); | ||
| 153 | patch_instruction(dest + 2, instrs[2]); | ||
| 154 | } | ||
| 155 | |||
| 156 | printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i); | ||
| 157 | } | ||
| 158 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
| 159 | |||
| 119 | void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) | 160 | void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) |
| 120 | { | 161 | { |
| 121 | long *start, *end; | 162 | long *start, *end; |
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 1edfbc1e40f4..4fb21e17504a 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c | |||
| @@ -37,13 +37,62 @@ | |||
| 37 | #include <asm/kexec.h> | 37 | #include <asm/kexec.h> |
| 38 | #include <asm/smp.h> | 38 | #include <asm/smp.h> |
| 39 | #include <asm/tm.h> | 39 | #include <asm/tm.h> |
| 40 | #include <asm/setup.h> | ||
| 40 | 41 | ||
| 41 | #include "powernv.h" | 42 | #include "powernv.h" |
| 42 | 43 | ||
| 44 | static void pnv_setup_rfi_flush(void) | ||
| 45 | { | ||
| 46 | struct device_node *np, *fw_features; | ||
| 47 | enum l1d_flush_type type; | ||
| 48 | int enable; | ||
| 49 | |||
| 50 | /* Default to fallback in case fw-features are not available */ | ||
| 51 | type = L1D_FLUSH_FALLBACK; | ||
| 52 | enable = 1; | ||
| 53 | |||
| 54 | np = of_find_node_by_name(NULL, "ibm,opal"); | ||
| 55 | fw_features = of_get_child_by_name(np, "fw-features"); | ||
| 56 | of_node_put(np); | ||
| 57 | |||
| 58 | if (fw_features) { | ||
| 59 | np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2"); | ||
| 60 | if (np && of_property_read_bool(np, "enabled")) | ||
| 61 | type = L1D_FLUSH_MTTRIG; | ||
| 62 | |||
| 63 | of_node_put(np); | ||
| 64 | |||
| 65 | np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0"); | ||
| 66 | if (np && of_property_read_bool(np, "enabled")) | ||
| 67 | type = L1D_FLUSH_ORI; | ||
| 68 | |||
| 69 | of_node_put(np); | ||
| 70 | |||
| 71 | /* Enable unless firmware says NOT to */ | ||
| 72 | enable = 2; | ||
| 73 | np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0"); | ||
| 74 | if (np && of_property_read_bool(np, "disabled")) | ||
| 75 | enable--; | ||
| 76 | |||
| 77 | of_node_put(np); | ||
| 78 | |||
| 79 | np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-pr-0-to-1"); | ||
| 80 | if (np && of_property_read_bool(np, "disabled")) | ||
| 81 | enable--; | ||
| 82 | |||
| 83 | of_node_put(np); | ||
| 84 | of_node_put(fw_features); | ||
| 85 | } | ||
| 86 | |||
| 87 | setup_rfi_flush(type, enable > 0); | ||
| 88 | } | ||
| 89 | |||
| 43 | static void __init pnv_setup_arch(void) | 90 | static void __init pnv_setup_arch(void) |
| 44 | { | 91 | { |
| 45 | set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); | 92 | set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); |
| 46 | 93 | ||
| 94 | pnv_setup_rfi_flush(); | ||
| 95 | |||
| 47 | /* Initialize SMP */ | 96 | /* Initialize SMP */ |
| 48 | pnv_smp_init(); | 97 | pnv_smp_init(); |
| 49 | 98 | ||
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 6e35780c5962..a0b20c03f078 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c | |||
| @@ -574,11 +574,26 @@ static ssize_t dlpar_show(struct class *class, struct class_attribute *attr, | |||
| 574 | 574 | ||
| 575 | static CLASS_ATTR_RW(dlpar); | 575 | static CLASS_ATTR_RW(dlpar); |
| 576 | 576 | ||
| 577 | static int __init pseries_dlpar_init(void) | 577 | int __init dlpar_workqueue_init(void) |
| 578 | { | 578 | { |
| 579 | if (pseries_hp_wq) | ||
| 580 | return 0; | ||
| 581 | |||
| 579 | pseries_hp_wq = alloc_workqueue("pseries hotplug workqueue", | 582 | pseries_hp_wq = alloc_workqueue("pseries hotplug workqueue", |
| 580 | WQ_UNBOUND, 1); | 583 | WQ_UNBOUND, 1); |
| 584 | |||
| 585 | return pseries_hp_wq ? 0 : -ENOMEM; | ||
| 586 | } | ||
| 587 | |||
| 588 | static int __init dlpar_sysfs_init(void) | ||
| 589 | { | ||
| 590 | int rc; | ||
| 591 | |||
| 592 | rc = dlpar_workqueue_init(); | ||
| 593 | if (rc) | ||
| 594 | return rc; | ||
| 595 | |||
| 581 | return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr); | 596 | return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr); |
| 582 | } | 597 | } |
| 583 | machine_device_initcall(pseries, pseries_dlpar_init); | 598 | machine_device_initcall(pseries, dlpar_sysfs_init); |
| 584 | 599 | ||
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 4470a3194311..1ae1d9f4dbe9 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
| @@ -98,4 +98,6 @@ static inline unsigned long cmo_get_page_size(void) | |||
| 98 | return CMO_PageSize; | 98 | return CMO_PageSize; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | int dlpar_workqueue_init(void); | ||
| 102 | |||
| 101 | #endif /* _PSERIES_PSERIES_H */ | 103 | #endif /* _PSERIES_PSERIES_H */ |
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 4923ffe230cf..81d8614e7379 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c | |||
| @@ -69,7 +69,8 @@ static int __init init_ras_IRQ(void) | |||
| 69 | /* Hotplug Events */ | 69 | /* Hotplug Events */ |
| 70 | np = of_find_node_by_path("/event-sources/hot-plug-events"); | 70 | np = of_find_node_by_path("/event-sources/hot-plug-events"); |
| 71 | if (np != NULL) { | 71 | if (np != NULL) { |
| 72 | request_event_sources_irqs(np, ras_hotplug_interrupt, | 72 | if (dlpar_workqueue_init() == 0) |
| 73 | request_event_sources_irqs(np, ras_hotplug_interrupt, | ||
| 73 | "RAS_HOTPLUG"); | 74 | "RAS_HOTPLUG"); |
| 74 | of_node_put(np); | 75 | of_node_put(np); |
| 75 | } | 76 | } |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index a8531e012658..ae4f596273b5 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
| @@ -459,6 +459,39 @@ static void __init find_and_init_phbs(void) | |||
| 459 | of_pci_check_probe_only(); | 459 | of_pci_check_probe_only(); |
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | static void pseries_setup_rfi_flush(void) | ||
| 463 | { | ||
| 464 | struct h_cpu_char_result result; | ||
| 465 | enum l1d_flush_type types; | ||
| 466 | bool enable; | ||
| 467 | long rc; | ||
| 468 | |||
| 469 | /* Enable by default */ | ||
| 470 | enable = true; | ||
| 471 | |||
| 472 | rc = plpar_get_cpu_characteristics(&result); | ||
| 473 | if (rc == H_SUCCESS) { | ||
| 474 | types = L1D_FLUSH_NONE; | ||
| 475 | |||
| 476 | if (result.character & H_CPU_CHAR_L1D_FLUSH_TRIG2) | ||
| 477 | types |= L1D_FLUSH_MTTRIG; | ||
| 478 | if (result.character & H_CPU_CHAR_L1D_FLUSH_ORI30) | ||
| 479 | types |= L1D_FLUSH_ORI; | ||
| 480 | |||
| 481 | /* Use fallback if nothing set in hcall */ | ||
| 482 | if (types == L1D_FLUSH_NONE) | ||
| 483 | types = L1D_FLUSH_FALLBACK; | ||
| 484 | |||
| 485 | if (!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR)) | ||
| 486 | enable = false; | ||
| 487 | } else { | ||
| 488 | /* Default to fallback if case hcall is not available */ | ||
| 489 | types = L1D_FLUSH_FALLBACK; | ||
| 490 | } | ||
| 491 | |||
| 492 | setup_rfi_flush(types, enable); | ||
| 493 | } | ||
| 494 | |||
| 462 | static void __init pSeries_setup_arch(void) | 495 | static void __init pSeries_setup_arch(void) |
| 463 | { | 496 | { |
| 464 | set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); | 497 | set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); |
| @@ -476,6 +509,8 @@ static void __init pSeries_setup_arch(void) | |||
| 476 | 509 | ||
| 477 | fwnmi_init(); | 510 | fwnmi_init(); |
| 478 | 511 | ||
| 512 | pseries_setup_rfi_flush(); | ||
| 513 | |||
| 479 | /* By default, only probe PCI (can be overridden by rtas_pci) */ | 514 | /* By default, only probe PCI (can be overridden by rtas_pci) */ |
| 480 | pci_add_flags(PCI_PROBE_ONLY); | 515 | pci_add_flags(PCI_PROBE_ONLY); |
| 481 | 516 | ||
