From: Greg Kroah-Hartman Date: Sun, 4 Feb 2018 11:08:33 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v3.18.94~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cf83516028a4e8907be657362e9c06e53d14e129;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: powerpc-64-add-macros-for-annotating-the-destination-of-rfid-hrfid.patch powerpc-64-convert-fast_exception_return-to-use-rfi_to_user-kernel.patch powerpc-64-convert-the-syscall-exit-path-to-use-rfi_to_user-kernel.patch powerpc-64s-add-support-for-rfi-flush-of-l1-d-cache.patch powerpc-64s-allow-control-of-rfi-flush-via-debugfs.patch powerpc-64s-convert-slb_miss_common-to-use-rfi_to_user-kernel.patch powerpc-64s-support-disabling-rfi-flush-with-no_rfi_flush-and-nopti.patch powerpc-64s-wire-up-cpu_show_meltdown.patch powerpc-powernv-check-device-tree-for-rfi-flush-settings.patch powerpc-pseries-add-h_get_cpu_characteristics-flags-wrapper.patch powerpc-pseries-query-hypervisor-for-rfi-flush-settings.patch --- diff --git a/queue-4.9/powerpc-64-add-macros-for-annotating-the-destination-of-rfid-hrfid.patch b/queue-4.9/powerpc-64-add-macros-for-annotating-the-destination-of-rfid-hrfid.patch new file mode 100644 index 00000000000..134590c6614 --- /dev/null +++ b/queue-4.9/powerpc-64-add-macros-for-annotating-the-destination-of-rfid-hrfid.patch @@ -0,0 +1,80 @@ +From 50e51c13b3822d14ff6df4279423e4b7b2269bc3 Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Wed, 10 Jan 2018 03:07:15 +1100 +Subject: powerpc/64: Add macros for annotating the destination of rfid/hrfid + +From: Nicholas Piggin + +commit 50e51c13b3822d14ff6df4279423e4b7b2269bc3 upstream. + +The rfid/hrfid ((Hypervisor) Return From Interrupt) instruction is +used for switching from the kernel to userspace, and from the +hypervisor to the guest kernel. However it can and is also used for +other transitions, eg. from real mode kernel code to virtual mode +kernel code, and it's not always clear from the code what the +destination context is. + +To make it clearer when reading the code, add macros which encode the +expected destination context. + +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/exception-64e.h | 6 ++++++ + arch/powerpc/include/asm/exception-64s.h | 29 +++++++++++++++++++++++++++++ + 2 files changed, 35 insertions(+) + +--- a/arch/powerpc/include/asm/exception-64e.h ++++ b/arch/powerpc/include/asm/exception-64e.h +@@ -209,5 +209,11 @@ exc_##label##_book3e: + ori r3,r3,vector_offset@l; \ + mtspr SPRN_IVOR##vector_number,r3; + ++#define RFI_TO_KERNEL \ ++ rfi ++ ++#define RFI_TO_USER \ ++ rfi ++ + #endif /* _ASM_POWERPC_EXCEPTION_64E_H */ + +--- a/arch/powerpc/include/asm/exception-64s.h ++++ b/arch/powerpc/include/asm/exception-64s.h +@@ -51,6 +51,35 @@ + #define EX_PPR 88 /* SMT thread status register (priority) */ + #define EX_CTR 96 + ++/* Macros for annotating the expected destination of (h)rfid */ ++ ++#define RFI_TO_KERNEL \ ++ rfid ++ ++#define RFI_TO_USER \ ++ rfid ++ ++#define RFI_TO_USER_OR_KERNEL \ ++ rfid ++ ++#define RFI_TO_GUEST \ ++ rfid ++ ++#define HRFI_TO_KERNEL \ ++ hrfid ++ ++#define HRFI_TO_USER \ ++ hrfid ++ ++#define HRFI_TO_USER_OR_KERNEL \ ++ hrfid ++ ++#define HRFI_TO_GUEST \ ++ hrfid ++ ++#define HRFI_TO_UNKNOWN \ ++ hrfid ++ + #ifdef CONFIG_RELOCATABLE + #define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \ + mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ diff --git a/queue-4.9/powerpc-64-convert-fast_exception_return-to-use-rfi_to_user-kernel.patch b/queue-4.9/powerpc-64-convert-fast_exception_return-to-use-rfi_to_user-kernel.patch new file mode 100644 index 00000000000..8f14d198680 --- /dev/null +++ b/queue-4.9/powerpc-64-convert-fast_exception_return-to-use-rfi_to_user-kernel.patch @@ -0,0 +1,57 @@ +From a08f828cf47e6c605af21d2cdec68f84e799c318 Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Wed, 10 Jan 2018 03:07:15 +1100 +Subject: powerpc/64: Convert fast_exception_return to use RFI_TO_USER/KERNEL + +From: Nicholas Piggin + +commit a08f828cf47e6c605af21d2cdec68f84e799c318 upstream. + +Similar to the syscall return path, in fast_exception_return we may be +returning to user or kernel context. We already have a test for that, +because we conditionally restore r13. So use that existing test and +branch, and bifurcate the return based on that. + +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/entry_64.S | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/kernel/entry_64.S ++++ b/arch/powerpc/kernel/entry_64.S +@@ -859,7 +859,7 @@ BEGIN_FTR_SECTION + END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + ACCOUNT_CPU_USER_EXIT(r13, r2, r4) + REST_GPR(13, r1) +-1: ++ + mtspr SPRN_SRR1,r3 + + ld r2,_CCR(r1) +@@ -872,8 +872,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + ld r3,GPR3(r1) + ld r4,GPR4(r1) + ld r1,GPR1(r1) ++ RFI_TO_USER ++ b . /* prevent speculative execution */ + +- rfid ++1: mtspr SPRN_SRR1,r3 ++ ++ ld r2,_CCR(r1) ++ mtcrf 0xFF,r2 ++ ld r2,_NIP(r1) ++ mtspr SPRN_SRR0,r2 ++ ++ ld r0,GPR0(r1) ++ ld r2,GPR2(r1) ++ ld r3,GPR3(r1) ++ ld r4,GPR4(r1) ++ ld r1,GPR1(r1) ++ RFI_TO_KERNEL + b . /* prevent speculative execution */ + + #endif /* CONFIG_PPC_BOOK3E */ diff --git a/queue-4.9/powerpc-64-convert-the-syscall-exit-path-to-use-rfi_to_user-kernel.patch b/queue-4.9/powerpc-64-convert-the-syscall-exit-path-to-use-rfi_to_user-kernel.patch new file mode 100644 index 00000000000..839ff0600f8 --- /dev/null +++ b/queue-4.9/powerpc-64-convert-the-syscall-exit-path-to-use-rfi_to_user-kernel.patch @@ -0,0 +1,49 @@ +From b8e90cb7bc04a509e821e82ab6ed7a8ef11ba333 Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Wed, 10 Jan 2018 03:07:15 +1100 +Subject: powerpc/64: Convert the syscall exit path to use RFI_TO_USER/KERNEL + +From: Nicholas Piggin + +commit b8e90cb7bc04a509e821e82ab6ed7a8ef11ba333 upstream. + +In the syscall exit path we may be returning to user or kernel +context. We already have a test for that, because we conditionally +restore r13. So use that existing test and branch, and bifurcate the +return based on that. + +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/entry_64.S | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/entry_64.S ++++ b/arch/powerpc/kernel/entry_64.S +@@ -251,13 +251,23 @@ BEGIN_FTR_SECTION + END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + + ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ ++ ld r2,GPR2(r1) ++ ld r1,GPR1(r1) ++ mtlr r4 ++ mtcr r5 ++ mtspr SPRN_SRR0,r7 ++ mtspr SPRN_SRR1,r8 ++ RFI_TO_USER ++ b . /* prevent speculative execution */ ++ ++ /* exit to kernel */ + 1: ld r2,GPR2(r1) + ld r1,GPR1(r1) + mtlr r4 + mtcr r5 + mtspr SPRN_SRR0,r7 + mtspr SPRN_SRR1,r8 +- RFI ++ RFI_TO_KERNEL + b . /* prevent speculative execution */ + + syscall_error: diff --git a/queue-4.9/powerpc-64s-add-support-for-rfi-flush-of-l1-d-cache.patch b/queue-4.9/powerpc-64s-add-support-for-rfi-flush-of-l1-d-cache.patch new file mode 100644 index 00000000000..af7927eaf2a --- /dev/null +++ b/queue-4.9/powerpc-64s-add-support-for-rfi-flush-of-l1-d-cache.patch @@ -0,0 +1,469 @@ +From aa8a5e0062ac940f7659394f4817c948dc8c0667 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Wed, 10 Jan 2018 03:07:15 +1100 +Subject: powerpc/64s: Add support for RFI flush of L1-D cache + +From: Michael Ellerman + +commit aa8a5e0062ac940f7659394f4817c948dc8c0667 upstream. + +On some CPUs we can prevent the Meltdown vulnerability by flushing the +L1-D cache on exit from kernel to user mode, and from hypervisor to +guest. + +This is known to be the case on at least Power7, Power8 and Power9. At +this time we do not know the status of the vulnerability on other CPUs +such as the 970 (Apple G5), pasemi CPUs (AmigaOne X1000) or Freescale +CPUs. As more information comes to light we can enable this, or other +mechanisms on those CPUs. + +The vulnerability occurs when the load of an architecturally +inaccessible memory region (eg. userspace load of kernel memory) is +speculatively executed to the point where its result can influence the +address of a subsequent speculatively executed load. + +In order for that to happen, the first load must hit in the L1, +because before the load is sent to the L2 the permission check is +performed. Therefore if no kernel addresses hit in the L1 the +vulnerability can not occur. We can ensure that is the case by +flushing the L1 whenever we return to userspace. Similarly for +hypervisor vs guest. + +In order to flush the L1-D cache on exit, we add a section of nops at +each (h)rfi location that returns to a lower privileged context, and +patch that with some sequence. Newer firmwares are able to advertise +to us that there is a special nop instruction that flushes the L1-D. +If we do not see that advertised, we fall back to doing a displacement +flush in software. + +For guest kernels we support migration between some CPU versions, and +different CPUs may use different flush instructions. So that we are +prepared to migrate to a machine with a different flush instruction +activated, we may have to patch more than one flush instruction at +boot if the hypervisor tells us to. + +In the end this patch is mostly the work of Nicholas Piggin and +Michael Ellerman. However a cast of thousands contributed to analysis +of the issue, earlier versions of the patch, back ports testing etc. +Many thanks to all of them. + +Tested-by: Jon Masters +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +[Balbir - back ported to stable with changes] +Signed-off-by: Balbir Singh +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/include/asm/exception-64s.h | 40 +++++++++++-- + arch/powerpc/include/asm/feature-fixups.h | 15 +++++ + arch/powerpc/include/asm/paca.h | 10 +++ + arch/powerpc/include/asm/setup.h | 13 ++++ + arch/powerpc/kernel/asm-offsets.c | 4 + + arch/powerpc/kernel/exceptions-64s.S | 86 ++++++++++++++++++++++++++++++ + arch/powerpc/kernel/setup_64.c | 79 +++++++++++++++++++++++++++ + arch/powerpc/kernel/vmlinux.lds.S | 9 +++ + arch/powerpc/lib/feature-fixups.c | 42 ++++++++++++++ + 9 files changed, 290 insertions(+), 8 deletions(-) + +--- a/arch/powerpc/include/asm/exception-64s.h ++++ b/arch/powerpc/include/asm/exception-64s.h +@@ -51,34 +51,58 @@ + #define EX_PPR 88 /* SMT thread status register (priority) */ + #define EX_CTR 96 + +-/* Macros for annotating the expected destination of (h)rfid */ ++/* ++ * Macros for annotating the expected destination of (h)rfid ++ * ++ * The nop instructions allow us to insert one or more instructions to flush the ++ * L1-D cache when returning to userspace or a guest. ++ */ ++#define RFI_FLUSH_SLOT \ ++ RFI_FLUSH_FIXUP_SECTION; \ ++ nop; \ ++ nop; \ ++ nop + + #define RFI_TO_KERNEL \ + rfid + + #define RFI_TO_USER \ +- rfid ++ RFI_FLUSH_SLOT; \ ++ rfid; \ ++ b rfi_flush_fallback + + #define RFI_TO_USER_OR_KERNEL \ +- rfid ++ RFI_FLUSH_SLOT; \ ++ rfid; \ ++ b rfi_flush_fallback + + #define RFI_TO_GUEST \ +- rfid ++ RFI_FLUSH_SLOT; \ ++ rfid; \ ++ b rfi_flush_fallback + + #define HRFI_TO_KERNEL \ + hrfid + + #define HRFI_TO_USER \ +- hrfid ++ RFI_FLUSH_SLOT; \ ++ hrfid; \ ++ b hrfi_flush_fallback + + #define HRFI_TO_USER_OR_KERNEL \ +- hrfid ++ RFI_FLUSH_SLOT; \ ++ hrfid; \ ++ b hrfi_flush_fallback + + #define HRFI_TO_GUEST \ +- hrfid ++ RFI_FLUSH_SLOT; \ ++ hrfid; \ ++ b hrfi_flush_fallback + + #define HRFI_TO_UNKNOWN \ +- hrfid ++ RFI_FLUSH_SLOT; \ ++ hrfid; \ ++ b hrfi_flush_fallback + + #ifdef CONFIG_RELOCATABLE + #define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \ +--- a/arch/powerpc/include/asm/feature-fixups.h ++++ b/arch/powerpc/include/asm/feature-fixups.h +@@ -189,4 +189,19 @@ void apply_feature_fixups(void); + void setup_feature_keys(void); + #endif + ++#define RFI_FLUSH_FIXUP_SECTION \ ++951: \ ++ .pushsection __rfi_flush_fixup,"a"; \ ++ .align 2; \ ++952: \ ++ FTR_ENTRY_OFFSET 951b-952b; \ ++ .popsection; ++ ++ ++#ifndef __ASSEMBLY__ ++ ++extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; ++ ++#endif ++ + #endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */ +--- a/arch/powerpc/include/asm/paca.h ++++ b/arch/powerpc/include/asm/paca.h +@@ -205,6 +205,16 @@ struct paca_struct { + struct sibling_subcore_state *sibling_subcore_state; + #endif + #endif ++#ifdef CONFIG_PPC_BOOK3S_64 ++ /* ++ * rfi fallback flush must be in its own cacheline to prevent ++ * other paca data leaking into the L1d ++ */ ++ u64 exrfi[13] __aligned(0x80); ++ void *rfi_flush_fallback_area; ++ u64 l1d_flush_congruence; ++ u64 l1d_flush_sets; ++#endif + }; + + #ifdef CONFIG_PPC_BOOK3S +--- a/arch/powerpc/include/asm/setup.h ++++ b/arch/powerpc/include/asm/setup.h +@@ -38,6 +38,19 @@ static inline void pseries_big_endian_ex + static inline void pseries_little_endian_exceptions(void) {} + #endif /* CONFIG_PPC_PSERIES */ + ++void rfi_flush_enable(bool enable); ++ ++/* These are bit flags */ ++enum l1d_flush_type { ++ L1D_FLUSH_NONE = 0x1, ++ L1D_FLUSH_FALLBACK = 0x2, ++ L1D_FLUSH_ORI = 0x4, ++ L1D_FLUSH_MTTRIG = 0x8, ++}; ++ ++void __init setup_rfi_flush(enum l1d_flush_type, bool enable); ++void do_rfi_flush_fixups(enum l1d_flush_type types); ++ + #endif /* !__ASSEMBLY__ */ + + #endif /* _ASM_POWERPC_SETUP_H */ +--- a/arch/powerpc/kernel/asm-offsets.c ++++ b/arch/powerpc/kernel/asm-offsets.c +@@ -240,6 +240,10 @@ int main(void) + #ifdef CONFIG_PPC_BOOK3S_64 + DEFINE(PACAMCEMERGSP, offsetof(struct paca_struct, mc_emergency_sp)); + DEFINE(PACA_IN_MCE, offsetof(struct paca_struct, in_mce)); ++ DEFINE(PACA_RFI_FLUSH_FALLBACK_AREA, offsetof(struct paca_struct, rfi_flush_fallback_area)); ++ DEFINE(PACA_EXRFI, offsetof(struct paca_struct, exrfi)); ++ DEFINE(PACA_L1D_FLUSH_CONGRUENCE, offsetof(struct paca_struct, l1d_flush_congruence)); ++ DEFINE(PACA_L1D_FLUSH_SETS, offsetof(struct paca_struct, l1d_flush_sets)); + #endif + DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); + DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state)); +--- a/arch/powerpc/kernel/exceptions-64s.S ++++ b/arch/powerpc/kernel/exceptions-64s.S +@@ -1594,6 +1594,92 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) + bl kernel_bad_stack + b 1b + ++ .globl rfi_flush_fallback ++rfi_flush_fallback: ++ SET_SCRATCH0(r13); ++ GET_PACA(r13); ++ std r9,PACA_EXRFI+EX_R9(r13) ++ std r10,PACA_EXRFI+EX_R10(r13) ++ std r11,PACA_EXRFI+EX_R11(r13) ++ std r12,PACA_EXRFI+EX_R12(r13) ++ std r8,PACA_EXRFI+EX_R13(r13) ++ mfctr r9 ++ ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) ++ ld r11,PACA_L1D_FLUSH_SETS(r13) ++ ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) ++ /* ++ * The load adresses are at staggered offsets within cachelines, ++ * which suits some pipelines better (on others it should not ++ * hurt). ++ */ ++ addi r12,r12,8 ++ mtctr r11 ++ DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ ++ ++ /* order ld/st prior to dcbt stop all streams with flushing */ ++ sync ++1: li r8,0 ++ .rept 8 /* 8-way set associative */ ++ ldx r11,r10,r8 ++ add r8,r8,r12 ++ xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not ++ add r8,r8,r11 // Add 0, this creates a dependency on the ldx ++ .endr ++ addi r10,r10,128 /* 128 byte cache line */ ++ bdnz 1b ++ ++ mtctr r9 ++ ld r9,PACA_EXRFI+EX_R9(r13) ++ ld r10,PACA_EXRFI+EX_R10(r13) ++ ld r11,PACA_EXRFI+EX_R11(r13) ++ ld r12,PACA_EXRFI+EX_R12(r13) ++ ld r8,PACA_EXRFI+EX_R13(r13) ++ GET_SCRATCH0(r13); ++ rfid ++ ++ .globl hrfi_flush_fallback ++hrfi_flush_fallback: ++ SET_SCRATCH0(r13); ++ GET_PACA(r13); ++ std r9,PACA_EXRFI+EX_R9(r13) ++ std r10,PACA_EXRFI+EX_R10(r13) ++ std r11,PACA_EXRFI+EX_R11(r13) ++ std r12,PACA_EXRFI+EX_R12(r13) ++ std r8,PACA_EXRFI+EX_R13(r13) ++ mfctr r9 ++ ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) ++ ld r11,PACA_L1D_FLUSH_SETS(r13) ++ ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) ++ /* ++ * The load adresses are at staggered offsets within cachelines, ++ * which suits some pipelines better (on others it should not ++ * hurt). ++ */ ++ addi r12,r12,8 ++ mtctr r11 ++ DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ ++ ++ /* order ld/st prior to dcbt stop all streams with flushing */ ++ sync ++1: li r8,0 ++ .rept 8 /* 8-way set associative */ ++ ldx r11,r10,r8 ++ add r8,r8,r12 ++ xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not ++ add r8,r8,r11 // Add 0, this creates a dependency on the ldx ++ .endr ++ addi r10,r10,128 /* 128 byte cache line */ ++ bdnz 1b ++ ++ mtctr r9 ++ ld r9,PACA_EXRFI+EX_R9(r13) ++ ld r10,PACA_EXRFI+EX_R10(r13) ++ ld r11,PACA_EXRFI+EX_R11(r13) ++ ld r12,PACA_EXRFI+EX_R12(r13) ++ ld r8,PACA_EXRFI+EX_R13(r13) ++ GET_SCRATCH0(r13); ++ hrfid ++ + /* + * Called from arch_local_irq_enable when an interrupt needs + * to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate +--- a/arch/powerpc/kernel/setup_64.c ++++ b/arch/powerpc/kernel/setup_64.c +@@ -678,4 +678,83 @@ static int __init disable_hardlockup_det + return 0; + } + early_initcall(disable_hardlockup_detector); ++ ++#ifdef CONFIG_PPC_BOOK3S_64 ++static enum l1d_flush_type enabled_flush_types; ++static void *l1d_flush_fallback_area; ++bool rfi_flush; ++ ++static void do_nothing(void *unused) ++{ ++ /* ++ * We don't need to do the flush explicitly, just enter+exit kernel is ++ * sufficient, the RFI exit handlers will do the right thing. ++ */ ++} ++ ++void rfi_flush_enable(bool enable) ++{ ++ if (rfi_flush == enable) ++ return; ++ ++ if (enable) { ++ do_rfi_flush_fixups(enabled_flush_types); ++ on_each_cpu(do_nothing, NULL, 1); ++ } else ++ do_rfi_flush_fixups(L1D_FLUSH_NONE); ++ ++ rfi_flush = enable; ++} ++ ++static void init_fallback_flush(void) ++{ ++ u64 l1d_size, limit; ++ int cpu; ++ ++ l1d_size = ppc64_caches.dsize; ++ limit = min(safe_stack_limit(), ppc64_rma_size); ++ ++ /* ++ * Align to L1d size, and size it at 2x L1d size, to catch possible ++ * hardware prefetch runoff. We don't have a recipe for load patterns to ++ * reliably avoid the prefetcher. ++ */ ++ l1d_flush_fallback_area = __va(memblock_alloc_base(l1d_size * 2, l1d_size, limit)); ++ memset(l1d_flush_fallback_area, 0, l1d_size * 2); ++ ++ for_each_possible_cpu(cpu) { ++ /* ++ * The fallback flush is currently coded for 8-way ++ * associativity. Different associativity is possible, but it ++ * will be treated as 8-way and may not evict the lines as ++ * effectively. ++ * ++ * 128 byte lines are mandatory. ++ */ ++ u64 c = l1d_size / 8; ++ ++ paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area; ++ paca[cpu].l1d_flush_congruence = c; ++ paca[cpu].l1d_flush_sets = c / 128; ++ } ++} ++ ++void __init setup_rfi_flush(enum l1d_flush_type types, bool enable) ++{ ++ if (types & L1D_FLUSH_FALLBACK) { ++ pr_info("rfi-flush: Using fallback displacement flush\n"); ++ init_fallback_flush(); ++ } ++ ++ if (types & L1D_FLUSH_ORI) ++ pr_info("rfi-flush: Using ori type flush\n"); ++ ++ if (types & L1D_FLUSH_MTTRIG) ++ pr_info("rfi-flush: Using mttrig type flush\n"); ++ ++ enabled_flush_types = types; ++ ++ rfi_flush_enable(enable); ++} ++#endif /* CONFIG_PPC_BOOK3S_64 */ + #endif +--- a/arch/powerpc/kernel/vmlinux.lds.S ++++ b/arch/powerpc/kernel/vmlinux.lds.S +@@ -132,6 +132,15 @@ SECTIONS + /* Read-only data */ + RODATA + ++#ifdef CONFIG_PPC64 ++ . = ALIGN(8); ++ __rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) { ++ __start___rfi_flush_fixup = .; ++ *(__rfi_flush_fixup) ++ __stop___rfi_flush_fixup = .; ++ } ++#endif ++ + EXCEPTION_TABLE(0) + + NOTES :kernel :notes +--- a/arch/powerpc/lib/feature-fixups.c ++++ b/arch/powerpc/lib/feature-fixups.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + struct fixup_entry { + unsigned long mask; +@@ -115,6 +116,47 @@ void do_feature_fixups(unsigned long val + } + } + ++#ifdef CONFIG_PPC_BOOK3S_64 ++void do_rfi_flush_fixups(enum l1d_flush_type types) ++{ ++ unsigned int instrs[3], *dest; ++ long *start, *end; ++ int i; ++ ++ start = PTRRELOC(&__start___rfi_flush_fixup), ++ end = PTRRELOC(&__stop___rfi_flush_fixup); ++ ++ instrs[0] = 0x60000000; /* nop */ ++ instrs[1] = 0x60000000; /* nop */ ++ instrs[2] = 0x60000000; /* nop */ ++ ++ if (types & L1D_FLUSH_FALLBACK) ++ /* b .+16 to fallback flush */ ++ instrs[0] = 0x48000010; ++ ++ i = 0; ++ if (types & L1D_FLUSH_ORI) { ++ instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */ ++ instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/ ++ } ++ ++ if (types & L1D_FLUSH_MTTRIG) ++ instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */ ++ ++ for (i = 0; start < end; start++, i++) { ++ dest = (void *)start + *start; ++ ++ pr_devel("patching dest %lx\n", (unsigned long)dest); ++ ++ patch_instruction(dest, instrs[0]); ++ patch_instruction(dest + 1, instrs[1]); ++ patch_instruction(dest + 2, instrs[2]); ++ } ++ ++ printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i); ++} ++#endif /* CONFIG_PPC_BOOK3S_64 */ ++ + void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) + { + long *start, *end; diff --git a/queue-4.9/powerpc-64s-allow-control-of-rfi-flush-via-debugfs.patch b/queue-4.9/powerpc-64s-allow-control-of-rfi-flush-via-debugfs.patch new file mode 100644 index 00000000000..86aeb9a5e07 --- /dev/null +++ b/queue-4.9/powerpc-64s-allow-control-of-rfi-flush-via-debugfs.patch @@ -0,0 +1,72 @@ +From 236003e6b5443c45c18e613d2b0d776a9f87540e Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Tue, 16 Jan 2018 22:17:18 +1100 +Subject: powerpc/64s: Allow control of RFI flush via debugfs + +From: Michael Ellerman + +commit 236003e6b5443c45c18e613d2b0d776a9f87540e upstream. + +Expose the state of the RFI flush (enabled/disabled) via debugfs, and +allow it to be enabled/disabled at runtime. + +eg: $ cat /sys/kernel/debug/powerpc/rfi_flush + 1 + $ echo 0 > /sys/kernel/debug/powerpc/rfi_flush + $ cat /sys/kernel/debug/powerpc/rfi_flush + 0 + +Signed-off-by: Michael Ellerman +Reviewed-by: Nicholas Piggin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/setup_64.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +--- a/arch/powerpc/kernel/setup_64.c ++++ b/arch/powerpc/kernel/setup_64.c +@@ -38,6 +38,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -779,6 +780,35 @@ void __init setup_rfi_flush(enum l1d_flu + rfi_flush_enable(enable); + } + ++#ifdef CONFIG_DEBUG_FS ++static int rfi_flush_set(void *data, u64 val) ++{ ++ if (val == 1) ++ rfi_flush_enable(true); ++ else if (val == 0) ++ rfi_flush_enable(false); ++ else ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int rfi_flush_get(void *data, u64 *val) ++{ ++ *val = rfi_flush ? 1 : 0; ++ return 0; ++} ++ ++DEFINE_SIMPLE_ATTRIBUTE(fops_rfi_flush, rfi_flush_get, rfi_flush_set, "%llu\n"); ++ ++static __init int rfi_flush_debugfs_init(void) ++{ ++ debugfs_create_file("rfi_flush", 0600, powerpc_debugfs_root, NULL, &fops_rfi_flush); ++ return 0; ++} ++device_initcall(rfi_flush_debugfs_init); ++#endif ++ + ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) + { + if (rfi_flush) diff --git a/queue-4.9/powerpc-64s-convert-slb_miss_common-to-use-rfi_to_user-kernel.patch b/queue-4.9/powerpc-64s-convert-slb_miss_common-to-use-rfi_to_user-kernel.patch new file mode 100644 index 00000000000..4e10a38e831 --- /dev/null +++ b/queue-4.9/powerpc-64s-convert-slb_miss_common-to-use-rfi_to_user-kernel.patch @@ -0,0 +1,69 @@ +From c7305645eb0c1621351cfc104038831ae87c0053 Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Wed, 10 Jan 2018 03:07:15 +1100 +Subject: powerpc/64s: Convert slb_miss_common to use RFI_TO_USER/KERNEL + +From: Nicholas Piggin + +commit c7305645eb0c1621351cfc104038831ae87c0053 upstream. + +In the SLB miss handler we may be returning to user or kernel. We need +to add a check early on and save the result in the cr4 register, and +then we bifurcate the return path based on that. + +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Signed-off-by: Nicholas Piggin +[mpe: Backport to 4.4 based on patch from Balbir] +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/exceptions-64s.S | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/kernel/exceptions-64s.S ++++ b/arch/powerpc/kernel/exceptions-64s.S +@@ -655,6 +655,8 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_R + + andi. r10,r12,MSR_RI /* check for unrecoverable exception */ + beq- 2f ++ andi. r10,r12,MSR_PR /* check for user mode (PR != 0) */ ++ bne 1f + + /* All done -- return from exception. */ + +@@ -671,7 +673,23 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_R + ld r11,PACA_EXSLB+EX_R11(r13) + ld r12,PACA_EXSLB+EX_R12(r13) + ld r13,PACA_EXSLB+EX_R13(r13) +- rfid ++ RFI_TO_KERNEL ++ b . /* prevent speculative execution */ ++ ++1: ++.machine push ++.machine "power4" ++ mtcrf 0x80,r9 ++ mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ ++.machine pop ++ ++ RESTORE_PPR_PACA(PACA_EXSLB, r9) ++ ld r9,PACA_EXSLB+EX_R9(r13) ++ ld r10,PACA_EXSLB+EX_R10(r13) ++ ld r11,PACA_EXSLB+EX_R11(r13) ++ ld r12,PACA_EXSLB+EX_R12(r13) ++ ld r13,PACA_EXSLB+EX_R13(r13) ++ RFI_TO_USER + b . /* prevent speculative execution */ + + 2: mfspr r11,SPRN_SRR0 +@@ -679,7 +697,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_R + mtspr SPRN_SRR0,r10 + ld r10,PACAKMSR(r13) + mtspr SPRN_SRR1,r10 +- rfid ++ RFI_TO_KERNEL + b . + + 8: mfspr r11,SPRN_SRR0 diff --git a/queue-4.9/powerpc-64s-support-disabling-rfi-flush-with-no_rfi_flush-and-nopti.patch b/queue-4.9/powerpc-64s-support-disabling-rfi-flush-with-no_rfi_flush-and-nopti.patch new file mode 100644 index 00000000000..378095aee78 --- /dev/null +++ b/queue-4.9/powerpc-64s-support-disabling-rfi-flush-with-no_rfi_flush-and-nopti.patch @@ -0,0 +1,67 @@ +From bc9c9304a45480797e13a8e1df96ffcf44fb62fe Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Wed, 10 Jan 2018 03:07:15 +1100 +Subject: powerpc/64s: Support disabling RFI flush with no_rfi_flush and nopti + +From: Michael Ellerman + +commit bc9c9304a45480797e13a8e1df96ffcf44fb62fe upstream. + +Because there may be some performance overhead of the RFI flush, add +kernel command line options to disable it. + +We add a sensibly named 'no_rfi_flush' option, but we also hijack the +x86 option 'nopti'. The RFI flush is not the same as KPTI, but if we +see 'nopti' we can guess that the user is trying to avoid any overhead +of Meltdown mitigations, and it means we don't have to educate every +one about a different command line option. + +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/setup_64.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/setup_64.c ++++ b/arch/powerpc/kernel/setup_64.c +@@ -682,8 +682,29 @@ early_initcall(disable_hardlockup_detect + #ifdef CONFIG_PPC_BOOK3S_64 + static enum l1d_flush_type enabled_flush_types; + static void *l1d_flush_fallback_area; ++static bool no_rfi_flush; + bool rfi_flush; + ++static int __init handle_no_rfi_flush(char *p) ++{ ++ pr_info("rfi-flush: disabled on command line."); ++ no_rfi_flush = true; ++ return 0; ++} ++early_param("no_rfi_flush", handle_no_rfi_flush); ++ ++/* ++ * The RFI flush is not KPTI, but because users will see doco that says to use ++ * nopti we hijack that option here to also disable the RFI flush. ++ */ ++static int __init handle_no_pti(char *p) ++{ ++ pr_info("rfi-flush: disabling due to 'nopti' on command line.\n"); ++ handle_no_rfi_flush(NULL); ++ return 0; ++} ++early_param("nopti", handle_no_pti); ++ + static void do_nothing(void *unused) + { + /* +@@ -754,7 +775,8 @@ void __init setup_rfi_flush(enum l1d_flu + + enabled_flush_types = types; + +- rfi_flush_enable(enable); ++ if (!no_rfi_flush) ++ rfi_flush_enable(enable); + } + #endif /* CONFIG_PPC_BOOK3S_64 */ + #endif diff --git a/queue-4.9/powerpc-64s-wire-up-cpu_show_meltdown.patch b/queue-4.9/powerpc-64s-wire-up-cpu_show_meltdown.patch new file mode 100644 index 00000000000..b13372c9bd6 --- /dev/null +++ b/queue-4.9/powerpc-64s-wire-up-cpu_show_meltdown.patch @@ -0,0 +1,56 @@ +From fd6e440f20b1a4304553775fc55938848ff617c9 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Tue, 16 Jan 2018 21:20:05 +1100 +Subject: powerpc/64s: Wire up cpu_show_meltdown() + +From: Michael Ellerman + +commit fd6e440f20b1a4304553775fc55938848ff617c9 upstream. + +The recent commit 87590ce6e373 ("sysfs/cpu: Add vulnerability folder") +added a generic folder and set of files for reporting information on +CPU vulnerabilities. One of those was for meltdown: + + /sys/devices/system/cpu/vulnerabilities/meltdown + +This commit wires up that file for 64-bit Book3S powerpc. + +For now we default to "Vulnerable" unless the RFI flush is enabled. +That may not actually be true on all hardware, further patches will +refine the reporting based on the CPU/platform etc. But for now we +default to being pessimists. + +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/Kconfig | 1 + + arch/powerpc/kernel/setup_64.c | 8 ++++++++ + 2 files changed, 9 insertions(+) + +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -128,6 +128,7 @@ config PPC + select ARCH_HAS_GCOV_PROFILE_ALL + select GENERIC_SMP_IDLE_THREAD + select GENERIC_CMOS_UPDATE ++ select GENERIC_CPU_VULNERABILITIES if PPC_BOOK3S_64 + select GENERIC_TIME_VSYSCALL_OLD + select GENERIC_CLOCKEVENTS + select GENERIC_CLOCKEVENTS_BROADCAST if SMP +--- a/arch/powerpc/kernel/setup_64.c ++++ b/arch/powerpc/kernel/setup_64.c +@@ -778,5 +778,13 @@ void __init setup_rfi_flush(enum l1d_flu + if (!no_rfi_flush) + rfi_flush_enable(enable); + } ++ ++ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) ++{ ++ if (rfi_flush) ++ return sprintf(buf, "Mitigation: RFI Flush\n"); ++ ++ return sprintf(buf, "Vulnerable\n"); ++} + #endif /* CONFIG_PPC_BOOK3S_64 */ + #endif diff --git a/queue-4.9/powerpc-powernv-check-device-tree-for-rfi-flush-settings.patch b/queue-4.9/powerpc-powernv-check-device-tree-for-rfi-flush-settings.patch new file mode 100644 index 00000000000..5d81606d4b7 --- /dev/null +++ b/queue-4.9/powerpc-powernv-check-device-tree-for-rfi-flush-settings.patch @@ -0,0 +1,88 @@ +From 6e032b350cd1fdb830f18f8320ef0e13b4e24094 Mon Sep 17 00:00:00 2001 +From: Oliver O'Halloran +Date: Wed, 10 Jan 2018 03:07:15 +1100 +Subject: powerpc/powernv: Check device-tree for RFI flush settings + +From: Oliver O'Halloran + +commit 6e032b350cd1fdb830f18f8320ef0e13b4e24094 upstream. + +New device-tree properties are available which tell the hypervisor +settings related to the RFI flush. Use them to determine the +appropriate flush instruction to use, and whether the flush is +required. + +Signed-off-by: Oliver O'Halloran +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/platforms/powernv/setup.c | 50 +++++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +--- a/arch/powerpc/platforms/powernv/setup.c ++++ b/arch/powerpc/platforms/powernv/setup.c +@@ -35,13 +35,63 @@ + #include + #include + #include ++#include ++#include + + #include "powernv.h" + ++static void pnv_setup_rfi_flush(void) ++{ ++ struct device_node *np, *fw_features; ++ enum l1d_flush_type type; ++ int enable; ++ ++ /* Default to fallback in case fw-features are not available */ ++ type = L1D_FLUSH_FALLBACK; ++ enable = 1; ++ ++ np = of_find_node_by_name(NULL, "ibm,opal"); ++ fw_features = of_get_child_by_name(np, "fw-features"); ++ of_node_put(np); ++ ++ if (fw_features) { ++ np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2"); ++ if (np && of_property_read_bool(np, "enabled")) ++ type = L1D_FLUSH_MTTRIG; ++ ++ of_node_put(np); ++ ++ np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0"); ++ if (np && of_property_read_bool(np, "enabled")) ++ type = L1D_FLUSH_ORI; ++ ++ of_node_put(np); ++ ++ /* Enable unless firmware says NOT to */ ++ enable = 2; ++ np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0"); ++ if (np && of_property_read_bool(np, "disabled")) ++ enable--; ++ ++ of_node_put(np); ++ ++ np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-pr-0-to-1"); ++ if (np && of_property_read_bool(np, "disabled")) ++ enable--; ++ ++ of_node_put(np); ++ of_node_put(fw_features); ++ } ++ ++ setup_rfi_flush(type, enable > 0); ++} ++ + static void __init pnv_setup_arch(void) + { + set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); + ++ pnv_setup_rfi_flush(); ++ + /* Initialize SMP */ + pnv_smp_init(); + diff --git a/queue-4.9/powerpc-pseries-add-h_get_cpu_characteristics-flags-wrapper.patch b/queue-4.9/powerpc-pseries-add-h_get_cpu_characteristics-flags-wrapper.patch new file mode 100644 index 00000000000..2b0e20e64e1 --- /dev/null +++ b/queue-4.9/powerpc-pseries-add-h_get_cpu_characteristics-flags-wrapper.patch @@ -0,0 +1,85 @@ +From 191eccb1580939fb0d47deb405b82a85b0379070 Mon Sep 17 00:00:00 2001 +From: Michael Neuling +Date: Tue, 9 Jan 2018 03:52:05 +1100 +Subject: powerpc/pseries: Add H_GET_CPU_CHARACTERISTICS flags & wrapper + +From: Michael Neuling + +commit 191eccb1580939fb0d47deb405b82a85b0379070 upstream. + +A new hypervisor call has been defined to communicate various +characteristics of the CPU to guests. Add definitions for the hcall +number, flags and a wrapper function. + +Signed-off-by: Michael Neuling +Signed-off-by: Michael Ellerman +[Balbir fixed conflicts in backport] +Signed-off-by: Balbir Singh +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/hvcall.h | 17 +++++++++++++++++ + arch/powerpc/include/asm/plpar_wrappers.h | 14 ++++++++++++++ + 2 files changed, 31 insertions(+) + +--- a/arch/powerpc/include/asm/hvcall.h ++++ b/arch/powerpc/include/asm/hvcall.h +@@ -240,6 +240,7 @@ + #define H_GET_HCA_INFO 0x1B8 + #define H_GET_PERF_COUNT 0x1BC + #define H_MANAGE_TRACE 0x1C0 ++#define H_GET_CPU_CHARACTERISTICS 0x1C8 + #define H_FREE_LOGICAL_LAN_BUFFER 0x1D4 + #define H_QUERY_INT_STATE 0x1E4 + #define H_POLL_PENDING 0x1D8 +@@ -306,6 +307,17 @@ + #define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 + #define H_SET_MODE_RESOURCE_LE 4 + ++/* H_GET_CPU_CHARACTERISTICS return values */ ++#define H_CPU_CHAR_SPEC_BAR_ORI31 (1ull << 63) // IBM bit 0 ++#define H_CPU_CHAR_BCCTRL_SERIALISED (1ull << 62) // IBM bit 1 ++#define H_CPU_CHAR_L1D_FLUSH_ORI30 (1ull << 61) // IBM bit 2 ++#define H_CPU_CHAR_L1D_FLUSH_TRIG2 (1ull << 60) // IBM bit 3 ++#define H_CPU_CHAR_L1D_THREAD_PRIV (1ull << 59) // IBM bit 4 ++ ++#define H_CPU_BEHAV_FAVOUR_SECURITY (1ull << 63) // IBM bit 0 ++#define H_CPU_BEHAV_L1D_FLUSH_PR (1ull << 62) // IBM bit 1 ++#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ull << 61) // IBM bit 2 ++ + #ifndef __ASSEMBLY__ + + /** +@@ -433,6 +445,11 @@ static inline unsigned long cmo_get_page + } + #endif /* CONFIG_PPC_PSERIES */ + ++struct h_cpu_char_result { ++ u64 character; ++ u64 behaviour; ++}; ++ + #endif /* __ASSEMBLY__ */ + #endif /* __KERNEL__ */ + #endif /* _ASM_POWERPC_HVCALL_H */ +--- a/arch/powerpc/include/asm/plpar_wrappers.h ++++ b/arch/powerpc/include/asm/plpar_wrappers.h +@@ -340,4 +340,18 @@ static inline long plapr_set_watchpoint0 + return plpar_set_mode(0, H_SET_MODE_RESOURCE_SET_DAWR, dawr0, dawrx0); + } + ++static inline long plpar_get_cpu_characteristics(struct h_cpu_char_result *p) ++{ ++ unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; ++ long rc; ++ ++ rc = plpar_hcall(H_GET_CPU_CHARACTERISTICS, retbuf); ++ if (rc == H_SUCCESS) { ++ p->character = retbuf[0]; ++ p->behaviour = retbuf[1]; ++ } ++ ++ return rc; ++} ++ + #endif /* _ASM_POWERPC_PLPAR_WRAPPERS_H */ diff --git a/queue-4.9/powerpc-pseries-query-hypervisor-for-rfi-flush-settings.patch b/queue-4.9/powerpc-pseries-query-hypervisor-for-rfi-flush-settings.patch new file mode 100644 index 00000000000..c39777d0905 --- /dev/null +++ b/queue-4.9/powerpc-pseries-query-hypervisor-for-rfi-flush-settings.patch @@ -0,0 +1,72 @@ +From 8989d56878a7735dfdb234707a2fee6faf631085 Mon Sep 17 00:00:00 2001 +From: Michael Neuling +Date: Wed, 10 Jan 2018 03:07:15 +1100 +Subject: powerpc/pseries: Query hypervisor for RFI flush settings + +From: Michael Neuling + +commit 8989d56878a7735dfdb234707a2fee6faf631085 upstream. + +A new hypervisor call is available which tells the guest settings +related to the RFI flush. Use it to query the appropriate flush +instruction(s), and whether the flush is required. + +Signed-off-by: Michael Neuling +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/platforms/pseries/setup.c | 35 +++++++++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +--- a/arch/powerpc/platforms/pseries/setup.c ++++ b/arch/powerpc/platforms/pseries/setup.c +@@ -450,6 +450,39 @@ static void __init find_and_init_phbs(vo + of_pci_check_probe_only(); + } + ++static void pseries_setup_rfi_flush(void) ++{ ++ struct h_cpu_char_result result; ++ enum l1d_flush_type types; ++ bool enable; ++ long rc; ++ ++ /* Enable by default */ ++ enable = true; ++ ++ rc = plpar_get_cpu_characteristics(&result); ++ if (rc == H_SUCCESS) { ++ types = L1D_FLUSH_NONE; ++ ++ if (result.character & H_CPU_CHAR_L1D_FLUSH_TRIG2) ++ types |= L1D_FLUSH_MTTRIG; ++ if (result.character & H_CPU_CHAR_L1D_FLUSH_ORI30) ++ types |= L1D_FLUSH_ORI; ++ ++ /* Use fallback if nothing set in hcall */ ++ if (types == L1D_FLUSH_NONE) ++ types = L1D_FLUSH_FALLBACK; ++ ++ if (!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR)) ++ enable = false; ++ } else { ++ /* Default to fallback if case hcall is not available */ ++ types = L1D_FLUSH_FALLBACK; ++ } ++ ++ setup_rfi_flush(types, enable); ++} ++ + static void __init pSeries_setup_arch(void) + { + set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT); +@@ -467,6 +500,8 @@ static void __init pSeries_setup_arch(vo + + fwnmi_init(); + ++ pseries_setup_rfi_flush(); ++ + /* By default, only probe PCI (can be overridden by rtas_pci) */ + pci_add_flags(PCI_PROBE_ONLY); +