-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Greg/Sasha,

Please queue up these powerpc patches for 4.4 if you have no objections.

cheers


Christophe Leroy (1):
  powerpc/fsl: Fix the flush of branch predictor.

Diana Craciun (10):
  powerpc/64: Disable the speculation barrier from the command line
  powerpc/64: Make stf barrier PPC_BOOK3S_64 specific.
  powerpc/64: Make meltdown reporting Book3S 64 specific
  powerpc/fsl: Add barrier_nospec implementation for NXP PowerPC Book3E
  powerpc/fsl: Add infrastructure to fixup branch predictor flush
  powerpc/fsl: Add macro to flush the branch predictor
  powerpc/fsl: Fix spectre_v2 mitigations reporting
  powerpc/fsl: Add nospectre_v2 command line argument
  powerpc/fsl: Flush the branch predictor at each kernel entry (64bit)
  powerpc/fsl: Update Spectre v2 reporting

Mauricio Faria de Oliveira (4):
  powerpc/rfi-flush: Differentiate enabled and patched flush types
  powerpc/pseries: Fix clearing of security feature flags
  powerpc: Move default security feature flags
  powerpc/pseries: Restore default security feature flags on setup

Michael Ellerman (29):
  powerpc/xmon: Add RFI flush related fields to paca dump
  powerpc/pseries: Support firmware disable of RFI flush
  powerpc/powernv: Support firmware disable of RFI flush
  powerpc/rfi-flush: Move the logic to avoid a redo into the debugfs
    code
  powerpc/rfi-flush: Make it possible to call setup_rfi_flush() again
  powerpc/rfi-flush: Always enable fallback flush on pseries
  powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags
  powerpc/rfi-flush: Call setup_rfi_flush() after LPM migration
  powerpc: Add security feature flags for Spectre/Meltdown
  powerpc/pseries: Set or clear security feature flags
  powerpc/powernv: Set or clear security feature flags
  powerpc/64s: Move cpu_show_meltdown()
  powerpc/64s: Enhance the information in cpu_show_meltdown()
  powerpc/powernv: Use the security flags in pnv_setup_rfi_flush()
  powerpc/pseries: Use the security flags in pseries_setup_rfi_flush()
  powerpc/64s: Wire up cpu_show_spectre_v1()
  powerpc/64s: Wire up cpu_show_spectre_v2()
  powerpc/64s: Fix section mismatch warnings from setup_rfi_flush()
  powerpc/64: Use barrier_nospec in syscall entry
  powerpc: Use barrier_nospec in copy_from_user()
  powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2
  powerpc/64: Add CONFIG_PPC_BARRIER_NOSPEC
  powerpc/64: Call setup_barrier_nospec() from setup_arch()
  powerpc/asm: Add a patch_site macro & helpers for patching
    instructions
  powerpc/64s: Add new security feature flags for count cache flush
  powerpc/64s: Add support for software count cache flush
  powerpc/pseries: Query hypervisor for count cache flush settings
  powerpc/powernv: Query firmware for count cache flush settings
  powerpc/security: Fix spectre_v2 reporting

Michael Neuling (1):
  powerpc: Avoid code patching freed init sections

Michal Suchanek (5):
  powerpc/64s: Add barrier_nospec
  powerpc/64s: Add support for ori barrier_nospec patching
  powerpc/64s: Patch barrier_nospec in modules
  powerpc/64s: Enable barrier_nospec based on firmware settings
  powerpc/64s: Enhance the information in cpu_show_spectre_v1()

Nicholas Piggin (2):
  powerpc/64s: Improve RFI L1-D cache flush fallback
  powerpc/64s: Add support for a store forwarding barrier at kernel
    entry/exit

 arch/powerpc/Kconfig                         |   7 +-
 arch/powerpc/include/asm/asm-prototypes.h    |  21 +
 arch/powerpc/include/asm/barrier.h           |  21 +
 arch/powerpc/include/asm/code-patching-asm.h |  18 +
 arch/powerpc/include/asm/code-patching.h     |   2 +
 arch/powerpc/include/asm/exception-64s.h     |  35 ++
 arch/powerpc/include/asm/feature-fixups.h    |  40 ++
 arch/powerpc/include/asm/hvcall.h            |   5 +
 arch/powerpc/include/asm/paca.h              |   3 +-
 arch/powerpc/include/asm/ppc-opcode.h        |   1 +
 arch/powerpc/include/asm/ppc_asm.h           |  11 +
 arch/powerpc/include/asm/security_features.h |  92 ++++
 arch/powerpc/include/asm/setup.h             |  23 +-
 arch/powerpc/include/asm/uaccess.h           |  18 +-
 arch/powerpc/kernel/Makefile                 |   1 +
 arch/powerpc/kernel/asm-offsets.c            |   3 +-
 arch/powerpc/kernel/entry_64.S               |  69 +++
 arch/powerpc/kernel/exceptions-64e.S         |  27 +-
 arch/powerpc/kernel/exceptions-64s.S         |  98 +++--
 arch/powerpc/kernel/module.c                 |  10 +-
 arch/powerpc/kernel/security.c               | 433 +++++++++++++++++++
 arch/powerpc/kernel/setup_32.c               |   2 +
 arch/powerpc/kernel/setup_64.c               |  50 +--
 arch/powerpc/kernel/vmlinux.lds.S            |  33 +-
 arch/powerpc/lib/code-patching.c             |  29 ++
 arch/powerpc/lib/feature-fixups.c            | 218 +++++++++-
 arch/powerpc/mm/mem.c                        |   2 +
 arch/powerpc/mm/tlb_low_64e.S                |   7 +
 arch/powerpc/platforms/powernv/setup.c       |  99 +++--
 arch/powerpc/platforms/pseries/mobility.c    |   3 +
 arch/powerpc/platforms/pseries/pseries.h     |   2 +
 arch/powerpc/platforms/pseries/setup.c       |  88 +++-
 arch/powerpc/xmon/xmon.c                     |   2 +
 33 files changed, 1345 insertions(+), 128 deletions(-)
 create mode 100644 arch/powerpc/include/asm/asm-prototypes.h
 create mode 100644 arch/powerpc/include/asm/code-patching-asm.h
 create mode 100644 arch/powerpc/include/asm/security_features.h
 create mode 100644 arch/powerpc/kernel/security.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 58a1fa979655..01b6c00a7060 100644
- --- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -136,7 +136,7 @@ config PPC
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_CMOS_UPDATE
        select GENERIC_TIME_VSYSCALL_OLD
- -     select GENERIC_CPU_VULNERABILITIES      if PPC_BOOK3S_64
+       select GENERIC_CPU_VULNERABILITIES      if PPC_BARRIER_NOSPEC
        select GENERIC_CLOCKEVENTS
        select GENERIC_CLOCKEVENTS_BROADCAST if SMP
        select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
@@ -162,6 +162,11 @@ config PPC
        select ARCH_HAS_DMA_SET_COHERENT_MASK
        select HAVE_ARCH_SECCOMP_FILTER
 
+config PPC_BARRIER_NOSPEC
+    bool
+    default y
+    depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E
+
 config GENERIC_CSUM
        def_bool CPU_LITTLE_ENDIAN
 
