Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-12-23 15:16:51 +0100
committerTakashi Iwai <tiwai@suse.de>2017-12-23 15:16:51 +0100
commitf319846f861cf8533100c74840129daf6797130a (patch)
tree69f90b5103a7474b95a384f978a85a9401b5f5c2
parent539bc5efe7b34a54938540a30b4a7b2d53c3327d (diff)
parent376b1d22eed8540a510debf88892a700d3d8a255 (diff)
Merge branch 'users/jkosina/SLE12-SP3/pti' into SLE12-SP3-PTI
-rw-r--r--patches.suse/4.4-50-kaiser-add_pti_cmdline_option_and_documentation.patch14
-rw-r--r--patches.suse/4.4-58-kaiser-disable-on-xen.patch30
-rw-r--r--patches.suse/powerpc-Secure-memory-rfi-flush-SLE12SP3.patch558
-rw-r--r--series.conf2
4 files changed, 590 insertions, 14 deletions
diff --git a/patches.suse/4.4-50-kaiser-add_pti_cmdline_option_and_documentation.patch b/patches.suse/4.4-50-kaiser-add_pti_cmdline_option_and_documentation.patch
index 96ed0dd4e5..dd2219bb84 100644
--- a/patches.suse/4.4-50-kaiser-add_pti_cmdline_option_and_documentation.patch
+++ b/patches.suse/4.4-50-kaiser-add_pti_cmdline_option_and_documentation.patch
@@ -12,8 +12,8 @@ like upstream.
Signed-off-by: Borislav Petkov <bp@suse.de>
---
Documentation/kernel-parameters.txt | 6 +++
- arch/x86/mm/kaiser.c | 57 ++++++++++++++++++++++++------------
- 2 files changed, 45 insertions(+), 18 deletions(-)
+ arch/x86/mm/kaiser.c | 59 +++++++++++++++++++++++++-----------
+ 2 files changed, 47 insertions(+), 18 deletions(-)
--- a/arch/x86/mm/kaiser.c
+++ b/arch/x86/mm/kaiser.c
@@ -25,7 +25,7 @@ Signed-off-by: Borislav Petkov <bp@suse.de>
int kaiser_enabled __read_mostly = 1;
EXPORT_SYMBOL(kaiser_enabled); /* for inlined TLB flush functions */
-@@ -258,6 +259,41 @@ static void __init kaiser_init_all_pgds(
+@@ -258,6 +259,43 @@ static void __init kaiser_init_all_pgds(
WARN_ON(__ret); \
} while (0)
@@ -33,8 +33,10 @@ Signed-off-by: Borislav Petkov <bp@suse.de>
+{
+ bool enable = true;
+ char arg[5];
++ int ret;
+
-+ if (cmdline_find_option(boot_command_line, "pti", arg, sizeof(arg))) {
++ ret = cmdline_find_option(boot_command_line, "pti", arg, sizeof(arg));
++ if (ret > 0) {
+ if (!strncmp(arg, "on", 2))
+ goto enable;
+
@@ -67,7 +69,7 @@ Signed-off-by: Borislav Petkov <bp@suse.de>
/*
* If anything in here fails, we will likely die on one of the
* first kernel->user transitions and init will die. But, we
-@@ -269,12 +305,10 @@ void __init kaiser_init(void)
+@@ -269,12 +307,10 @@ void __init kaiser_init(void)
{
int cpu;
@@ -83,7 +85,7 @@ Signed-off-by: Borislav Petkov <bp@suse.de>
kaiser_init_all_pgds();
-@@ -418,16 +452,3 @@ void kaiser_flush_tlb_on_return_to_user(
+@@ -418,16 +454,3 @@ void kaiser_flush_tlb_on_return_to_user(
X86_CR3_PCID_USER_FLUSH | KAISER_SHADOW_PGD_OFFSET);
}
EXPORT_SYMBOL(kaiser_flush_tlb_on_return_to_user);
diff --git a/patches.suse/4.4-58-kaiser-disable-on-xen.patch b/patches.suse/4.4-58-kaiser-disable-on-xen.patch
index 46cc1cb80f..d038ac1fef 100644
--- a/patches.suse/4.4-58-kaiser-disable-on-xen.patch
+++ b/patches.suse/4.4-58-kaiser-disable-on-xen.patch
@@ -12,14 +12,28 @@ guests use distinct %cr3 values for kernel and user already.
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+---
+ arch/x86/mm/kaiser.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
--- a/arch/x86/mm/kaiser.c
+++ b/arch/x86/mm/kaiser.c
-@@ -280,6 +280,8 @@
- skip:
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
- goto disable;
-+ if (static_cpu_has(X86_FEATURE_XENPV))
-+ goto disable;
+@@ -258,6 +258,9 @@ void __init kaiser_check_boottime_disabl
+ char arg[5];
+ int ret;
+
++ if (boot_cpu_has(X86_FEATURE_XENPV))
++ goto silent_disable;
++
+ ret = cmdline_find_option(boot_command_line, "pti", arg, sizeof(arg));
+ if (ret > 0) {
+ if (!strncmp(arg, "on", 2))
+@@ -285,6 +288,8 @@ enable:
- enable:
- if (enable)
+ disable:
+ pr_info("Kernel/User page tables isolation: disabled\n");
++
++silent_disable:
+ kaiser_enabled = 0;
+ setup_clear_cpu_cap(X86_FEATURE_KAISER);
+ }
diff --git a/patches.suse/powerpc-Secure-memory-rfi-flush-SLE12SP3.patch b/patches.suse/powerpc-Secure-memory-rfi-flush-SLE12SP3.patch
new file mode 100644
index 0000000000..3a8e5d45a7
--- /dev/null
+++ b/patches.suse/powerpc-Secure-memory-rfi-flush-SLE12SP3.patch
@@ -0,0 +1,558 @@
+From: Nicholas Piggin <npiggin@gmail.com>
+Date: Fri, 15 Dec 2017 16:34:38 +1100
+Subject: [PATCH] powerpc: Secure memory rfi flush
+Patch-mainline: Not yet, under development
+References: bsc#1068032
+
+This puts a nop before each rfid/hrfid and patches in an L1-D
+cache flush instruction where possible.
+
+It provides /sys/devices/system/cpu/secure_memory_protection which can
+report and can patch the rfi flushes at runtime.
+
+This has some debug checking in the rfi instructions to make sure
+we're returning to the context we think we are, so we can avoid
+some flushes.
+
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+---
+--- a/arch/powerpc/include/asm/exception-64s.h
++++ b/arch/powerpc/include/asm/exception-64s.h
+@@ -34,6 +34,7 @@
+ * exception handlers (including pSeries LPAR) and iSeries LPAR
+ * implementations as possible.
+ */
++#include <asm/bug.h>
+
+ #define EX_R9 0
+ #define EX_R10 8
+@@ -50,6 +51,58 @@
+ #define EX_PPR 88 /* SMT thread status register (priority) */
+ #define EX_CTR 96
+
++/*
++ * The nop instruction allows a secure memory protection instruction to be
++ * inserted with the rfi flush fixup.
++ */
++#define PREPARE_RFI_TO_USER \
++ RFI_FLUSH_FIXUP_SECTION; \
++ nop
++
++#define PREPARE_RFI_TO_GUEST \
++ RFI_FLUSH_FIXUP_SECTION; \
++ nop
++
++#define DEBUG_RFI
++
++#ifdef DEBUG_RFI
++#define CHECK_TARGET_MSR_PR(srr_reg, expected_pr) \
++ SET_SCRATCH0(r3); \
++ mfspr r3,srr_reg; \
++ extrdi r3,r3,1,63-MSR_PR_LG; \
++666: tdnei r3,expected_pr; \
++ EMIT_BUG_ENTRY 666b,__FILE__,__LINE__,0; \
++ GET_SCRATCH0(r3);
++#else
++#define CHECK_TARGET_MSR_PR(expected)
++#endif
++
++#define RFI_TO_KERNEL \
++ CHECK_TARGET_MSR_PR(SPRN_SRR1, 0); \
++ rfid
++
++#define RFI_TO_USER \
++ CHECK_TARGET_MSR_PR(SPRN_SRR1, 1); \
++ PREPARE_RFI_TO_USER; \
++ rfid
++
++#define RFI_TO_GUEST \
++ PREPARE_RFI_TO_GUEST; \
++ rfid
++
++#define HRFI_TO_KERNEL \
++ CHECK_TARGET_MSR_PR(SPRN_HSRR1, 0); \
++ hrfid
++
++#define HRFI_TO_USER \
++ CHECK_TARGET_MSR_PR(SPRN_HSRR1, 1); \
++ PREPARE_RFI_TO_USER; \
++ hrfid
++
++#define HRFI_TO_GUEST \
++ PREPARE_RFI_TO_GUEST; \
++ hrfid
++
+ #ifdef CONFIG_RELOCATABLE
+ #define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h) \
+ ld r12,PACAKBASE(r13); /* get high part of &label */ \
+@@ -191,7 +244,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##rfid; /* h##RFI_TO_KERNEL runs out of space */ \
+ b . /* prevent speculative execution */
+ #define EXCEPTION_PROLOG_PSERIES_1(label, h) \
+ __EXCEPTION_PROLOG_PSERIES_1(label, h)
+--- a/arch/powerpc/include/asm/feature-fixups.h
++++ b/arch/powerpc/include/asm/feature-fixups.h
+@@ -184,4 +184,19 @@ 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;
++extern void do_rfi_flush_fixups(bool enable, unsigned int insn);
++
++#endif
+ #endif /* __ASM_POWERPC_FEATURE_FIXUPS_H */
+--- a/arch/powerpc/include/asm/setup.h
++++ b/arch/powerpc/include/asm/setup.h
+@@ -26,6 +26,10 @@ void initmem_init(void);
+ void setup_panic(void);
+ #define ARCH_PANIC_TIMEOUT 180
+
++extern bool rfi_flush;
++void rfi_flush_enable(bool enable);
++void __init setup_rfi_flush(void);
++
+ #endif /* !__ASSEMBLY__ */
+
+ #endif /* _ASM_POWERPC_SETUP_H */
+--- a/arch/powerpc/kernel/entry_64.S
++++ b/arch/powerpc/kernel/entry_64.S
+@@ -37,6 +37,9 @@
+ #include <asm/hw_irq.h>
+ #include <asm/context_tracking.h>
+ #include <asm/tm.h>
++#ifdef CONFIG_PPC_BOOK3S
++#include <asm/exception-64s.h>
++#endif
+
+ /*
+ * System calls.
+@@ -226,13 +229,23 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECK
+ ACCOUNT_CPU_USER_EXIT(r11, r12)
+ HMT_MEDIUM_LOW_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:
+@@ -888,7 +901,7 @@ BEGIN_FTR_SECTION
+ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
+ ACCOUNT_CPU_USER_EXIT(r2, r4)
+ REST_GPR(13, r1)
+-1:
++
+ mtspr SPRN_SRR1,r3
+
+ ld r2,_CCR(r1)
+@@ -901,8 +914,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 */
+@@ -1078,7 +1105,7 @@ _GLOBAL(enter_rtas)
+
+ mtspr SPRN_SRR0,r5
+ mtspr SPRN_SRR1,r6
+- rfid
++ RFI_TO_KERNEL
+ b . /* prevent speculative execution */
+
+ rtas_return_loc:
+@@ -1103,7 +1130,7 @@ rtas_return_loc:
+
+ mtspr SPRN_SRR0,r3
+ mtspr SPRN_SRR1,r4
+- rfid
++ RFI_TO_KERNEL
+ b . /* prevent speculative execution */
+
+ .align 3
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -54,7 +54,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
+ 1: mfspr r12,SPRN_SRR1 ; \
+ xori r12,r12,MSR_LE ; \
+ mtspr SPRN_SRR1,r12 ; \
+- rfid ; /* return to userspace */ \
++ RFI_TO_USER ; /* return to userspace */ \
+ b . ; /* prevent speculative execution */
+
+ #if defined(CONFIG_RELOCATABLE)
+@@ -671,7 +671,7 @@ masked_##_H##interrupt: \
+ ld r10,PACA_EXGEN+EX_R10(r13); \
+ ld r11,PACA_EXGEN+EX_R11(r13); \
+ GET_SCRATCH0(r13); \
+- ##_H##rfid; \
++ ##_H##RFI_TO_KERNEL; \
+ b .
+
+ MASKED_INTERRUPT()
+@@ -747,7 +747,7 @@ slb_miss_user_pseries:
+ mtspr SRR0,r12
+ mfspr r12,SRR1 /* and SRR1 */
+ mtspr SRR1,r10
+- rfid
++ RFI_TO_KERNEL
+ b . /* prevent spec. execution */
+ #endif /* __DISABLED__ */
+
+@@ -761,7 +761,7 @@ kvmppc_skip_interrupt:
+ addi r13, r13, 4
+ mtspr SPRN_SRR0, r13
+ GET_SCRATCH0(r13)
+- rfid
++ RFI_TO_GUEST
+ b .
+
+ kvmppc_skip_Hinterrupt:
+@@ -773,7 +773,7 @@ kvmppc_skip_Hinterrupt:
+ addi r13, r13, 4
+ mtspr SPRN_HSRR0, r13
+ GET_SCRATCH0(r13)
+- hrfid
++ HRFI_TO_GUEST
+ b .
+ #endif
+
+@@ -1525,7 +1525,7 @@ slb_miss_realmode:
+ mtspr SPRN_SRR0,r10
+ ld r10,PACAKMSR(r13)
+ mtspr SPRN_SRR1,r10
+- rfid
++ RFI_TO_KERNEL
+ b .
+
+ unrecov_slb:
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -847,3 +847,80 @@ static int __init disable_hardlockup_det
+ }
+ early_initcall(disable_hardlockup_detector);
+ #endif
++
++#ifdef CONFIG_PPC_BOOK3S_64
++enum l1d_flush_type {
++ L1D_FLUSH_NONE,
++ L1D_FLUSH_ORI,
++ L1D_FLUSH_MTTRIG,
++};
++
++enum l1d_flush_type l1d_flush_type;
++
++bool rfi_flush;
++
++static void do_rfi_flush(void *val)
++{
++ switch (l1d_flush_type) {
++ case L1D_FLUSH_ORI:
++ asm volatile("ori 30,30,0" ::: "memory");
++ break;
++ case L1D_FLUSH_MTTRIG:
++ asm volatile("mtspr 882,0" ::: "memory");
++ break;
++ default:
++ break;
++ }
++}
++
++void rfi_flush_enable(bool enable)
++{
++ unsigned int insn;
++
++ if (rfi_flush == enable)
++ return;
++
++ switch (l1d_flush_type) {
++ case L1D_FLUSH_ORI:
++ insn = 0x63de0000;
++ break;
++ case L1D_FLUSH_MTTRIG:
++ insn = 0x7c12dba6;
++ break;
++ default:
++ printk("Secure memory protection not enabled! System is vulnerable to local exploit. Update firmware.\n");
++ return;
++ }
++
++ do_rfi_flush_fixups(enable, insn);
++
++ if (enable)
++ on_each_cpu(do_rfi_flush, NULL, 1);
++
++ rfi_flush = enable;
++}
++
++/* This tries to guess the cpu characteristics based on the PVR. */
++static bool get_cpu_characteristics(void)
++{
++ if (pvr_version_is(PVR_POWER7) || pvr_version_is(PVR_POWER7p))
++ l1d_flush_type = L1D_FLUSH_NONE;
++ else if (pvr_version_is(PVR_POWER8E) ||
++ pvr_version_is(PVR_POWER8NVL) ||
++ pvr_version_is(PVR_POWER8))
++ l1d_flush_type = L1D_FLUSH_ORI;
++ else {
++ /* unknown CPU */
++ l1d_flush_type = L1D_FLUSH_NONE;
++ return false;
++ }
++
++ return true;
++}
++
++void __init setup_rfi_flush(void)
++{
++ if (get_cpu_characteristics())
++ rfi_flush_enable(true);
++}
++#endif /* CONFIG_PPC_BOOK3S_64 */
+--- a/arch/powerpc/kernel/sysfs.c
++++ b/arch/powerpc/kernel/sysfs.c
+@@ -18,8 +18,10 @@
+ #include <asm/smp.h>
+ #include <asm/pmc.h>
+ #include <asm/firmware.h>
++// #include <asm/ppc_asm.h>
+
+ #include "cacheinfo.h"
++// #include "setup.h"
+
+ #ifdef CONFIG_PPC64
+ #include <asm/paca.h>
+@@ -496,6 +498,43 @@ static DEVICE_ATTR(spurr, 0400, show_spu
+ static DEVICE_ATTR(purr, 0400, show_purr, store_purr);
+ static DEVICE_ATTR(pir, 0400, show_pir, NULL);
+
++#ifdef CONFIG_PPC_BOOK3S_64
++static ssize_t show_rfi_flush(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ return sprintf(buf, "%d\n", rfi_flush ? 1 : 0);
++}
++
++static ssize_t __used store_rfi_flush(struct device *dev,
++ struct device_attribute *attr, const char *buf,
++ size_t count)
++{
++ int val;
++ int ret = 0;
++
++ ret = sscanf(buf, "%d", &val);
++ if (ret != 1)
++ return -EINVAL;
++
++ if (val == 1)
++ rfi_flush_enable(true);
++ else if (val == 0)
++ rfi_flush_enable(false);
++ else
++ return -EINVAL;
++
++ return count;
++}
++
++static DEVICE_ATTR(rfi_flush, 0600,
++ show_rfi_flush, store_rfi_flush);
++
++static void sysfs_create_rfi_flush(void)
++{
++ device_create_file(cpu_subsys.dev_root, &dev_attr_rfi_flush);
++}
++#endif /* CONFIG_PPC_BOOK3S_64 */
++
+ /*
+ * This is the system wide DSCR register default value. Any
+ * change to this default value through the sysfs interface
+@@ -1058,6 +1097,7 @@ static int __init topology_init(void)
+
+ #ifdef CONFIG_PPC64
+ sysfs_create_dscr_default();
++ sysfs_create_rfi_flush();
+ #endif /* CONFIG_PPC64 */
+
+ return 0;
+--- a/arch/powerpc/kernel/vmlinux.lds.S
++++ b/arch/powerpc/kernel/vmlinux.lds.S
+@@ -72,6 +72,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/kvm/book3s_hv_rmhandlers.S
++++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+@@ -64,7 +64,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)
+@@ -170,7 +170,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+ mtsrr0 r8
+ mtsrr1 r7
+ beq cr1, 13f /* machine check */
+- RFI
++ RFI_TO_KERNEL
+
+ /* On POWER7, we have external interrupts set to use HSRR0/1 */
+ 11: mtspr SPRN_HSRR0, r8
+@@ -965,8 +965,7 @@ BEGIN_FTR_SECTION
+ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
+ 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
+@@ -141,7 +141,7 @@ kvmppc_handler_skip_ins:
+ GET_SCRATCH0(r13)
+
+ /* And get back into the code */
+- RFI
++ RFI_TO_GUEST
+ #endif
+
+ /*
+@@ -164,6 +164,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/lib/feature-fixups.c
++++ b/arch/powerpc/lib/feature-fixups.c
+@@ -20,6 +20,7 @@
+ #include <asm/code-patching.h>
+ #include <asm/page.h>
+ #include <asm/sections.h>
++#include <asm/setup.h>
+
+
+ struct fixup_entry {
+@@ -113,6 +114,33 @@ void do_feature_fixups(unsigned long val
+ }
+ }
+
++#ifdef CONFIG_PPC_BOOK3S_64
++void do_rfi_flush_fixups(bool enable, unsigned int insn)
++{
++ long *start, *end;
++ unsigned int *dest;
++ int i;
++
++ start = PTRRELOC(&__start___rfi_flush_fixup),
++ end = PTRRELOC(&__stop___rfi_flush_fixup);
++
++ for (i = 0; start < end; start++, i++) {
++ dest = (void *)start + *start;
++
++ pr_devel("RFI FLUSH FIXUP %s %lx\n", enable ? "enable" : "disable", (unsigned long)start);
++ if (!enable) {
++ pr_devel("patching dest %lx\n", (unsigned long)dest);
++ patch_instruction(dest, PPC_INST_NOP);
++ } else {
++ pr_devel("patching dest %lx\n", (unsigned long)dest);
++ patch_instruction(dest, insn);
++ }
++ }
++
++ printk(KERN_DEBUG "rfi-fixups: 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;
+--- a/arch/powerpc/platforms/powernv/setup.c
++++ b/arch/powerpc/platforms/powernv/setup.c
+@@ -42,6 +42,8 @@ static void __init pnv_setup_arch(void)
+ {
+ set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
+
++ setup_rfi_flush();
++
+ /* Initialize SMP */
+ pnv_smp_init();
+
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -561,6 +561,8 @@ static void __init pSeries_setup_arch(vo
+
+ fwnmi_init();
+
++ setup_rfi_flush();
++
+ /* By default, only probe PCI (can be overriden by rtas_pci) */
+ pci_add_flags(PCI_PROBE_ONLY);
+
diff --git a/series.conf b/series.conf
index 9e727adcae..3187338afc 100644
--- a/series.conf
+++ b/series.conf
@@ -2069,6 +2069,8 @@
patches.fixes/powerpc-64-Fix-flush_-di-cache_range-called-from-modules
patches.arch/powerpc-powernv-ioda-Fix-endianness-when-reading-TCE.patch
+ patches.suse/powerpc-Secure-memory-rfi-flush-SLE12SP3.patch
+
########################################################
# ARM
########################################################