summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThorsten Leemhuis <fedora@leemhuis.info>2018-01-22 14:57:52 +0100
committerThorsten Leemhuis <fedora@leemhuis.info>2018-01-22 14:57:52 +0100
commita07fc1fd670797f6525e962a7218e975f47ba94c (patch)
tree0dc2a071d5d6c03c9a092e141184d46d9822434d
parent9cec2216fb0e16448b2ce4068b01c1af3942b859 (diff)
parentcc95f96a359a1474ad94d107276498b58c36aab7 (diff)
downloadkernel-a07fc1fd670797f6525e962a7218e975f47ba94c.tar.gz
kernel-a07fc1fd670797f6525e962a7218e975f47ba94c.tar.xz
kernel-a07fc1fd670797f6525e962a7218e975f47ba94c.zip
Merge remote-tracking branch 'origin/f26' into f26-user-thl-vanilla-fedora
-rw-r--r--kernel.spec6
-rw-r--r--ppc-mitigations.patch1309
2 files changed, 1314 insertions, 1 deletions
diff --git a/kernel.spec b/kernel.spec
index b23eef91f..f84f35117 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -651,6 +651,7 @@ Patch507: loop-fix-concurrent-lo_open-lo_release.patch
# 550-600 Meltdown and Spectre Fixes
Patch550: prevent-bounds-check-bypass-via-speculative-execution.patch
+Patch551: ppc-mitigations.patch
# 600 - Patches for improved Bay and Cherry Trail device support
# Below patches are submitted upstream, awaiting review / merging
@@ -2259,7 +2260,10 @@ fi
#
#
%changelog
-* Wed Jan 17 2018 Justin M. Forbes <jforbes@fedoraproject.org> - 4.14.14-200
+* Thu Jan 18 2018 Justin M. Forbes <jforbes@fedoraproject.org> - 4.14.14-300
+- Add some ppc mitigations from upstream
+
+* Wed Jan 17 2018 Justin M. Forbes <jforbes@fedoraproject.org>
- Linux v4.14.14
- Fixes (rhbz 1532458)
diff --git a/ppc-mitigations.patch b/ppc-mitigations.patch
new file mode 100644
index 000000000..909485721
--- /dev/null
+++ b/ppc-mitigations.patch
@@ -0,0 +1,1309 @@
+From 191eccb1580939fb0d47deb405b82a85b0379070 Mon Sep 17 00:00:00 2001
+From: Michael Neuling <mikey@neuling.org>
+Date: Tue, 9 Jan 2018 03:52:05 +1100
+Subject: powerpc/pseries: Add H_GET_CPU_CHARACTERISTICS flags & wrapper
+
+From: Michael Neuling <mikey@neuling.org>
+
+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 <mikey@neuling.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -241,6 +241,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
+@@ -330,6 +331,17 @@
+ #define H_SIGNAL_SYS_RESET_ALL_OTHERS -2
+ /* >= 0 values are CPU number */
+
++/* 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
++
+ /* Flag values used in H_REGISTER_PROC_TBL hcall */
+ #define PROC_TABLE_OP_MASK 0x18
+ #define PROC_TABLE_DEREG 0x10
+@@ -436,6 +448,11 @@ static inline unsigned int get_longbusy_
+ }
+ }
+
++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
+@@ -326,4 +326,18 @@ static inline long plapr_signal_sys_rese
+ return plpar_hcall_norets(H_SIGNAL_SYS_RESET, cpu);
+ }
+
++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 */
+From 50e51c13b3822d14ff6df4279423e4b7b2269bc3 Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+Date: Wed, 10 Jan 2018 03:07:15 +1100
+Subject: powerpc/64: Add macros for annotating the destination of rfid/hrfid
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+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 <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -69,6 +69,35 @@
+ */
+ #define EX_R3 EX_DAR
+
++/* 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 */ \
+From 222f20f140623ef6033491d0103ee0875fe87d35 Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+Date: Wed, 10 Jan 2018 03:07:15 +1100
+Subject: powerpc/64s: Simple RFI macro conversions
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+commit 222f20f140623ef6033491d0103ee0875fe87d35 upstream.
+
+This commit does simple conversions of rfi/rfid to the new macros that
+include the expected destination context. By simple we mean cases
+where there is a single well known destination context, and it's
+simply a matter of substituting the instruction for the appropriate
+macro.
+
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ arch/powerpc/include/asm/exception-64s.h | 4 ++--
+ arch/powerpc/kernel/entry_64.S | 14 +++++++++-----
+ arch/powerpc/kernel/exceptions-64s.S | 22 +++++++++++-----------
+ arch/powerpc/kvm/book3s_hv_rmhandlers.S | 7 +++----
+ arch/powerpc/kvm/book3s_rmhandlers.S | 7 +++++--
+ arch/powerpc/kvm/book3s_segment.S | 4 ++--
+ 6 files changed, 32 insertions(+), 26 deletions(-)
+
+--- a/arch/powerpc/include/asm/exception-64s.h
++++ b/arch/powerpc/include/asm/exception-64s.h
+@@ -242,7 +242,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
+ mtspr SPRN_##h##SRR0,r12; \
+ mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
+ mtspr SPRN_##h##SRR1,r10; \
+- h##rfid; \
++ h##RFI_TO_KERNEL; \
+ b . /* prevent speculative execution */
+ #define EXCEPTION_PROLOG_PSERIES_1(label, h) \
+ __EXCEPTION_PROLOG_PSERIES_1(label, h)
+@@ -256,7 +256,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
+ mtspr SPRN_##h##SRR0,r12; \
+ mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
+ mtspr SPRN_##h##SRR1,r10; \
+- h##rfid; \
++ h##RFI_TO_KERNEL; \
+ b . /* prevent speculative execution */
+
+ #define EXCEPTION_PROLOG_PSERIES_1_NORI(label, h) \
+--- a/arch/powerpc/kernel/entry_64.S
++++ b/arch/powerpc/kernel/entry_64.S
+@@ -37,6 +37,11 @@
+ #include <asm/tm.h>
+ #include <asm/ppc-opcode.h>
+ #include <asm/export.h>
++#ifdef CONFIG_PPC_BOOK3S
++#include <asm/exception-64s.h>
++#else
++#include <asm/exception-64e.h>
++#endif
+
+ /*
+ * System calls.
+@@ -397,8 +402,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
+ mtmsrd r10, 1
+ mtspr SPRN_SRR0, r11
+ mtspr SPRN_SRR1, r12
+-
+- rfid
++ RFI_TO_USER
+ b . /* prevent speculative execution */
+ #endif
+ _ASM_NOKPROBE_SYMBOL(system_call_common);
+@@ -1073,7 +1077,7 @@ __enter_rtas:
+
+ mtspr SPRN_SRR0,r5
+ mtspr SPRN_SRR1,r6
+- rfid
++ RFI_TO_KERNEL
+ b . /* prevent speculative execution */
+
+ rtas_return_loc:
+@@ -1098,7 +1102,7 @@ rtas_return_loc:
+
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+- rfid
++ RFI_TO_KERNEL
+ b . /* prevent speculative execution */
+ _ASM_NOKPROBE_SYMBOL(__enter_rtas)
+ _ASM_NOKPROBE_SYMBOL(rtas_return_loc)
+@@ -1171,7 +1175,7 @@ _GLOBAL(enter_prom)
+ LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE)
+ andc r11,r11,r12
+ mtsrr1 r11
+- rfid
++ RFI_TO_KERNEL
+ #endif /* CONFIG_PPC_BOOK3E */
+
+ 1: /* Return from OF */
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -254,7 +254,7 @@ BEGIN_FTR_SECTION
+ LOAD_HANDLER(r12, machine_check_handle_early)
+ 1: mtspr SPRN_SRR0,r12
+ mtspr SPRN_SRR1,r11
+- rfid
++ RFI_TO_KERNEL
+ b . /* prevent speculative execution */
+ 2:
+ /* Stack overflow. Stay on emergency stack and panic.
+@@ -443,7 +443,7 @@ EXC_COMMON_BEGIN(machine_check_handle_ea
+ li r3,MSR_ME
+ andc r10,r10,r3 /* Turn off MSR_ME */
+ mtspr SPRN_SRR1,r10
+- rfid
++ RFI_TO_KERNEL
+ b .
+ 2:
+ /*
+@@ -461,7 +461,7 @@ EXC_COMMON_BEGIN(machine_check_handle_ea
+ */
+ bl machine_check_queue_event
+ MACHINE_CHECK_HANDLER_WINDUP
+- rfid
++ RFI_TO_USER_OR_KERNEL
+ 9:
+ /* Deliver the machine check to host kernel in V mode. */
+ MACHINE_CHECK_HANDLER_WINDUP
+@@ -649,7 +649,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: std r3,PACA_EXSLB+EX_DAR(r13)
+@@ -660,7 +660,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 .
+
+ EXC_COMMON_BEGIN(unrecov_slb)
+@@ -905,7 +905,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
+ mtspr SPRN_SRR0,r10 ; \
+ ld r10,PACAKMSR(r13) ; \
+ mtspr SPRN_SRR1,r10 ; \
+- rfid ; \
++ RFI_TO_KERNEL ; \
+ b . ; /* prevent speculative execution */
+
+ #define SYSCALL_FASTENDIAN \
+@@ -914,7 +914,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
+ xori r12,r12,MSR_LE ; \
+ mtspr SPRN_SRR1,r12 ; \
+ mr r13,r9 ; \
+- rfid ; /* return to userspace */ \
++ RFI_TO_USER ; /* return to userspace */ \
+ b . ; /* prevent speculative execution */
+
+ #if defined(CONFIG_RELOCATABLE)
+@@ -1299,7 +1299,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
+ ld r11,PACA_EXGEN+EX_R11(r13)
+ ld r12,PACA_EXGEN+EX_R12(r13)
+ ld r13,PACA_EXGEN+EX_R13(r13)
+- HRFID
++ HRFI_TO_UNKNOWN
+ b .
+ #endif
+
+@@ -1403,7 +1403,7 @@ masked_##_H##interrupt: \
+ ld r10,PACA_EXGEN+EX_R10(r13); \
+ ld r11,PACA_EXGEN+EX_R11(r13); \
+ /* returns to kernel where r13 must be set up, so don't restore it */ \
+- ##_H##rfid; \
++ ##_H##RFI_TO_KERNEL; \
+ b .; \
+ MASKED_DEC_HANDLER(_H)
+
+@@ -1426,7 +1426,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_interrupt)
+ addi r13, r13, 4
+ mtspr SPRN_SRR0, r13
+ GET_SCRATCH0(r13)
+- rfid
++ RFI_TO_KERNEL
+ b .
+
+ TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
+@@ -1438,7 +1438,7 @@ TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
+ addi r13, r13, 4
+ mtspr SPRN_HSRR0, r13
+ GET_SCRATCH0(r13)
+- hrfid
++ HRFI_TO_KERNEL
+ b .
+ #endif
+
+--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
++++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+@@ -78,7 +78,7 @@ _GLOBAL_TOC(kvmppc_hv_entry_trampoline)
+ mtmsrd r0,1 /* clear RI in MSR */
+ mtsrr0 r5
+ mtsrr1 r6
+- RFI
++ RFI_TO_KERNEL
+
+ kvmppc_call_hv_entry:
+ ld r4, HSTATE_KVM_VCPU(r13)
+@@ -187,7 +187,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300)
+ mtmsrd r6, 1 /* Clear RI in MSR */
+ mtsrr0 r8
+ mtsrr1 r7
+- RFI
++ RFI_TO_KERNEL
+
+ /* Virtual-mode return */
+ .Lvirt_return:
+@@ -1131,8 +1131,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
+
+ ld r0, VCPU_GPR(R0)(r4)
+ ld r4, VCPU_GPR(R4)(r4)
+-
+- hrfid
++ HRFI_TO_GUEST
+ b .
+
+ secondary_too_late:
+--- a/arch/powerpc/kvm/book3s_rmhandlers.S
++++ b/arch/powerpc/kvm/book3s_rmhandlers.S
+@@ -46,6 +46,9 @@
+
+ #define FUNC(name) name
+
++#define RFI_TO_KERNEL RFI
++#define RFI_TO_GUEST RFI
++
+ .macro INTERRUPT_TRAMPOLINE intno
+
+ .global kvmppc_trampoline_\intno
+@@ -141,7 +144,7 @@ kvmppc_handler_skip_ins:
+ GET_SCRATCH0(r13)
+
+ /* And get back into the code */
+- RFI
++ RFI_TO_KERNEL
+ #endif
+
+ /*
+@@ -164,6 +167,6 @@ _GLOBAL_TOC(kvmppc_entry_trampoline)
+ ori r5, r5, MSR_EE
+ mtsrr0 r7
+ mtsrr1 r6
+- RFI
++ RFI_TO_KERNEL
+
+ #include "book3s_segment.S"
+--- a/arch/powerpc/kvm/book3s_segment.S
++++ b/arch/powerpc/kvm/book3s_segment.S
+@@ -156,7 +156,7 @@ no_dcbz32_on:
+ PPC_LL r9, SVCPU_R9(r3)
+ PPC_LL r3, (SVCPU_R3)(r3)
+
+- RFI
++ RFI_TO_GUEST
+ kvmppc_handler_trampoline_enter_end:
+
+
+@@ -407,5 +407,5 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
+ cmpwi r12, BOOK3S_INTERRUPT_DOORBELL
+ beqa BOOK3S_INTERRUPT_DOORBELL
+
+- RFI
++ RFI_TO_KERNEL
+ kvmppc_handler_trampoline_exit_end:
+From b8e90cb7bc04a509e821e82ab6ed7a8ef11ba333 Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+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 <npiggin@gmail.com>
+
+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 <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -267,13 +267,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 */
+
+ .Lsyscall_error:
+From a08f828cf47e6c605af21d2cdec68f84e799c318 Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+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 <npiggin@gmail.com>
+
+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 <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -892,7 +892,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)
+@@ -905,8 +905,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 */
+From c7305645eb0c1621351cfc104038831ae87c0053 Mon Sep 17 00:00:00 2001
+From: Nicholas Piggin <npiggin@gmail.com>
+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 <npiggin@gmail.com>
+
+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 <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/exceptions-64s.S | 29 ++++++++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -596,6 +596,9 @@ EXC_COMMON_BEGIN(slb_miss_common)
+ stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
+ std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
+
++ andi. r9,r11,MSR_PR // Check for exception from userspace
++ cmpdi cr4,r9,MSR_PR // And save the result in CR4 for later
++
+ /*
+ * Test MSR_RI before calling slb_allocate_realmode, because the
+ * MSR in r11 gets clobbered. However we still want to allocate
+@@ -622,9 +625,32 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_R
+
+ /* All done -- return from exception. */
+
++ bne cr4,1f /* returning to kernel */
++
++.machine push
++.machine "power4"
++ mtcrf 0x80,r9
++ mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */
++ mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */
++ mtcrf 0x02,r9 /* I/D indication is in cr6 */
++ mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
++.machine pop
++
++ RESTORE_CTR(r9, PACA_EXSLB)
++ RESTORE_PPR_PACA(PACA_EXSLB, r9)
++ mr r3,r12
++ 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 */
++1:
+ .machine push
+ .machine "power4"
+ mtcrf 0x80,r9
++ mtcrf 0x08,r9 /* MSR[PR] indication is in cr4 */
+ mtcrf 0x04,r9 /* MSR[RI] indication is in cr5 */
+ mtcrf 0x02,r9 /* I/D indication is in cr6 */
+ mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
+@@ -638,9 +664,10 @@ 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 */
+
++
+ 2: std r3,PACA_EXSLB+EX_DAR(r13)
+ mr r3,r12
+ mfspr r11,SPRN_SRR0
+From aa8a5e0062ac940f7659394f4817c948dc8c0667 Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 10 Jan 2018 03:07:15 +1100
+Subject: powerpc/64s: Add support for RFI flush of L1-D cache
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+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 <jcm@redhat.com>
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/include/asm/exception-64s.h | 40 +++++++++++---
+ arch/powerpc/include/asm/feature-fixups.h | 13 ++++
+ arch/powerpc/include/asm/paca.h | 10 +++
+ arch/powerpc/include/asm/setup.h | 13 ++++
+ arch/powerpc/kernel/asm-offsets.c | 5 +
+ arch/powerpc/kernel/exceptions-64s.S | 84 ++++++++++++++++++++++++++++++
+ arch/powerpc/kernel/setup_64.c | 79 ++++++++++++++++++++++++++++
+ arch/powerpc/kernel/vmlinux.lds.S | 9 +++
+ arch/powerpc/lib/feature-fixups.c | 41 ++++++++++++++
+ 9 files changed, 286 insertions(+), 8 deletions(-)
+
+--- a/arch/powerpc/include/asm/exception-64s.h
++++ b/arch/powerpc/include/asm/exception-64s.h
+@@ -69,34 +69,58 @@
+ */
+ #define EX_R3 EX_DAR
+
+-/* 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
+@@ -187,7 +187,20 @@ label##3: \
+ FTR_ENTRY_OFFSET label##1b-label##3b; \
+ .popsection;
+
++#define RFI_FLUSH_FIXUP_SECTION \
++951: \
++ .pushsection __rfi_flush_fixup,"a"; \
++ .align 2; \
++952: \
++ FTR_ENTRY_OFFSET 951b-952b; \
++ .popsection;
++
++
+ #ifndef __ASSEMBLY__
++#include <linux/types.h>
++
++extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
++
+ void apply_feature_fixups(void);
+ void setup_feature_keys(void);
+ #endif
+--- a/arch/powerpc/include/asm/paca.h
++++ b/arch/powerpc/include/asm/paca.h
+@@ -231,6 +231,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[EX_SIZE] __aligned(0x80);
++ void *rfi_flush_fallback_area;
++ u64 l1d_flush_congruence;
++ u64 l1d_flush_sets;
++#endif
+ };
+
+ extern void copy_mm_to_paca(struct mm_struct *mm);
+--- a/arch/powerpc/include/asm/setup.h
++++ b/arch/powerpc/include/asm/setup.h
+@@ -39,6 +39,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
+@@ -237,6 +237,11 @@ int main(void)
+ OFFSET(PACA_NMI_EMERG_SP, paca_struct, nmi_emergency_sp);
+ OFFSET(PACA_IN_MCE, paca_struct, in_mce);
+ OFFSET(PACA_IN_NMI, paca_struct, in_nmi);
++ OFFSET(PACA_RFI_FLUSH_FALLBACK_AREA, paca_struct, rfi_flush_fallback_area);
++ OFFSET(PACA_EXRFI, paca_struct, exrfi);
++ OFFSET(PACA_L1D_FLUSH_CONGRUENCE, paca_struct, l1d_flush_congruence);
++ OFFSET(PACA_L1D_FLUSH_SETS, paca_struct, l1d_flush_sets);
++
+ #endif
+ OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id);
+ OFFSET(PACAKEXECSTATE, paca_struct, kexec_state);
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -1434,6 +1434,90 @@ masked_##_H##interrupt: \
+ b .; \
+ MASKED_DEC_HANDLER(_H)
+
++TRAMP_REAL_BEGIN(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
++
++TRAMP_REAL_BEGIN(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
++
+ /*
+ * Real mode exceptions actually use this too, but alternate
+ * instruction code patches (which end up in the common .text area)
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -784,3 +784,82 @@ 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.l1d.size;
++ 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 */
+--- a/arch/powerpc/kernel/vmlinux.lds.S
++++ b/arch/powerpc/kernel/vmlinux.lds.S
+@@ -132,6 +132,15 @@ SECTIONS
+ /* Read-only data */
+ RO_DATA(PAGE_SIZE)
+
++#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
+@@ -116,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;
+From bc9c9304a45480797e13a8e1df96ffcf44fb62fe Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+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 <mpe@ellerman.id.au>
+
+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 <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -788,8 +788,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)
+ {
+ /*
+@@ -860,6 +881,7 @@ 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 */
+From 8989d56878a7735dfdb234707a2fee6faf631085 Mon Sep 17 00:00:00 2001
+From: Michael Neuling <mikey@neuling.org>
+Date: Wed, 10 Jan 2018 03:07:15 +1100
+Subject: powerpc/pseries: Query hypervisor for RFI flush settings
+
+From: Michael Neuling <mikey@neuling.org>
+
+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 <mikey@neuling.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -459,6 +459,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);
+@@ -476,6 +509,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);
+
+From 6e032b350cd1fdb830f18f8320ef0e13b4e24094 Mon Sep 17 00:00:00 2001
+From: Oliver O'Halloran <oohall@gmail.com>
+Date: Wed, 10 Jan 2018 03:07:15 +1100
+Subject: powerpc/powernv: Check device-tree for RFI flush settings
+
+From: Oliver O'Halloran <oohall@gmail.com>
+
+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 <oohall@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/setup.c | 49 +++++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+--- a/arch/powerpc/platforms/powernv/setup.c
++++ b/arch/powerpc/platforms/powernv/setup.c
+@@ -36,13 +36,62 @@
+ #include <asm/opal.h>
+ #include <asm/kexec.h>
+ #include <asm/smp.h>
++#include <asm/setup.h>
+
+ #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();
+