diff --git a/arch/powerpc/include/asm/asm-prototypes.h 
b/arch/powerpc/include/asm/asm-prototypes.h
new file mode 100644
index 000000000000..8944c55591cf
- --- /dev/null
+++ b/arch/powerpc/include/asm/asm-prototypes.h
@@ -0,0 +1,21 @@
+#ifndef _ASM_POWERPC_ASM_PROTOTYPES_H
+#define _ASM_POWERPC_ASM_PROTOTYPES_H
+/*
+ * This file is for prototypes of C functions that are only called
+ * from asm, and any associated variables.
+ *
+ * Copyright 2016, Daniel Axtens, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+/* Patch sites */
+extern s32 patch__call_flush_count_cache;
+extern s32 patch__flush_count_cache_return;
+
+extern long flush_count_cache;
+
+#endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */
diff --git a/arch/powerpc/include/asm/barrier.h 
b/arch/powerpc/include/asm/barrier.h
index b9e16855a037..e7cb72cdb2ba 100644
- --- a/arch/powerpc/include/asm/barrier.h
+++ b/arch/powerpc/include/asm/barrier.h
@@ -92,4 +92,25 @@ do {                                                         
        \
 #define smp_mb__after_atomic()      smp_mb()
 #define smp_mb__before_spinlock()   smp_mb()
 
+#ifdef CONFIG_PPC_BOOK3S_64
+#define NOSPEC_BARRIER_SLOT   nop
+#elif defined(CONFIG_PPC_FSL_BOOK3E)
+#define NOSPEC_BARRIER_SLOT   nop; nop
+#endif
+
+#ifdef CONFIG_PPC_BARRIER_NOSPEC
+/*
+ * Prevent execution of subsequent instructions until preceding branches have
+ * been fully resolved and are no longer executing speculatively.
+ */
+#define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; NOSPEC_BARRIER_SLOT
+
+// This also acts as a compiler barrier due to the memory clobber.
+#define barrier_nospec() asm (stringify_in_c(barrier_nospec_asm) ::: "memory")
+
+#else /* !CONFIG_PPC_BARRIER_NOSPEC */
+#define barrier_nospec_asm
+#define barrier_nospec()
+#endif /* CONFIG_PPC_BARRIER_NOSPEC */
+
 #endif /* _ASM_POWERPC_BARRIER_H */
diff --git a/arch/powerpc/include/asm/code-patching-asm.h 
b/arch/powerpc/include/asm/code-patching-asm.h
new file mode 100644
index 000000000000..ed7b1448493a
- --- /dev/null
+++ b/arch/powerpc/include/asm/code-patching-asm.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2018, Michael Ellerman, IBM Corporation.
+ */
+#ifndef _ASM_POWERPC_CODE_PATCHING_ASM_H
+#define _ASM_POWERPC_CODE_PATCHING_ASM_H
+
+/* Define a "site" that can be patched */
+.macro patch_site label name
+       .pushsection ".rodata"
+       .balign 4
+       .global \name
+\name:
+       .4byte  \label - .
+       .popsection
+.endm
+
+#endif /* _ASM_POWERPC_CODE_PATCHING_ASM_H */
diff --git a/arch/powerpc/include/asm/code-patching.h 
b/arch/powerpc/include/asm/code-patching.h
index 840a5509b3f1..a734b4b34d26 100644
- --- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -28,6 +28,8 @@ unsigned int create_cond_branch(const unsigned int *addr,
                                unsigned long target, int flags);
 int patch_branch(unsigned int *addr, unsigned long target, int flags);
 int patch_instruction(unsigned int *addr, unsigned int instr);
+int patch_instruction_site(s32 *addr, unsigned int instr);
+int patch_branch_site(s32 *site, unsigned long target, int flags);
 
 int instr_is_relative_branch(unsigned int instr);
 int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
diff --git a/arch/powerpc/include/asm/exception-64s.h 
b/arch/powerpc/include/asm/exception-64s.h
index 9bddbec441b8..3ed536bec462 100644
- --- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -50,6 +50,27 @@
 #define EX_PPR         88      /* SMT thread status register (priority) */
 #define EX_CTR         96
 
+#define STF_ENTRY_BARRIER_SLOT                                         \
+       STF_ENTRY_BARRIER_FIXUP_SECTION;                                \
+       nop;                                                            \
+       nop;                                                            \
+       nop
+
+#define STF_EXIT_BARRIER_SLOT                                          \
+       STF_EXIT_BARRIER_FIXUP_SECTION;                                 \
+       nop;                                                            \
+       nop;                                                            \
+       nop;                                                            \
+       nop;                                                            \
+       nop;                                                            \
+       nop
+
+/*
+ * r10 must be free to use, r13 must be paca
+ */
+#define INTERRUPT_TO_KERNEL                                            \
+       STF_ENTRY_BARRIER_SLOT
+
 /*
  * Macros for annotating the expected destination of (h)rfid
  *
@@ -66,16 +87,19 @@
        rfid
 
 #define RFI_TO_USER                                                    \
+       STF_EXIT_BARRIER_SLOT;                                          \
        RFI_FLUSH_SLOT;                                                 \
        rfid;                                                           \
        b       rfi_flush_fallback
 
 #define RFI_TO_USER_OR_KERNEL                                          \
+       STF_EXIT_BARRIER_SLOT;                                          \
        RFI_FLUSH_SLOT;                                                 \
        rfid;                                                           \
        b       rfi_flush_fallback
 
 #define RFI_TO_GUEST                                                   \
+       STF_EXIT_BARRIER_SLOT;                                          \
        RFI_FLUSH_SLOT;                                                 \
        rfid;                                                           \
        b       rfi_flush_fallback
@@ -84,21 +108,25 @@
        hrfid
 
 #define HRFI_TO_USER                                                   \
+       STF_EXIT_BARRIER_SLOT;                                          \
        RFI_FLUSH_SLOT;                                                 \
        hrfid;                                                          \
        b       hrfi_flush_fallback
 
 #define HRFI_TO_USER_OR_KERNEL                                         \
+       STF_EXIT_BARRIER_SLOT;                                          \
        RFI_FLUSH_SLOT;                                                 \
        hrfid;                                                          \
        b       hrfi_flush_fallback
 
 #define HRFI_TO_GUEST                                                  \
+       STF_EXIT_BARRIER_SLOT;                                          \
        RFI_FLUSH_SLOT;                                                 \
        hrfid;                                                          \
        b       hrfi_flush_fallback
 
 #define HRFI_TO_UNKNOWN                                                        
\
+       STF_EXIT_BARRIER_SLOT;                                          \
        RFI_FLUSH_SLOT;                                                 \
        hrfid;                                                          \
        b       hrfi_flush_fallback
@@ -226,6 +254,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
 #define __EXCEPTION_PROLOG_1(area, extra, vec)                         \
        OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR);         \
        OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);          \
+       INTERRUPT_TO_KERNEL;                                            \
        SAVE_CTR(r10, area);                                            \
        mfcr    r9;                                                     \
        extra(vec);                                                     \
@@ -512,6 +541,12 @@ label##_relon_hv:                                          
\
 #define _MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)              \
        __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)
 
+#define MASKABLE_EXCEPTION_OOL(vec, label)                             \
+       .globl label##_ool;                                             \
+label##_ool:                                                           \
+       EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec);            \
+       EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD);
+
 #define MASKABLE_EXCEPTION_PSERIES(loc, vec, label)                    \
        . = loc;                                                        \
        .globl label##_pSeries;                                         \
diff --git a/arch/powerpc/include/asm/feature-fixups.h 
b/arch/powerpc/include/asm/feature-fixups.h
index 7068bafbb2d6..145a37ab2d3e 100644
- --- a/arch/powerpc/include/asm/feature-fixups.h
+++ b/arch/powerpc/include/asm/feature-fixups.h
@@ -184,6 +184,22 @@ label##3:                                          \
        FTR_ENTRY_OFFSET label##1b-label##3b;           \
        .popsection;
 
+#define STF_ENTRY_BARRIER_FIXUP_SECTION                        \
+953:                                                   \
+       .pushsection __stf_entry_barrier_fixup,"a";     \
+       .align 2;                                       \
+954:                                                   \
+       FTR_ENTRY_OFFSET 953b-954b;                     \
+       .popsection;
+
+#define STF_EXIT_BARRIER_FIXUP_SECTION                 \
+955:                                                   \
+       .pushsection __stf_exit_barrier_fixup,"a";      \
+       .align 2;                                       \
+956:                                                   \
+       FTR_ENTRY_OFFSET 955b-956b;                     \
+       .popsection;
+
 #define RFI_FLUSH_FIXUP_SECTION                                \
 951:                                                   \
        .pushsection __rfi_flush_fixup,"a";             \
@@ -192,10 +208,34 @@ label##3:                                         \
        FTR_ENTRY_OFFSET 951b-952b;                     \
        .popsection;
 
+#define NOSPEC_BARRIER_FIXUP_SECTION                   \
+953:                                                   \
+       .pushsection __barrier_nospec_fixup,"a";        \
+       .align 2;                                       \
+954:                                                   \
+       FTR_ENTRY_OFFSET 953b-954b;                     \
+       .popsection;
+
+#define START_BTB_FLUSH_SECTION                        \
+955:                                                   \
+
+#define END_BTB_FLUSH_SECTION                  \
+956:                                                   \
+       .pushsection __btb_flush_fixup,"a";     \
+       .align 2;                                                       \
+957:                                           \
+       FTR_ENTRY_OFFSET 955b-957b;                     \
+       FTR_ENTRY_OFFSET 956b-957b;                     \
+       .popsection;
 
 #ifndef __ASSEMBLY__
 
+extern long stf_barrier_fallback;
+extern long __start___stf_entry_barrier_fixup, 
__stop___stf_entry_barrier_fixup;
+extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
 extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
+extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup;
+extern long __start__btb_flush_fixup, __stop__btb_flush_fixup;
 
 #endif
 
diff --git a/arch/powerpc/include/asm/hvcall.h 
b/arch/powerpc/include/asm/hvcall.h
index 449bbb87c257..b57db9d09db9 100644
- --- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -292,10 +292,15 @@
 #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_CHAR_BRANCH_HINTS_HONORED        (1ull << 58) // IBM bit 5
+#define H_CPU_CHAR_THREAD_RECONFIG_CTRL        (1ull << 57) // IBM bit 6
+#define H_CPU_CHAR_COUNT_CACHE_DISABLED        (1ull << 56) // IBM bit 7
+#define H_CPU_CHAR_BCCTR_FLUSH_ASSIST  (1ull << 54) // IBM bit 9
 
 #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
+#define H_CPU_BEHAV_FLUSH_COUNT_CACHE  (1ull << 58) // IBM bit 5
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 45e2aefece16..08e5df3395fa 100644
- --- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -199,8 +199,7 @@ struct paca_struct {
         */
        u64 exrfi[13] __aligned(0x80);
        void *rfi_flush_fallback_area;
- -     u64 l1d_flush_congruence;
- -     u64 l1d_flush_sets;
+       u64 l1d_flush_size;
 #endif
 };
 
diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index 7ab04fc59e24..faf1bb045dee 100644
- --- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -147,6 +147,7 @@
 #define PPC_INST_LWSYNC                        0x7c2004ac
 #define PPC_INST_SYNC                  0x7c0004ac
 #define PPC_INST_SYNC_MASK             0xfc0007fe
+#define PPC_INST_ISYNC                 0x4c00012c
 #define PPC_INST_LXVD2X                        0x7c000698
 #define PPC_INST_MCRXR                 0x7c000400
 #define PPC_INST_MCRXR_MASK            0xfc0007fe
diff --git a/arch/powerpc/include/asm/ppc_asm.h 
b/arch/powerpc/include/asm/ppc_asm.h
index 160bb2311bbb..d219816b3e19 100644
- --- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -821,4 +821,15 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945)
        .long 0x2400004c  /* rfid                               */
 #endif /* !CONFIG_PPC_BOOK3E */
 #endif /*  __ASSEMBLY__ */
+
+#ifdef CONFIG_PPC_FSL_BOOK3E
+#define BTB_FLUSH(reg)                 \
+       lis reg,BUCSR_INIT@h;           \
+       ori reg,reg,BUCSR_INIT@l;       \
+       mtspr SPRN_BUCSR,reg;           \
+       isync;
+#else
+#define BTB_FLUSH(reg)
+#endif /* CONFIG_PPC_FSL_BOOK3E */
+
 #endif /* _ASM_POWERPC_PPC_ASM_H */
diff --git a/arch/powerpc/include/asm/security_features.h 
b/arch/powerpc/include/asm/security_features.h
new file mode 100644
index 000000000000..759597bf0fd8
- --- /dev/null
+++ b/arch/powerpc/include/asm/security_features.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Security related feature bit definitions.
+ *
+ * Copyright 2018, Michael Ellerman, IBM Corporation.
+ */
+
+#ifndef _ASM_POWERPC_SECURITY_FEATURES_H
+#define _ASM_POWERPC_SECURITY_FEATURES_H
+
+
+extern unsigned long powerpc_security_features;
+extern bool rfi_flush;
+
+/* These are bit flags */
+enum stf_barrier_type {
+       STF_BARRIER_NONE        = 0x1,
+       STF_BARRIER_FALLBACK    = 0x2,
+       STF_BARRIER_EIEIO       = 0x4,
+       STF_BARRIER_SYNC_ORI    = 0x8,
+};
+
+void setup_stf_barrier(void);
+void do_stf_barrier_fixups(enum stf_barrier_type types);
+void setup_count_cache_flush(void);
+
+static inline void security_ftr_set(unsigned long feature)
+{
+       powerpc_security_features |= feature;
+}
+
+static inline void security_ftr_clear(unsigned long feature)
+{
+       powerpc_security_features &= ~feature;
+}
+
+static inline bool security_ftr_enabled(unsigned long feature)
+{
+       return !!(powerpc_security_features & feature);
+}
+
+
+// Features indicating support for Spectre/Meltdown mitigations
+
+// The L1-D cache can be flushed with ori r30,r30,0
+#define SEC_FTR_L1D_FLUSH_ORI30                0x0000000000000001ull
+
+// The L1-D cache can be flushed with mtspr 882,r0 (aka SPRN_TRIG2)
+#define SEC_FTR_L1D_FLUSH_TRIG2                0x0000000000000002ull
+
+// ori r31,r31,0 acts as a speculation barrier
+#define SEC_FTR_SPEC_BAR_ORI31         0x0000000000000004ull
+
+// Speculation past bctr is disabled
+#define SEC_FTR_BCCTRL_SERIALISED      0x0000000000000008ull
+
+// Entries in L1-D are private to a SMT thread
+#define SEC_FTR_L1D_THREAD_PRIV                0x0000000000000010ull
+
+// Indirect branch prediction cache disabled
+#define SEC_FTR_COUNT_CACHE_DISABLED   0x0000000000000020ull
+
+// bcctr 2,0,0 triggers a hardware assisted count cache flush
+#define SEC_FTR_BCCTR_FLUSH_ASSIST     0x0000000000000800ull
+
+
+// Features indicating need for Spectre/Meltdown mitigations
+
+// The L1-D cache should be flushed on MSR[HV] 1->0 transition (hypervisor to 
guest)
+#define SEC_FTR_L1D_FLUSH_HV           0x0000000000000040ull
+
+// The L1-D cache should be flushed on MSR[PR] 0->1 transition (kernel to 
userspace)
+#define SEC_FTR_L1D_FLUSH_PR           0x0000000000000080ull
+
+// A speculation barrier should be used for bounds checks (Spectre variant 1)
+#define SEC_FTR_BNDS_CHK_SPEC_BAR      0x0000000000000100ull
+
+// Firmware configuration indicates user favours security over performance
+#define SEC_FTR_FAVOUR_SECURITY                0x0000000000000200ull
+
+// Software required to flush count cache on context switch
+#define SEC_FTR_FLUSH_COUNT_CACHE      0x0000000000000400ull
+
+
+// Features enabled by default
+#define SEC_FTR_DEFAULT \
+       (SEC_FTR_L1D_FLUSH_HV | \
+        SEC_FTR_L1D_FLUSH_PR | \
+        SEC_FTR_BNDS_CHK_SPEC_BAR | \
+        SEC_FTR_FAVOUR_SECURITY)
+
+#endif /* _ASM_POWERPC_SECURITY_FEATURES_H */
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 7916b56f2e60..d299479c770b 100644
- --- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -8,6 +8,7 @@ extern void ppc_printk_progress(char *s, unsigned short hex);
 
 extern unsigned int rtas_data;
 extern unsigned long long memory_limit;
+extern bool init_mem_is_free;
 extern unsigned long klimit;
 extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
 
@@ -36,8 +37,28 @@ enum l1d_flush_type {
        L1D_FLUSH_MTTRIG        = 0x8,
 };
 
- -void __init setup_rfi_flush(enum l1d_flush_type, bool enable);
+void setup_rfi_flush(enum l1d_flush_type, bool enable);
 void do_rfi_flush_fixups(enum l1d_flush_type types);
+#ifdef CONFIG_PPC_BARRIER_NOSPEC
+void setup_barrier_nospec(void);
+#else
+static inline void setup_barrier_nospec(void) { };
+#endif
+void do_barrier_nospec_fixups(bool enable);
+extern bool barrier_nospec_enabled;
+
+#ifdef CONFIG_PPC_BARRIER_NOSPEC
+void do_barrier_nospec_fixups_range(bool enable, void *start, void *end);
+#else
+static inline void do_barrier_nospec_fixups_range(bool enable, void *start, 
void *end) { };
+#endif
+
+#ifdef CONFIG_PPC_FSL_BOOK3E
+void setup_spectre_v2(void);
+#else
+static inline void setup_spectre_v2(void) {};
+#endif
+void do_btb_flush_fixups(void);
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/powerpc/include/asm/uaccess.h 
b/arch/powerpc/include/asm/uaccess.h
index 05f1389228d2..e51ce5a0e221 100644
- --- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -269,6 +269,7 @@ do {                                                        
        \
        __chk_user_ptr(ptr);                                    \
        if (!is_kernel_addr((unsigned long)__gu_addr))          \
                might_fault();                                  \
+       barrier_nospec();                                       \
        __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
        (x) = (__typeof__(*(ptr)))__gu_val;                     \
        __gu_err;                                               \
@@ -283,6 +284,7 @@ do {                                                        
        \
        __chk_user_ptr(ptr);                                    \
        if (!is_kernel_addr((unsigned long)__gu_addr))          \
                might_fault();                                  \
+       barrier_nospec();                                       \
        __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
        (x) = (__force __typeof__(*(ptr)))__gu_val;                     \
        __gu_err;                                               \
@@ -295,8 +297,10 @@ do {                                                       
        \
        unsigned long  __gu_val = 0;                                    \
        __typeof__(*(ptr)) __user *__gu_addr = (ptr);           \
        might_fault();                                                  \
- -     if (access_ok(VERIFY_READ, __gu_addr, (size)))                  \
+       if (access_ok(VERIFY_READ, __gu_addr, (size))) {                \
+               barrier_nospec();                                       \
                __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
+       }                                                               \
        (x) = (__force __typeof__(*(ptr)))__gu_val;                             
\
        __gu_err;                                                       \
 })
@@ -307,6 +311,7 @@ do {                                                        
        \
        unsigned long __gu_val;                                 \
        __typeof__(*(ptr)) __user *__gu_addr = (ptr);   \
        __chk_user_ptr(ptr);                                    \
+       barrier_nospec();                                       \
        __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
        (x) = (__force __typeof__(*(ptr)))__gu_val;                     \
        __gu_err;                                               \
@@ -323,8 +328,10 @@ extern unsigned long __copy_tofrom_user(void __user *to,
 static inline unsigned long copy_from_user(void *to,
                const void __user *from, unsigned long n)
 {
- -     if (likely(access_ok(VERIFY_READ, from, n)))
+       if (likely(access_ok(VERIFY_READ, from, n))) {
+               barrier_nospec();
                return __copy_tofrom_user((__force void __user *)to, from, n);
+       }
        memset(to, 0, n);
        return n;
 }
@@ -359,21 +366,27 @@ static inline unsigned long 
__copy_from_user_inatomic(void *to,
 
                switch (n) {
                case 1:
+                       barrier_nospec();
                        __get_user_size(*(u8 *)to, from, 1, ret);
                        break;
                case 2:
+                       barrier_nospec();
                        __get_user_size(*(u16 *)to, from, 2, ret);
                        break;
                case 4:
+                       barrier_nospec();
                        __get_user_size(*(u32 *)to, from, 4, ret);
                        break;
                case 8:
+                       barrier_nospec();
                        __get_user_size(*(u64 *)to, from, 8, ret);
                        break;
                }
                if (ret == 0)
                        return 0;
        }
+
+       barrier_nospec();
        return __copy_tofrom_user((__force void __user *)to, from, n);
 }
 
@@ -400,6 +413,7 @@ static inline unsigned long __copy_to_user_inatomic(void 
__user *to,
                if (ret == 0)
                        return 0;
        }
+
        return __copy_tofrom_user(to, (__force const void __user *)from, n);
 }
 
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index ba336930d448..22ed3c32fca8 100644
- --- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_PPC_BOOK3S_64)   += cpu_setup_power.o
 obj-$(CONFIG_PPC_BOOK3S_64)    += mce.o mce_power.o
 obj64-$(CONFIG_RELOCATABLE)    += reloc_64.o
 obj-$(CONFIG_PPC_BOOK3E_64)    += exceptions-64e.o idle_book3e.o
+obj-$(CONFIG_PPC_BARRIER_NOSPEC) += security.o
 obj-$(CONFIG_PPC64)            += vdso64/
 obj-$(CONFIG_ALTIVEC)          += vecemu.o
 obj-$(CONFIG_PPC_970_NAP)      += idle_power4.o
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index d92705e3a0c1..de3c29c51503 100644
- --- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -245,8 +245,7 @@ int main(void)
        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));
+       DEFINE(PACA_L1D_FLUSH_SIZE, offsetof(struct paca_struct, 
l1d_flush_size));
 #endif
        DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
        DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 59be96917369..6d36a4fb4acf 100644
- --- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -25,6 +25,7 @@
 #include <asm/page.h>
 #include <asm/mmu.h>
 #include <asm/thread_info.h>
+#include <asm/code-patching-asm.h>
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/cputable.h>
@@ -36,6 +37,7 @@
 #include <asm/hw_irq.h>
 #include <asm/context_tracking.h>
 #include <asm/tm.h>
+#include <asm/barrier.h>
 #ifdef CONFIG_PPC_BOOK3S
 #include <asm/exception-64s.h>
 #else
@@ -75,6 +77,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
        std     r0,GPR0(r1)
        std     r10,GPR1(r1)
        beq     2f                      /* if from kernel mode */
+#ifdef CONFIG_PPC_FSL_BOOK3E
+START_BTB_FLUSH_SECTION
+       BTB_FLUSH(r10)
+END_BTB_FLUSH_SECTION
+#endif
        ACCOUNT_CPU_USER_ENTRY(r10, r11)
 2:     std     r2,GPR2(r1)
        std     r3,GPR3(r1)
@@ -177,6 +184,15 @@ system_call:                       /* label this so stack 
traces look sane */
        clrldi  r8,r8,32
 15:
        slwi    r0,r0,4
+
+       barrier_nospec_asm
+       /*
+        * Prevent the load of the handler below (based on the user-passed
+        * system call number) being speculatively executed until the test
+        * against NR_syscalls and branch to .Lsyscall_enosys above has
+        * committed.
+        */
+
        ldx     r12,r11,r0      /* Fetch system call handler [ptr] */
        mtctr   r12
        bctrl                   /* Call handler */
@@ -440,6 +456,57 @@ _GLOBAL(ret_from_kernel_thread)
        li      r3,0
        b       .Lsyscall_exit
 
+#ifdef CONFIG_PPC_BOOK3S_64
+
+#define FLUSH_COUNT_CACHE      \
+1:     nop;                    \
+       patch_site 1b, patch__call_flush_count_cache
+
+
+#define BCCTR_FLUSH    .long 0x4c400420
+
+.macro nops number
+       .rept \number
+       nop
+       .endr
+.endm
+
+.balign 32
+.global flush_count_cache
+flush_count_cache:
+       /* Save LR into r9 */
+       mflr    r9
+
+       .rept 64
+       bl      .+4
+       .endr
+       b       1f
+       nops    6
+
+       .balign 32
+       /* Restore LR */
+1:     mtlr    r9
+       li      r9,0x7fff
+       mtctr   r9
+
+       BCCTR_FLUSH
+
+2:     nop
+       patch_site 2b patch__flush_count_cache_return
+
+       nops    3
+
+       .rept 278
+       .balign 32
+       BCCTR_FLUSH
+       nops    7
+       .endr
+
+       blr
+#else
+#define FLUSH_COUNT_CACHE
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
 /*
  * This routine switches between two different tasks.  The process
  * state of one is saved on its kernel stack.  Then the state
@@ -503,6 +570,8 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 #endif
 
+       FLUSH_COUNT_CACHE
+
 #ifdef CONFIG_SMP
        /* We need a sync somewhere here to make sure that if the
         * previous task gets rescheduled on another CPU, it sees all
diff --git a/arch/powerpc/kernel/exceptions-64e.S 
b/arch/powerpc/kernel/exceptions-64e.S
index 5cc93f0b52ca..48ec841ea1bf 100644
- --- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -295,7 +295,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
        andi.   r10,r11,MSR_PR;         /* save stack pointer */            \
        beq     1f;                     /* branch around if supervisor */   \
        ld      r1,PACAKSAVE(r13);      /* get kernel stack coming from usr */\
- -1:   cmpdi   cr1,r1,0;               /* check if SP makes sense */       \
+1:     type##_BTB_FLUSH                \
+       cmpdi   cr1,r1,0;               /* check if SP makes sense */       \
        bge-    cr1,exc_##n##_bad_stack;/* bad stack (TODO: out of line) */ \
        mfspr   r10,SPRN_##type##_SRR0; /* read SRR0 before touching stack */
 
@@ -327,6 +328,30 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
 #define SPRN_MC_SRR0   SPRN_MCSRR0
 #define SPRN_MC_SRR1   SPRN_MCSRR1
 
+#ifdef CONFIG_PPC_FSL_BOOK3E
+#define GEN_BTB_FLUSH                  \
+       START_BTB_FLUSH_SECTION         \
+               beq 1f;                 \
+               BTB_FLUSH(r10)                  \
+               1:              \
+       END_BTB_FLUSH_SECTION
+
+#define CRIT_BTB_FLUSH                 \
+       START_BTB_FLUSH_SECTION         \
+               BTB_FLUSH(r10)          \
+       END_BTB_FLUSH_SECTION
+
+#define DBG_BTB_FLUSH CRIT_BTB_FLUSH
+#define MC_BTB_FLUSH CRIT_BTB_FLUSH
+#define GDBELL_BTB_FLUSH GEN_BTB_FLUSH
+#else
+#define GEN_BTB_FLUSH
+#define CRIT_BTB_FLUSH
+#define DBG_BTB_FLUSH
+#define MC_BTB_FLUSH
+#define GDBELL_BTB_FLUSH
+#endif
+
 #define NORMAL_EXCEPTION_PROLOG(n, intnum, addition)                       \
        EXCEPTION_PROLOG(n, intnum, GEN, addition##_GEN(n))
 
diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 938a30fef031..10e7cec9553d 100644
- --- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -36,6 +36,7 @@ BEGIN_FTR_SECTION                                             
\
 END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)                         \
        mr      r9,r13 ;                                        \
        GET_PACA(r13) ;                                         \
+       INTERRUPT_TO_KERNEL ;                                   \
        mfspr   r11,SPRN_SRR0 ;                                 \
 0:
 
@@ -292,7 +293,9 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
        . = 0x900
        .globl decrementer_pSeries
 decrementer_pSeries:
- -     _MASKABLE_EXCEPTION_PSERIES(0x900, decrementer, EXC_STD, SOFTEN_TEST_PR)
+       SET_SCRATCH0(r13)
+       EXCEPTION_PROLOG_0(PACA_EXGEN)
+       b       decrementer_ool
 
        STD_EXCEPTION_HV(0x980, 0x982, hdecrementer)
 
@@ -319,6 +322,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
        OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR);
        HMT_MEDIUM;
        std     r10,PACA_EXGEN+EX_R10(r13)
+       INTERRUPT_TO_KERNEL
        OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r9, CPU_FTR_HAS_PPR);
        mfcr    r9
        KVMTEST(0xc00)
@@ -607,6 +611,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
 
        .align  7
        /* moved from 0xe00 */
+       MASKABLE_EXCEPTION_OOL(0x900, decrementer)
        STD_EXCEPTION_HV_OOL(0xe02, h_data_storage)
        KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0xe02)
        STD_EXCEPTION_HV_OOL(0xe22, h_instr_storage)
@@ -1564,6 +1569,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        blr
 #endif
 
+       .balign 16
+       .globl stf_barrier_fallback
+stf_barrier_fallback:
+       std     r9,PACA_EXRFI+EX_R9(r13)
+       std     r10,PACA_EXRFI+EX_R10(r13)
+       sync
+       ld      r9,PACA_EXRFI+EX_R9(r13)
+       ld      r10,PACA_EXRFI+EX_R10(r13)
+       ori     31,31,0
+       .rept 14
+       b       1f
+1:
+       .endr
+       blr
+
        .globl rfi_flush_fallback
 rfi_flush_fallback:
        SET_SCRATCH0(r13);
@@ -1571,39 +1591,37 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        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
+       ld      r11,PACA_L1D_FLUSH_SIZE(r13)
+       srdi    r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */
        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 */
+
+       /*
+        * The load adresses are at staggered offsets within cachelines,
+        * which suits some pipelines better (on others it should not
+        * hurt).
+        */
+1:
+       ld      r11,(0x80 + 8)*0(r10)
+       ld      r11,(0x80 + 8)*1(r10)
+       ld      r11,(0x80 + 8)*2(r10)
+       ld      r11,(0x80 + 8)*3(r10)
+       ld      r11,(0x80 + 8)*4(r10)
+       ld      r11,(0x80 + 8)*5(r10)
+       ld      r11,(0x80 + 8)*6(r10)
+       ld      r11,(0x80 + 8)*7(r10)
+       addi    r10,r10,0x80*8
        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
 
@@ -1614,39 +1632,37 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        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
+       ld      r11,PACA_L1D_FLUSH_SIZE(r13)
+       srdi    r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */
        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 */
+
+       /*
+        * The load adresses are at staggered offsets within cachelines,
+        * which suits some pipelines better (on others it should not
+        * hurt).
+        */
+1:
+       ld      r11,(0x80 + 8)*0(r10)
+       ld      r11,(0x80 + 8)*1(r10)
+       ld      r11,(0x80 + 8)*2(r10)
+       ld      r11,(0x80 + 8)*3(r10)
+       ld      r11,(0x80 + 8)*4(r10)
+       ld      r11,(0x80 + 8)*5(r10)
+       ld      r11,(0x80 + 8)*6(r10)
+       ld      r11,(0x80 + 8)*7(r10)
+       addi    r10,r10,0x80*8
        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
 
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 9547381b631a..ff009be97a42 100644
- --- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -67,7 +67,15 @@ int module_finalize(const Elf_Ehdr *hdr,
                do_feature_fixups(powerpc_firmware_features,
                                  (void *)sect->sh_addr,
                                  (void *)sect->sh_addr + sect->sh_size);
- -#endif
+#endif /* CONFIG_PPC64 */
+
+#ifdef CONFIG_PPC_BARRIER_NOSPEC
+       sect = find_section(hdr, sechdrs, "__spec_barrier_fixup");
+       if (sect != NULL)
+               do_barrier_nospec_fixups_range(barrier_nospec_enabled,
+                                 (void *)sect->sh_addr,
+                                 (void *)sect->sh_addr + sect->sh_size);
+#endif /* CONFIG_PPC_BARRIER_NOSPEC */
 
        sect = find_section(hdr, sechdrs, "__lwsync_fixup");
        if (sect != NULL)
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
new file mode 100644
index 000000000000..58f0602a92b9
- --- /dev/null
+++ b/arch/powerpc/kernel/security.c
@@ -0,0 +1,433 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Security related flags and so on.
+//
+// Copyright 2018, Michael Ellerman, IBM Corporation.
+
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/seq_buf.h>
+
+#include <asm/debug.h>
+#include <asm/asm-prototypes.h>
+#include <asm/code-patching.h>
+#include <asm/security_features.h>
+#include <asm/setup.h>
+
+
+unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
+
+enum count_cache_flush_type {
+       COUNT_CACHE_FLUSH_NONE  = 0x1,
+       COUNT_CACHE_FLUSH_SW    = 0x2,
+       COUNT_CACHE_FLUSH_HW    = 0x4,
+};
+static enum count_cache_flush_type count_cache_flush_type = 
COUNT_CACHE_FLUSH_NONE;
+
+bool barrier_nospec_enabled;
+static bool no_nospec;
+static bool btb_flush_enabled;
+#ifdef CONFIG_PPC_FSL_BOOK3E
+static bool no_spectrev2;
+#endif
+
+static void enable_barrier_nospec(bool enable)
+{
+       barrier_nospec_enabled = enable;
+       do_barrier_nospec_fixups(enable);
+}
+
+void setup_barrier_nospec(void)
+{
+       bool enable;
+
+       /*
+        * It would make sense to check SEC_FTR_SPEC_BAR_ORI31 below as well.
+        * But there's a good reason not to. The two flags we check below are
+        * both are enabled by default in the kernel, so if the hcall is not
+        * functional they will be enabled.
+        * On a system where the host firmware has been updated (so the ori
+        * functions as a barrier), but on which the hypervisor (KVM/Qemu) has
+        * not been updated, we would like to enable the barrier. Dropping the
+        * check for SEC_FTR_SPEC_BAR_ORI31 achieves that. The only downside is
+        * we potentially enable the barrier on systems where the host firmware
+        * is not updated, but that's harmless as it's a no-op.
+        */
+       enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
+                security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR);
+
+       if (!no_nospec)
+               enable_barrier_nospec(enable);
+}
+
+static int __init handle_nospectre_v1(char *p)
+{
+       no_nospec = true;
+
+       return 0;
+}
+early_param("nospectre_v1", handle_nospectre_v1);
+
+#ifdef CONFIG_DEBUG_FS
+static int barrier_nospec_set(void *data, u64 val)
+{
+       switch (val) {
+       case 0:
+       case 1:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (!!val == !!barrier_nospec_enabled)
+               return 0;
+
+       enable_barrier_nospec(!!val);
+
+       return 0;
+}
+
+static int barrier_nospec_get(void *data, u64 *val)
+{
+       *val = barrier_nospec_enabled ? 1 : 0;
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_barrier_nospec,
+                       barrier_nospec_get, barrier_nospec_set, "%llu\n");
+
+static __init int barrier_nospec_debugfs_init(void)
+{
+       debugfs_create_file("barrier_nospec", 0600, powerpc_debugfs_root, NULL,
+                           &fops_barrier_nospec);
+       return 0;
+}
+device_initcall(barrier_nospec_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
+
+#ifdef CONFIG_PPC_FSL_BOOK3E
+static int __init handle_nospectre_v2(char *p)
+{
+       no_spectrev2 = true;
+
+       return 0;
+}
+early_param("nospectre_v2", handle_nospectre_v2);
+void setup_spectre_v2(void)
+{
+       if (no_spectrev2)
+               do_btb_flush_fixups();
+       else
+               btb_flush_enabled = true;
+}
+#endif /* CONFIG_PPC_FSL_BOOK3E */
+
+#ifdef CONFIG_PPC_BOOK3S_64
+ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, 
char *buf)
+{
+       bool thread_priv;
+
+       thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);
+
+       if (rfi_flush || thread_priv) {
+               struct seq_buf s;
+               seq_buf_init(&s, buf, PAGE_SIZE - 1);
+
+               seq_buf_printf(&s, "Mitigation: ");
+
+               if (rfi_flush)
+                       seq_buf_printf(&s, "RFI Flush");
+
+               if (rfi_flush && thread_priv)
+                       seq_buf_printf(&s, ", ");
+
+               if (thread_priv)
+                       seq_buf_printf(&s, "L1D private per thread");
+
+               seq_buf_printf(&s, "\n");
+
+               return s.len;
+       }
+
+       if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
+           !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
+               return sprintf(buf, "Not affected\n");
+
+       return sprintf(buf, "Vulnerable\n");
+}
+#endif
+
+ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, 
char *buf)
+{
+       struct seq_buf s;
+
+       seq_buf_init(&s, buf, PAGE_SIZE - 1);
+
+       if (security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR)) {
+               if (barrier_nospec_enabled)
+                       seq_buf_printf(&s, "Mitigation: __user pointer 
sanitization");
+               else
+                       seq_buf_printf(&s, "Vulnerable");
+
+               if (security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31))
+                       seq_buf_printf(&s, ", ori31 speculation barrier 
enabled");
+
+               seq_buf_printf(&s, "\n");
+       } else
+               seq_buf_printf(&s, "Not affected\n");
+
+       return s.len;
+}
+
+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, 
char *buf)
+{
+       struct seq_buf s;
+       bool bcs, ccd;
+
+       seq_buf_init(&s, buf, PAGE_SIZE - 1);
+
+       bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED);
+       ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED);
+
+       if (bcs || ccd) {
+               seq_buf_printf(&s, "Mitigation: ");
+
+               if (bcs)
+                       seq_buf_printf(&s, "Indirect branch serialisation 
(kernel only)");
+
+               if (bcs && ccd)
+                       seq_buf_printf(&s, ", ");
+
+               if (ccd)
+                       seq_buf_printf(&s, "Indirect branch cache disabled");
+       } else if (count_cache_flush_type != COUNT_CACHE_FLUSH_NONE) {
+               seq_buf_printf(&s, "Mitigation: Software count cache flush");
+
+               if (count_cache_flush_type == COUNT_CACHE_FLUSH_HW)
+                       seq_buf_printf(&s, " (hardware accelerated)");
+       } else if (btb_flush_enabled) {
+               seq_buf_printf(&s, "Mitigation: Branch predictor state flush");
+       } else {
+               seq_buf_printf(&s, "Vulnerable");
+       }
+
+       seq_buf_printf(&s, "\n");
+
+       return s.len;
+}
+
+#ifdef CONFIG_PPC_BOOK3S_64
+/*
+ * Store-forwarding barrier support.
+ */
+
+static enum stf_barrier_type stf_enabled_flush_types;
+static bool no_stf_barrier;
+bool stf_barrier;
+
+static int __init handle_no_stf_barrier(char *p)
+{
+       pr_info("stf-barrier: disabled on command line.");
+       no_stf_barrier = true;
+       return 0;
+}
+
+early_param("no_stf_barrier", handle_no_stf_barrier);
+
+/* This is the generic flag used by other architectures */
+static int __init handle_ssbd(char *p)
+{
+       if (!p || strncmp(p, "auto", 5) == 0 || strncmp(p, "on", 2) == 0 ) {
+               /* Until firmware tells us, we have the barrier with auto */
+               return 0;
+       } else if (strncmp(p, "off", 3) == 0) {
+               handle_no_stf_barrier(NULL);
+               return 0;
+       } else
+               return 1;
+
+       return 0;
+}
+early_param("spec_store_bypass_disable", handle_ssbd);
+
+/* This is the generic flag used by other architectures */
+static int __init handle_no_ssbd(char *p)
+{
+       handle_no_stf_barrier(NULL);
+       return 0;
+}
+early_param("nospec_store_bypass_disable", handle_no_ssbd);
+
+static void stf_barrier_enable(bool enable)
+{
+       if (enable)
+               do_stf_barrier_fixups(stf_enabled_flush_types);
+       else
+               do_stf_barrier_fixups(STF_BARRIER_NONE);
+
+       stf_barrier = enable;
+}
+
+void setup_stf_barrier(void)
+{
+       enum stf_barrier_type type;
+       bool enable, hv;
+
+       hv = cpu_has_feature(CPU_FTR_HVMODE);
+
+       /* Default to fallback in case fw-features are not available */
+       if (cpu_has_feature(CPU_FTR_ARCH_207S))
+               type = STF_BARRIER_SYNC_ORI;
+       else if (cpu_has_feature(CPU_FTR_ARCH_206))
+               type = STF_BARRIER_FALLBACK;
+       else
+               type = STF_BARRIER_NONE;
+
+       enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
+               (security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR) ||
+                (security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) && hv));
+
+       if (type == STF_BARRIER_FALLBACK) {
+               pr_info("stf-barrier: fallback barrier available\n");
+       } else if (type == STF_BARRIER_SYNC_ORI) {
+               pr_info("stf-barrier: hwsync barrier available\n");
+       } else if (type == STF_BARRIER_EIEIO) {
+               pr_info("stf-barrier: eieio barrier available\n");
+       }
+
+       stf_enabled_flush_types = type;
+
+       if (!no_stf_barrier)
+               stf_barrier_enable(enable);
+}
+
+ssize_t cpu_show_spec_store_bypass(struct device *dev, struct device_attribute 
*attr, char *buf)
+{
+       if (stf_barrier && stf_enabled_flush_types != STF_BARRIER_NONE) {
+               const char *type;
+               switch (stf_enabled_flush_types) {
+               case STF_BARRIER_EIEIO:
+                       type = "eieio";
+                       break;
+               case STF_BARRIER_SYNC_ORI:
+                       type = "hwsync";
+                       break;
+               case STF_BARRIER_FALLBACK:
+                       type = "fallback";
+                       break;
+               default:
+                       type = "unknown";
+               }
+               return sprintf(buf, "Mitigation: Kernel entry/exit barrier 
(%s)\n", type);
+       }
+
+       if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
+           !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
+               return sprintf(buf, "Not affected\n");
+
+       return sprintf(buf, "Vulnerable\n");
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int stf_barrier_set(void *data, u64 val)
+{
+       bool enable;
+
+       if (val == 1)
+               enable = true;
+       else if (val == 0)
+               enable = false;
+       else
+               return -EINVAL;
+
+       /* Only do anything if we're changing state */
+       if (enable != stf_barrier)
+               stf_barrier_enable(enable);
+
+       return 0;
+}
+
+static int stf_barrier_get(void *data, u64 *val)
+{
+       *val = stf_barrier ? 1 : 0;
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_stf_barrier, stf_barrier_get, stf_barrier_set, 
"%llu\n");
+
+static __init int stf_barrier_debugfs_init(void)
+{
+       debugfs_create_file("stf_barrier", 0600, powerpc_debugfs_root, NULL, 
&fops_stf_barrier);
+       return 0;
+}
+device_initcall(stf_barrier_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
+
+static void toggle_count_cache_flush(bool enable)
+{
+       if (!enable || !security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) {
+               patch_instruction_site(&patch__call_flush_count_cache, 
PPC_INST_NOP);
+               count_cache_flush_type = COUNT_CACHE_FLUSH_NONE;
+               pr_info("count-cache-flush: software flush disabled.\n");
+               return;
+       }
+
+       patch_branch_site(&patch__call_flush_count_cache,
+                         (u64)&flush_count_cache, BRANCH_SET_LINK);
+
+       if (!security_ftr_enabled(SEC_FTR_BCCTR_FLUSH_ASSIST)) {
+               count_cache_flush_type = COUNT_CACHE_FLUSH_SW;
+               pr_info("count-cache-flush: full software flush sequence 
enabled.\n");
+               return;
+       }
+
+       patch_instruction_site(&patch__flush_count_cache_return, PPC_INST_BLR);
+       count_cache_flush_type = COUNT_CACHE_FLUSH_HW;
+       pr_info("count-cache-flush: hardware assisted flush sequence 
enabled\n");
+}
+
+void setup_count_cache_flush(void)
+{
+       toggle_count_cache_flush(true);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int count_cache_flush_set(void *data, u64 val)
+{
+       bool enable;
+
+       if (val == 1)
+               enable = true;
+       else if (val == 0)
+               enable = false;
+       else
+               return -EINVAL;
+
+       toggle_count_cache_flush(enable);
+
+       return 0;
+}
+
+static int count_cache_flush_get(void *data, u64 *val)
+{
+       if (count_cache_flush_type == COUNT_CACHE_FLUSH_NONE)
+               *val = 0;
+       else
+               *val = 1;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_count_cache_flush, count_cache_flush_get,
+                       count_cache_flush_set, "%llu\n");
+
+static __init int count_cache_flush_debugfs_init(void)
+{
+       debugfs_create_file("count_cache_flush", 0600, powerpc_debugfs_root,
+                           NULL, &fops_count_cache_flush);
+       return 0;
+}
+device_initcall(count_cache_flush_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
+#endif /* CONFIG_PPC_BOOK3S_64 */
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index ad8c9db61237..5a9f035bcd6b 100644
- --- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -322,6 +322,8 @@ void __init setup_arch(char **cmdline_p)
                ppc_md.setup_arch();
        if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
 
+       setup_barrier_nospec();
+
        paging_init();
 
        /* Initialize the MMU context management stuff */
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 9eb469bed22b..6bb731ababc6 100644
- --- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -736,6 +736,8 @@ void __init setup_arch(char **cmdline_p)
        if (ppc_md.setup_arch)
                ppc_md.setup_arch();
 
+       setup_barrier_nospec();
+
        paging_init();
 
        /* Initialize the MMU context management stuff */
@@ -873,9 +875,6 @@ static void do_nothing(void *unused)
 
 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);
@@ -885,11 +884,15 @@ void rfi_flush_enable(bool enable)
        rfi_flush = enable;
 }
 
- -static void init_fallback_flush(void)
+static void __ref init_fallback_flush(void)
 {
        u64 l1d_size, limit;
        int cpu;
 
+       /* Only allocate the fallback flush area once (at boot time). */
+       if (l1d_flush_fallback_area)
+               return;
+
        l1d_size = ppc64_caches.dsize;
        limit = min(safe_stack_limit(), ppc64_rma_size);
 
@@ -902,34 +905,23 @@ static void init_fallback_flush(void)
        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;
+               paca[cpu].l1d_flush_size = l1d_size;
        }
 }
 
- -void __init setup_rfi_flush(enum l1d_flush_type types, bool enable)
+void setup_rfi_flush(enum l1d_flush_type types, bool enable)
 {
        if (types & L1D_FLUSH_FALLBACK) {
- -             pr_info("rfi-flush: Using fallback displacement flush\n");
+               pr_info("rfi-flush: fallback displacement flush available\n");
                init_fallback_flush();
        }
 
        if (types & L1D_FLUSH_ORI)
- -             pr_info("rfi-flush: Using ori type flush\n");
+               pr_info("rfi-flush: ori type flush available\n");
 
        if (types & L1D_FLUSH_MTTRIG)
- -             pr_info("rfi-flush: Using mttrig type flush\n");
+               pr_info("rfi-flush: mttrig type flush available\n");
 
        enabled_flush_types = types;
 
@@ -940,13 +932,19 @@ void __init setup_rfi_flush(enum l1d_flush_type types, 
bool enable)
 #ifdef CONFIG_DEBUG_FS
 static int rfi_flush_set(void *data, u64 val)
 {
+       bool enable;
+
        if (val == 1)
- -             rfi_flush_enable(true);
+               enable = true;
        else if (val == 0)
- -             rfi_flush_enable(false);
+               enable = false;
        else
                return -EINVAL;
 
+       /* Only do anything if we're changing state */
+       if (enable != rfi_flush)
+               rfi_flush_enable(enable);
+
        return 0;
 }
 
@@ -965,12 +963,4 @@ static __init int rfi_flush_debugfs_init(void)
 }
 device_initcall(rfi_flush_debugfs_init);
 #endif
- -
- -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 */
diff --git a/arch/powerpc/kernel/vmlinux.lds.S 
b/arch/powerpc/kernel/vmlinux.lds.S
index 072a23a17350..876ac9d52afc 100644
- --- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -73,14 +73,45 @@ SECTIONS
        RODATA
 
 #ifdef CONFIG_PPC64
+       . = ALIGN(8);
+       __stf_entry_barrier_fixup : AT(ADDR(__stf_entry_barrier_fixup) - 
LOAD_OFFSET) {
+               __start___stf_entry_barrier_fixup = .;
+               *(__stf_entry_barrier_fixup)
+               __stop___stf_entry_barrier_fixup = .;
+       }
+
+       . = ALIGN(8);
+       __stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - 
LOAD_OFFSET) {
+               __start___stf_exit_barrier_fixup = .;
+               *(__stf_exit_barrier_fixup)
+               __stop___stf_exit_barrier_fixup = .;
+       }
+
        . = ALIGN(8);
        __rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) {
                __start___rfi_flush_fixup = .;
                *(__rfi_flush_fixup)
                __stop___rfi_flush_fixup = .;
        }
- -#endif
+#endif /* CONFIG_PPC64 */
 
+#ifdef CONFIG_PPC_BARRIER_NOSPEC
+       . = ALIGN(8);
+       __spec_barrier_fixup : AT(ADDR(__spec_barrier_fixup) - LOAD_OFFSET) {
+               __start___barrier_nospec_fixup = .;
+               *(__barrier_nospec_fixup)
+               __stop___barrier_nospec_fixup = .;
+       }
+#endif /* CONFIG_PPC_BARRIER_NOSPEC */
+
+#ifdef CONFIG_PPC_FSL_BOOK3E
+       . = ALIGN(8);
+       __spec_btb_flush_fixup : AT(ADDR(__spec_btb_flush_fixup) - LOAD_OFFSET) 
{
+               __start__btb_flush_fixup = .;
+               *(__btb_flush_fixup)
+               __stop__btb_flush_fixup = .;
+       }
+#endif
        EXCEPTION_TABLE(0)
 
        NOTES :kernel :notes
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index d5edbeb8eb82..570c06a00db6 100644
- --- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -14,12 +14,25 @@
 #include <asm/page.h>
 #include <asm/code-patching.h>
 #include <asm/uaccess.h>
+#include <asm/setup.h>
+#include <asm/sections.h>
 
 
+static inline bool is_init(unsigned int *addr)
+{
+       return addr >= (unsigned int *)__init_begin && addr < (unsigned int 
*)__init_end;
+}
+
 int patch_instruction(unsigned int *addr, unsigned int instr)
 {
        int err;
 
+       /* Make sure we aren't patching a freed init section */
+       if (init_mem_is_free && is_init(addr)) {
+               pr_debug("Skipping init section patching addr: 0x%px\n", addr);
+               return 0;
+       }
+
        __put_user_size(instr, addr, 4, err);
        if (err)
                return err;
@@ -32,6 +45,22 @@ int patch_branch(unsigned int *addr, unsigned long target, 
int flags)
        return patch_instruction(addr, create_branch(addr, target, flags));
 }
 
+int patch_branch_site(s32 *site, unsigned long target, int flags)
+{
+       unsigned int *addr;
+
+       addr = (unsigned int *)((unsigned long)site + *site);
+       return patch_instruction(addr, create_branch(addr, target, flags));
+}
+
+int patch_instruction_site(s32 *site, unsigned int instr)
+{
+       unsigned int *addr;
+
+       addr = (unsigned int *)((unsigned long)site + *site);
+       return patch_instruction(addr, instr);
+}
+
 unsigned int create_branch(const unsigned int *addr,
                           unsigned long target, int flags)
 {
diff --git a/arch/powerpc/lib/feature-fixups.c 
b/arch/powerpc/lib/feature-fixups.c
index 3af014684872..7bdfc19a491d 100644
- --- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -21,7 +21,7 @@
 #include <asm/page.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
- -
+#include <asm/security_features.h>
 
 struct fixup_entry {
        unsigned long   mask;
@@ -115,6 +115,120 @@ void do_feature_fixups(unsigned long value, void 
*fixup_start, void *fixup_end)
 }
 
 #ifdef CONFIG_PPC_BOOK3S_64
+void do_stf_entry_barrier_fixups(enum stf_barrier_type types)
+{
+       unsigned int instrs[3], *dest;
+       long *start, *end;
+       int i;
+
+       start = PTRRELOC(&__start___stf_entry_barrier_fixup),
+       end = PTRRELOC(&__stop___stf_entry_barrier_fixup);
+
+       instrs[0] = 0x60000000; /* nop */
+       instrs[1] = 0x60000000; /* nop */
+       instrs[2] = 0x60000000; /* nop */
+
+       i = 0;
+       if (types & STF_BARRIER_FALLBACK) {
+               instrs[i++] = 0x7d4802a6; /* mflr r10           */
+               instrs[i++] = 0x60000000; /* branch patched below */
+               instrs[i++] = 0x7d4803a6; /* mtlr r10           */
+       } else if (types & STF_BARRIER_EIEIO) {
+               instrs[i++] = 0x7e0006ac; /* eieio + bit 6 hint */
+       } else if (types & STF_BARRIER_SYNC_ORI) {
+               instrs[i++] = 0x7c0004ac; /* hwsync             */
+               instrs[i++] = 0xe94d0000; /* ld r10,0(r13)      */
+               instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
+       }
+
+       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]);
+
+               if (types & STF_BARRIER_FALLBACK)
+                       patch_branch(dest + 1, (unsigned 
long)&stf_barrier_fallback,
+                                    BRANCH_SET_LINK);
+               else
+                       patch_instruction(dest + 1, instrs[1]);
+
+               patch_instruction(dest + 2, instrs[2]);
+       }
+
+       printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s 
barrier)\n", i,
+               (types == STF_BARRIER_NONE)                  ? "no" :
+               (types == STF_BARRIER_FALLBACK)              ? "fallback" :
+               (types == STF_BARRIER_EIEIO)                 ? "eieio" :
+               (types == (STF_BARRIER_SYNC_ORI))            ? "hwsync"
+                                                          : "unknown");
+}
+
+void do_stf_exit_barrier_fixups(enum stf_barrier_type types)
+{
+       unsigned int instrs[6], *dest;
+       long *start, *end;
+       int i;
+
+       start = PTRRELOC(&__start___stf_exit_barrier_fixup),
+       end = PTRRELOC(&__stop___stf_exit_barrier_fixup);
+
+       instrs[0] = 0x60000000; /* nop */
+       instrs[1] = 0x60000000; /* nop */
+       instrs[2] = 0x60000000; /* nop */
+       instrs[3] = 0x60000000; /* nop */
+       instrs[4] = 0x60000000; /* nop */
+       instrs[5] = 0x60000000; /* nop */
+
+       i = 0;
+       if (types & STF_BARRIER_FALLBACK || types & STF_BARRIER_SYNC_ORI) {
+               if (cpu_has_feature(CPU_FTR_HVMODE)) {
+                       instrs[i++] = 0x7db14ba6; /* mtspr 0x131, r13 (HSPRG1) 
*/
+                       instrs[i++] = 0x7db04aa6; /* mfspr r13, 0x130 (HSPRG0) 
*/
+               } else {
+                       instrs[i++] = 0x7db243a6; /* mtsprg 2,r13       */
+                       instrs[i++] = 0x7db142a6; /* mfsprg r13,1    */
+               }
+               instrs[i++] = 0x7c0004ac; /* hwsync             */
+               instrs[i++] = 0xe9ad0000; /* ld r13,0(r13)      */
+               instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
+               if (cpu_has_feature(CPU_FTR_HVMODE)) {
+                       instrs[i++] = 0x7db14aa6; /* mfspr r13, 0x131 (HSPRG1) 
*/
+               } else {
+                       instrs[i++] = 0x7db242a6; /* mfsprg r13,2 */
+               }
+       } else if (types & STF_BARRIER_EIEIO) {
+               instrs[i++] = 0x7e0006ac; /* eieio + bit 6 hint */
+       }
+
+       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]);
+               patch_instruction(dest + 3, instrs[3]);
+               patch_instruction(dest + 4, instrs[4]);
+               patch_instruction(dest + 5, instrs[5]);
+       }
+       printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s 
barrier)\n", i,
+               (types == STF_BARRIER_NONE)                  ? "no" :
+               (types == STF_BARRIER_FALLBACK)              ? "fallback" :
+               (types == STF_BARRIER_EIEIO)                 ? "eieio" :
+               (types == (STF_BARRIER_SYNC_ORI))            ? "hwsync"
+                                                          : "unknown");
+}
+
+
+void do_stf_barrier_fixups(enum stf_barrier_type types)
+{
+       do_stf_entry_barrier_fixups(types);
+       do_stf_exit_barrier_fixups(types);
+}
+
 void do_rfi_flush_fixups(enum l1d_flush_type types)
 {
        unsigned int instrs[3], *dest;
@@ -151,10 +265,110 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
                patch_instruction(dest + 2, instrs[2]);
        }
 
- -     printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i);
+       printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i,
+               (types == L1D_FLUSH_NONE)       ? "no" :
+               (types == L1D_FLUSH_FALLBACK)   ? "fallback displacement" :
+               (types &  L1D_FLUSH_ORI)        ? (types & L1D_FLUSH_MTTRIG)
+                                                       ? "ori+mttrig type"
+                                                       : "ori type" :
+               (types &  L1D_FLUSH_MTTRIG)     ? "mttrig type"
+                                               : "unknown");
+}
+
+void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void 
*fixup_end)
+{
+       unsigned int instr, *dest;
+       long *start, *end;
+       int i;
+
+       start = fixup_start;
+       end = fixup_end;
+
+       instr = 0x60000000; /* nop */
+
+       if (enable) {
+               pr_info("barrier-nospec: using ORI speculation barrier\n");
+               instr = 0x63ff0000; /* ori 31,31,0 speculation barrier */
+       }
+
+       for (i = 0; start < end; start++, i++) {
+               dest = (void *)start + *start;
+
+               pr_devel("patching dest %lx\n", (unsigned long)dest);
+               patch_instruction(dest, instr);
+       }
+
+       printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
 }
+
 #endif /* CONFIG_PPC_BOOK3S_64 */
 
+#ifdef CONFIG_PPC_BARRIER_NOSPEC
+void do_barrier_nospec_fixups(bool enable)
+{
+       void *start, *end;
+
+       start = PTRRELOC(&__start___barrier_nospec_fixup),
+       end = PTRRELOC(&__stop___barrier_nospec_fixup);
+
+       do_barrier_nospec_fixups_range(enable, start, end);
+}
+#endif /* CONFIG_PPC_BARRIER_NOSPEC */
+
+#ifdef CONFIG_PPC_FSL_BOOK3E
+void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void 
*fixup_end)
+{
+       unsigned int instr[2], *dest;
+       long *start, *end;
+       int i;
+
+       start = fixup_start;
+       end = fixup_end;
+
+       instr[0] = PPC_INST_NOP;
+       instr[1] = PPC_INST_NOP;
+
+       if (enable) {
+               pr_info("barrier-nospec: using isync; sync as speculation 
barrier\n");
+               instr[0] = PPC_INST_ISYNC;
+               instr[1] = PPC_INST_SYNC;
+       }
+
+       for (i = 0; start < end; start++, i++) {
+               dest = (void *)start + *start;
+
+               pr_devel("patching dest %lx\n", (unsigned long)dest);
+               patch_instruction(dest, instr[0]);
+               patch_instruction(dest + 1, instr[1]);
+       }
+
+       printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
+}
+
+static void patch_btb_flush_section(long *curr)
+{
+       unsigned int *start, *end;
+
+       start = (void *)curr + *curr;
+       end = (void *)curr + *(curr + 1);
+       for (; start < end; start++) {
+               pr_devel("patching dest %lx\n", (unsigned long)start);
+               patch_instruction(start, PPC_INST_NOP);
+       }
+}
+
+void do_btb_flush_fixups(void)
+{
+       long *start, *end;
+
+       start = PTRRELOC(&__start__btb_flush_fixup);
+       end = PTRRELOC(&__stop__btb_flush_fixup);
+
+       for (; start < end; start += 2)
+               patch_btb_flush_section(start);
+}
+#endif /* CONFIG_PPC_FSL_BOOK3E */
+
 void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
 {
        long *start, *end;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 22d94c3e6fc4..1efe5ca5c3bc 100644
- --- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -62,6 +62,7 @@
 #endif
 
 unsigned long long memory_limit;
+bool init_mem_is_free;
 
 #ifdef CONFIG_HIGHMEM
 pte_t *kmap_pte;
@@ -381,6 +382,7 @@ void __init mem_init(void)
 void free_initmem(void)
 {
        ppc_md.progress = ppc_printk_progress;
+       init_mem_is_free = true;
        free_initmem_default(POISON_FREE_INITMEM);
 }
 
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
index 29d6987c37ba..5486d56da289 100644
- --- a/arch/powerpc/mm/tlb_low_64e.S
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -69,6 +69,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
        std     r15,EX_TLB_R15(r12)
        std     r10,EX_TLB_CR(r12)
 #ifdef CONFIG_PPC_FSL_BOOK3E
+START_BTB_FLUSH_SECTION
+       mfspr r11, SPRN_SRR1
+       andi. r10,r11,MSR_PR
+       beq 1f
+       BTB_FLUSH(r10)
+1:
+END_BTB_FLUSH_SECTION
        std     r7,EX_TLB_R7(r12)
 #endif
        TLB_MISS_PROLOG_STATS
diff --git a/arch/powerpc/platforms/powernv/setup.c 
b/arch/powerpc/platforms/powernv/setup.c
index c57afc619b20..e14b52c7ebd8 100644
- --- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -37,53 +37,99 @@
 #include <asm/smp.h>
 #include <asm/tm.h>
 #include <asm/setup.h>
+#include <asm/security_features.h>
 
 #include "powernv.h"
 
+
+static bool fw_feature_is(const char *state, const char *name,
+                         struct device_node *fw_features)
+{
+       struct device_node *np;
+       bool rc = false;
+
+       np = of_get_child_by_name(fw_features, name);
+       if (np) {
+               rc = of_property_read_bool(np, state);
+               of_node_put(np);
+       }
+
+       return rc;
+}
+
+static void init_fw_feat_flags(struct device_node *np)
+{
+       if (fw_feature_is("enabled", "inst-spec-barrier-ori31,31,0", np))
+               security_ftr_set(SEC_FTR_SPEC_BAR_ORI31);
+
+       if (fw_feature_is("enabled", "fw-bcctrl-serialized", np))
+               security_ftr_set(SEC_FTR_BCCTRL_SERIALISED);
+
+       if (fw_feature_is("enabled", "inst-l1d-flush-ori30,30,0", np))
+               security_ftr_set(SEC_FTR_L1D_FLUSH_ORI30);
+
+       if (fw_feature_is("enabled", "inst-l1d-flush-trig2", np))
+               security_ftr_set(SEC_FTR_L1D_FLUSH_TRIG2);
+
+       if (fw_feature_is("enabled", "fw-l1d-thread-split", np))
+               security_ftr_set(SEC_FTR_L1D_THREAD_PRIV);
+
+       if (fw_feature_is("enabled", "fw-count-cache-disabled", np))
+               security_ftr_set(SEC_FTR_COUNT_CACHE_DISABLED);
+
+       if (fw_feature_is("enabled", "fw-count-cache-flush-bcctr2,0,0", np))
+               security_ftr_set(SEC_FTR_BCCTR_FLUSH_ASSIST);
+
+       if (fw_feature_is("enabled", 
"needs-count-cache-flush-on-context-switch", np))
+               security_ftr_set(SEC_FTR_FLUSH_COUNT_CACHE);
+
+       /*
+        * The features below are enabled by default, so we instead look to see
+        * if firmware has *disabled* them, and clear them if so.
+        */
+       if (fw_feature_is("disabled", "speculation-policy-favor-security", np))
+               security_ftr_clear(SEC_FTR_FAVOUR_SECURITY);
+
+       if (fw_feature_is("disabled", "needs-l1d-flush-msr-pr-0-to-1", np))
+               security_ftr_clear(SEC_FTR_L1D_FLUSH_PR);
+
+       if (fw_feature_is("disabled", "needs-l1d-flush-msr-hv-1-to-0", np))
+               security_ftr_clear(SEC_FTR_L1D_FLUSH_HV);
+
+       if (fw_feature_is("disabled", "needs-spec-barrier-for-bound-checks", 
np))
+               security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR);
+}
+
 static void pnv_setup_rfi_flush(void)
 {
        struct device_node *np, *fw_features;
        enum l1d_flush_type type;
- -     int enable;
+       bool 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;
+               init_fw_feat_flags(fw_features);
+               of_node_put(fw_features);
 
- -             of_node_put(np);
+               if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_TRIG2))
+                       type = L1D_FLUSH_MTTRIG;
 
- -             np = of_get_child_by_name(fw_features, 
"inst-l1d-flush-ori30,30,0");
- -             if (np && of_property_read_bool(np, "enabled"))
+               if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_ORI30))
                        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);
+       enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && \
+                (security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR)   || \
+                 security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV));
+
+       setup_rfi_flush(type, enable);
+       setup_count_cache_flush();
 }
 
 static void __init pnv_setup_arch(void)
@@ -91,6 +137,7 @@ static void __init pnv_setup_arch(void)
        set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
 
        pnv_setup_rfi_flush();
+       setup_stf_barrier();
 
        /* Initialize SMP */
        pnv_smp_init();
diff --git a/arch/powerpc/platforms/pseries/mobility.c 
b/arch/powerpc/platforms/pseries/mobility.c
index 8dd0c8edefd6..c773396d0969 100644
- --- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -314,6 +314,9 @@ void post_mobility_fixup(void)
                printk(KERN_ERR "Post-mobility device tree update "
                        "failed: %d\n", rc);
 
+       /* Possibly switch to a new RFI flush type */
+       pseries_setup_rfi_flush();
+
        return;
 }
 
diff --git a/arch/powerpc/platforms/pseries/pseries.h 
b/arch/powerpc/platforms/pseries/pseries.h
index 8411c27293e4..e7d80797384d 100644
- --- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -81,4 +81,6 @@ extern struct pci_controller_ops pseries_pci_controller_ops;
 
 unsigned long pseries_memory_block_size(void);
 
+void pseries_setup_rfi_flush(void);
+
 #endif /* _PSERIES_PSERIES_H */
diff --git a/arch/powerpc/platforms/pseries/setup.c 
b/arch/powerpc/platforms/pseries/setup.c
index dd2545fc9947..9cc976ff7fec 100644
- --- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -67,6 +67,7 @@
 #include <asm/eeh.h>
 #include <asm/reg.h>
 #include <asm/plpar_wrappers.h>
+#include <asm/security_features.h>
 
 #include "pseries.h"
 
@@ -499,37 +500,87 @@ static void __init find_and_init_phbs(void)
        of_pci_check_probe_only();
 }
 
- -static void pseries_setup_rfi_flush(void)
+static void init_cpu_char_feature_flags(struct h_cpu_char_result *result)
+{
+       /*
+        * The features below are disabled by default, so we instead look to see
+        * if firmware has *enabled* them, and set them if so.
+        */
+       if (result->character & H_CPU_CHAR_SPEC_BAR_ORI31)
+               security_ftr_set(SEC_FTR_SPEC_BAR_ORI31);
+
+       if (result->character & H_CPU_CHAR_BCCTRL_SERIALISED)
+               security_ftr_set(SEC_FTR_BCCTRL_SERIALISED);
+
+       if (result->character & H_CPU_CHAR_L1D_FLUSH_ORI30)
+               security_ftr_set(SEC_FTR_L1D_FLUSH_ORI30);
+
+       if (result->character & H_CPU_CHAR_L1D_FLUSH_TRIG2)
+               security_ftr_set(SEC_FTR_L1D_FLUSH_TRIG2);
+
+       if (result->character & H_CPU_CHAR_L1D_THREAD_PRIV)
+               security_ftr_set(SEC_FTR_L1D_THREAD_PRIV);
+
+       if (result->character & H_CPU_CHAR_COUNT_CACHE_DISABLED)
+               security_ftr_set(SEC_FTR_COUNT_CACHE_DISABLED);
+
+       if (result->character & H_CPU_CHAR_BCCTR_FLUSH_ASSIST)
+               security_ftr_set(SEC_FTR_BCCTR_FLUSH_ASSIST);
+
+       if (result->behaviour & H_CPU_BEHAV_FLUSH_COUNT_CACHE)
+               security_ftr_set(SEC_FTR_FLUSH_COUNT_CACHE);
+
+       /*
+        * The features below are enabled by default, so we instead look to see
+        * if firmware has *disabled* them, and clear them if so.
+        */
+       if (!(result->behaviour & H_CPU_BEHAV_FAVOUR_SECURITY))
+               security_ftr_clear(SEC_FTR_FAVOUR_SECURITY);
+
+       if (!(result->behaviour & H_CPU_BEHAV_L1D_FLUSH_PR))
+               security_ftr_clear(SEC_FTR_L1D_FLUSH_PR);
+
+       if (!(result->behaviour & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR))
+               security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR);
+}
+
+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;
+       /*
+        * Set features to the defaults assumed by init_cpu_char_feature_flags()
+        * so it can set/clear again any features that might have changed after
+        * migration, and in case the hypercall fails and it is not even called.
+        */
+       powerpc_security_features = SEC_FTR_DEFAULT;
 
        rc = plpar_get_cpu_characteristics(&result);
- -     if (rc == H_SUCCESS) {
- -             types = L1D_FLUSH_NONE;
+       if (rc == H_SUCCESS)
+               init_cpu_char_feature_flags(&result);
 
- -             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;
+       /*
+        * We're the guest so this doesn't apply to us, clear it to simplify
+        * handling of it elsewhere.
+        */
+       security_ftr_clear(SEC_FTR_L1D_FLUSH_HV);
 
- -             /* Use fallback if nothing set in hcall */
- -             if (types == L1D_FLUSH_NONE)
- -                     types = L1D_FLUSH_FALLBACK;
+       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;
- -     }
+       if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_TRIG2))
+               types |= L1D_FLUSH_MTTRIG;
+
+       if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_ORI30))
+               types |= L1D_FLUSH_ORI;
+
+       enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && \
+                security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR);
 
        setup_rfi_flush(types, enable);
+       setup_count_cache_flush();
 }
 
 static void __init pSeries_setup_arch(void)
@@ -549,6 +600,7 @@ static void __init pSeries_setup_arch(void)
        fwnmi_init();
 
        pseries_setup_rfi_flush();
+       setup_stf_barrier();
 
        /* By default, only probe PCI (can be overridden by rtas_pci) */
        pci_add_flags(PCI_PROBE_ONLY);
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 786bf01691c9..83619ebede93 100644
- --- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2144,6 +2144,8 @@ static void dump_one_paca(int cpu)
        DUMP(p, slb_cache_ptr, "x");
        for (i = 0; i < SLB_CACHE_ENTRIES; i++)
                printf(" slb_cache[%d]:        = 0x%016lx\n", i, 
p->slb_cache[i]);
+
+       DUMP(p, rfi_flush_fallback_area, "px");
 #endif
        DUMP(p, dscr_default, "llx");
 #ifdef CONFIG_PPC_BOOK3E
- -- 
2.20.1

-----BEGIN PGP SIGNATURE-----

iQIcBAEBAgAGBQJcvHWhAAoJEFHr6jzI4aWA6nsP/0YskmAfLovcUmERQ7+bIjq6
IcS1T466dvy6MlqeBXU4x8pVgInWeHKEC9XJdkM1lOeib/SLW7Hbz4kgJeOGwFGY
lOTaexrxvsBqPm7f6GC0zbl9obEIIIIUs+TielFQANBgqm+q8Wio+XXPP9bpKeKY
agSpQ3nwL/PYixznbNmN/lP9py5p89LQ0IBcR7dDBGGWJtD/AXeZ9hslsZxPbPtI
nZJ0vdnjuoB2z+hCxfKWlYfLwH0VfoTpqP5x3ALCkvbBr67e8bf6EK8+trnvhyQ8
iLY4bp1pm2epAI0/3NfyEiDMsGjVJ6IFlkyhDkHJgJNu0BGcGOSX2GpyU3juviAK
c95FtBft/i8AwigOMCivg2mN5edYjsSiPoEItwT5KWqgByJsdr5i5mYVx8cUjMOz
iAxLZCdg+UHZYuCBCAO2ZI1G9bVXI1Pa3btMspiCOOOsYGjXGf0oFfKQ+7957hUO
ftYYJoGHlMHiHR1OPas6T3lk6YKF9uvfIDTE3OKw2obHbbRz3u82xoWMRGW503MN
7WpkpAP7oZ9RgqIWFVhatWy5f+7GFL0akEi4o2tsZHhYlPau7YWo+nToTd87itwt
GBaWJipzge4s13VkhAE+jWFO35Fvwi8uNZ7UgpuKMBECEjkGbtzBTq2MjSF5G8wc
yPEod5jby/Iqb7DkGPVG
=6DnF
-----END PGP SIGNATURE-----

Reply via email to