]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 23 May 2018 17:23:11 +0000 (19:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 23 May 2018 17:23:11 +0000 (19:23 +0200)
added patches:
ext2-fix-a-block-leak.patch
powerpc-64s-add-support-for-a-store-forwarding-barrier-at-kernel-entry-exit.patch
powerpc-64s-enhance-the-information-in-cpu_show_meltdown.patch
powerpc-64s-move-cpu_show_meltdown.patch
powerpc-64s-wire-up-cpu_show_spectre_v1.patch
powerpc-64s-wire-up-cpu_show_spectre_v2.patch
powerpc-add-security-feature-flags-for-spectre-meltdown.patch
powerpc-move-default-security-feature-flags.patch
powerpc-powernv-set-or-clear-security-feature-flags.patch
powerpc-powernv-use-the-security-flags-in-pnv_setup_rfi_flush.patch
powerpc-pseries-add-new-h_get_cpu_characteristics-flags.patch
powerpc-pseries-fix-clearing-of-security-feature-flags.patch
powerpc-pseries-set-or-clear-security-feature-flags.patch
powerpc-pseries-use-the-security-flags-in-pseries_setup_rfi_flush.patch
powerpc-rfi-flush-always-enable-fallback-flush-on-pseries.patch
s390-add-assembler-macros-for-cpu-alternatives.patch
s390-add-automatic-detection-of-the-spectre-defense.patch
s390-add-sysfs-attributes-for-spectre.patch
s390-correct-module-section-names-for-expoline-code-revert.patch
s390-correct-nospec-auto-detection-init-order.patch
s390-crc32-vx-use-expoline-for-indirect-branches.patch
s390-extend-expoline-to-bc-instructions.patch
s390-ftrace-use-expoline-for-indirect-branches.patch
s390-kernel-use-expoline-for-indirect-branches.patch
s390-lib-use-expoline-for-indirect-branches.patch
s390-move-expoline-assembler-macros-to-a-header.patch
s390-move-nobp-parameter-functions-to-nospec-branch.c.patch
s390-move-spectre-sysfs-attribute-code.patch
s390-report-spectre-mitigation-via-syslog.patch
s390-use-expoline-thunks-in-the-bpf-jit.patch

31 files changed:
queue-4.16/ext2-fix-a-block-leak.patch [new file with mode: 0644]
queue-4.16/powerpc-64s-add-support-for-a-store-forwarding-barrier-at-kernel-entry-exit.patch [new file with mode: 0644]
queue-4.16/powerpc-64s-enhance-the-information-in-cpu_show_meltdown.patch [new file with mode: 0644]
queue-4.16/powerpc-64s-move-cpu_show_meltdown.patch [new file with mode: 0644]
queue-4.16/powerpc-64s-wire-up-cpu_show_spectre_v1.patch [new file with mode: 0644]
queue-4.16/powerpc-64s-wire-up-cpu_show_spectre_v2.patch [new file with mode: 0644]
queue-4.16/powerpc-add-security-feature-flags-for-spectre-meltdown.patch [new file with mode: 0644]
queue-4.16/powerpc-move-default-security-feature-flags.patch [new file with mode: 0644]
queue-4.16/powerpc-powernv-set-or-clear-security-feature-flags.patch [new file with mode: 0644]
queue-4.16/powerpc-powernv-use-the-security-flags-in-pnv_setup_rfi_flush.patch [new file with mode: 0644]
queue-4.16/powerpc-pseries-add-new-h_get_cpu_characteristics-flags.patch [new file with mode: 0644]
queue-4.16/powerpc-pseries-fix-clearing-of-security-feature-flags.patch [new file with mode: 0644]
queue-4.16/powerpc-pseries-set-or-clear-security-feature-flags.patch [new file with mode: 0644]
queue-4.16/powerpc-pseries-use-the-security-flags-in-pseries_setup_rfi_flush.patch [new file with mode: 0644]
queue-4.16/powerpc-rfi-flush-always-enable-fallback-flush-on-pseries.patch [new file with mode: 0644]
queue-4.16/s390-add-assembler-macros-for-cpu-alternatives.patch [new file with mode: 0644]
queue-4.16/s390-add-automatic-detection-of-the-spectre-defense.patch [new file with mode: 0644]
queue-4.16/s390-add-sysfs-attributes-for-spectre.patch [new file with mode: 0644]
queue-4.16/s390-correct-module-section-names-for-expoline-code-revert.patch [new file with mode: 0644]
queue-4.16/s390-correct-nospec-auto-detection-init-order.patch [new file with mode: 0644]
queue-4.16/s390-crc32-vx-use-expoline-for-indirect-branches.patch [new file with mode: 0644]
queue-4.16/s390-extend-expoline-to-bc-instructions.patch [new file with mode: 0644]
queue-4.16/s390-ftrace-use-expoline-for-indirect-branches.patch [new file with mode: 0644]
queue-4.16/s390-kernel-use-expoline-for-indirect-branches.patch [new file with mode: 0644]
queue-4.16/s390-lib-use-expoline-for-indirect-branches.patch [new file with mode: 0644]
queue-4.16/s390-move-expoline-assembler-macros-to-a-header.patch [new file with mode: 0644]
queue-4.16/s390-move-nobp-parameter-functions-to-nospec-branch.c.patch [new file with mode: 0644]
queue-4.16/s390-move-spectre-sysfs-attribute-code.patch [new file with mode: 0644]
queue-4.16/s390-report-spectre-mitigation-via-syslog.patch [new file with mode: 0644]
queue-4.16/s390-use-expoline-thunks-in-the-bpf-jit.patch [new file with mode: 0644]
queue-4.16/series

diff --git a/queue-4.16/ext2-fix-a-block-leak.patch b/queue-4.16/ext2-fix-a-block-leak.patch
new file mode 100644 (file)
index 0000000..bd5bddc
--- /dev/null
@@ -0,0 +1,49 @@
+From 5aa1437d2d9a068c0334bd7c9dafa8ec4f97f13b Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Thu, 17 May 2018 17:18:30 -0400
+Subject: ext2: fix a block leak
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 5aa1437d2d9a068c0334bd7c9dafa8ec4f97f13b upstream.
+
+open file, unlink it, then use ioctl(2) to make it immutable or
+append only.  Now close it and watch the blocks *not* freed...
+
+Immutable/append-only checks belong in ->setattr().
+Note: the bug is old and backport to anything prior to 737f2e93b972
+("ext2: convert to use the new truncate convention") will need
+these checks lifted into ext2_setattr().
+
+Cc: stable@kernel.org
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext2/inode.c |   10 ----------
+ 1 file changed, 10 deletions(-)
+
+--- a/fs/ext2/inode.c
++++ b/fs/ext2/inode.c
+@@ -1261,21 +1261,11 @@ do_indirects:
+ static void ext2_truncate_blocks(struct inode *inode, loff_t offset)
+ {
+-      /*
+-       * XXX: it seems like a bug here that we don't allow
+-       * IS_APPEND inode to have blocks-past-i_size trimmed off.
+-       * review and fix this.
+-       *
+-       * Also would be nice to be able to handle IO errors and such,
+-       * but that's probably too much to ask.
+-       */
+       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+           S_ISLNK(inode->i_mode)))
+               return;
+       if (ext2_inode_is_fast_symlink(inode))
+               return;
+-      if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+-              return;
+       dax_sem_down_write(EXT2_I(inode));
+       __ext2_truncate_blocks(inode, offset);
diff --git a/queue-4.16/powerpc-64s-add-support-for-a-store-forwarding-barrier-at-kernel-entry-exit.patch b/queue-4.16/powerpc-64s-add-support-for-a-store-forwarding-barrier-at-kernel-entry-exit.patch
new file mode 100644 (file)
index 0000000..0bef878
--- /dev/null
@@ -0,0 +1,575 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:25 +1000
+Subject: powerpc/64s: Add support for a store forwarding barrier at kernel entry/exit
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-15-mpe@ellerman.id.au>
+
+From: Nicholas Piggin <npiggin@gmail.com>
+
+commit a048a07d7f4535baa4cbad6bc024f175317ab938 upstream.
+
+On some CPUs we can prevent a vulnerability related to store-to-load
+forwarding by preventing store forwarding between privilege domains,
+by inserting a barrier in kernel entry and exit paths.
+
+This is known to be the case on at least Power7, Power8 and Power9
+powerpc CPUs.
+
+Barriers must be inserted generally before the first load after moving
+to a higher privilege, and after the last store before moving to a
+lower privilege, HV and PR privilege transitions must be protected.
+
+Barriers are added as patch sections, with all kernel/hypervisor entry
+points patched, and the exit points to lower privilge levels patched
+similarly to the RFI flush patching.
+
+Firmware advertisement is not implemented yet, so CPU flush types
+are hard coded.
+
+Thanks to Michal Suchánek for bug fixes and review.
+
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Signed-off-by: Michael Neuling <mikey@neuling.org>
+Signed-off-by: Michal Suchánek <msuchanek@suse.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/exception-64s.h     |   29 +++++
+ arch/powerpc/include/asm/feature-fixups.h    |   19 +++
+ arch/powerpc/include/asm/security_features.h |   11 +
+ arch/powerpc/kernel/exceptions-64s.S         |   19 +++
+ arch/powerpc/kernel/security.c               |  149 +++++++++++++++++++++++++++
+ arch/powerpc/kernel/vmlinux.lds.S            |   14 ++
+ arch/powerpc/lib/feature-fixups.c            |  115 ++++++++++++++++++++
+ arch/powerpc/platforms/powernv/setup.c       |    1 
+ arch/powerpc/platforms/pseries/setup.c       |    1 
+ 9 files changed, 356 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/include/asm/exception-64s.h
++++ b/arch/powerpc/include/asm/exception-64s.h
+@@ -74,6 +74,27 @@
+  */
+ #define EX_R3         EX_DAR
++#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
+  *
+@@ -90,16 +111,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
+@@ -108,21 +132,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
+@@ -254,6 +282,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
+ #define __EXCEPTION_PROLOG_1_PRE(area)                                        \
+       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;
+--- a/arch/powerpc/include/asm/feature-fixups.h
++++ b/arch/powerpc/include/asm/feature-fixups.h
+@@ -187,6 +187,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";             \
+@@ -199,6 +215,9 @@ label##3:                                          \
+ #ifndef __ASSEMBLY__
+ #include <linux/types.h>
++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;
+ void apply_feature_fixups(void);
+--- a/arch/powerpc/include/asm/security_features.h
++++ b/arch/powerpc/include/asm/security_features.h
+@@ -12,6 +12,17 @@
+ 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);
++
+ static inline void security_ftr_set(unsigned long feature)
+ {
+       powerpc_security_features |= feature;
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -833,7 +833,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
+ #endif
+-EXC_REAL_MASKABLE(decrementer, 0x900, 0x80, IRQS_DISABLED)
++EXC_REAL_OOL_MASKABLE(decrementer, 0x900, 0x80, IRQS_DISABLED)
+ EXC_VIRT_MASKABLE(decrementer, 0x4900, 0x80, 0x900, IRQS_DISABLED)
+ TRAMP_KVM(PACA_EXGEN, 0x900)
+ EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt)
+@@ -909,6 +909,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknow
+       mtctr   r13;                                                    \
+       GET_PACA(r13);                                                  \
+       std     r10,PACA_EXGEN+EX_R10(r13);                             \
++      INTERRUPT_TO_KERNEL;                                            \
+       KVMTEST_PR(0xc00); /* uses r10, branch to do_kvm_0xc00_system_call */ \
+       HMT_MEDIUM;                                                     \
+       mfctr   r9;
+@@ -917,7 +918,8 @@ EXC_COMMON(trap_0b_common, 0xb00, unknow
+ #define SYSCALL_KVMTEST                                                       \
+       HMT_MEDIUM;                                                     \
+       mr      r9,r13;                                                 \
+-      GET_PACA(r13);
++      GET_PACA(r13);                                                  \
++      INTERRUPT_TO_KERNEL;
+ #endif
+       
+ #define LOAD_SYSCALL_HANDLER(reg)                                     \
+@@ -1455,6 +1457,19 @@ masked_##_H##interrupt:                                 \
+       b       .;                                      \
+       MASKED_DEC_HANDLER(_H)
++TRAMP_REAL_BEGIN(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
++
+ TRAMP_REAL_BEGIN(rfi_flush_fallback)
+       SET_SCRATCH0(r13);
+       GET_PACA(r13);
+--- a/arch/powerpc/kernel/security.c
++++ b/arch/powerpc/kernel/security.c
+@@ -8,6 +8,7 @@
+ #include <linux/device.h>
+ #include <linux/seq_buf.h>
++#include <asm/debugfs.h>
+ #include <asm/security_features.h>
+@@ -86,3 +87,151 @@ ssize_t cpu_show_spectre_v2(struct devic
+       return s.len;
+ }
++
++/*
++ * 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_300))
++              type = STF_BARRIER_EIEIO;
++      else 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 */
+--- a/arch/powerpc/kernel/vmlinux.lds.S
++++ b/arch/powerpc/kernel/vmlinux.lds.S
+@@ -134,6 +134,20 @@ SECTIONS
+ #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)
+--- a/arch/powerpc/lib/feature-fixups.c
++++ b/arch/powerpc/lib/feature-fixups.c
+@@ -23,6 +23,7 @@
+ #include <asm/page.h>
+ #include <asm/sections.h>
+ #include <asm/setup.h>
++#include <asm/security_features.h>
+ #include <asm/firmware.h>
+ struct fixup_entry {
+@@ -117,6 +118,120 @@ void do_feature_fixups(unsigned long val
+ }
+ #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;
+--- a/arch/powerpc/platforms/powernv/setup.c
++++ b/arch/powerpc/platforms/powernv/setup.c
+@@ -131,6 +131,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();
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -699,6 +699,7 @@ static void __init pSeries_setup_arch(vo
+       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/queue-4.16/powerpc-64s-enhance-the-information-in-cpu_show_meltdown.patch b/queue-4.16/powerpc-64s-enhance-the-information-in-cpu_show_meltdown.patch
new file mode 100644 (file)
index 0000000..adffb54
--- /dev/null
@@ -0,0 +1,78 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:18 +1000
+Subject: powerpc/64s: Enhance the information in cpu_show_meltdown()
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-8-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit ff348355e9c72493947be337bb4fae4fc1a41eba upstream.
+
+Now that we have the security feature flags we can make the
+information displayed in the "meltdown" file more informative.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/security_features.h |    1 
+ arch/powerpc/kernel/security.c               |   30 +++++++++++++++++++++++++--
+ 2 files changed, 29 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/include/asm/security_features.h
++++ b/arch/powerpc/include/asm/security_features.h
+@@ -10,6 +10,7 @@
+ extern unsigned long powerpc_security_features;
++extern bool rfi_flush;
+ static inline void security_ftr_set(unsigned long feature)
+ {
+--- a/arch/powerpc/kernel/security.c
++++ b/arch/powerpc/kernel/security.c
+@@ -6,6 +6,7 @@
+ #include <linux/kernel.h>
+ #include <linux/device.h>
++#include <linux/seq_buf.h>
+ #include <asm/security_features.h>
+@@ -19,8 +20,33 @@ unsigned long powerpc_security_features
+ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
+ {
+-      if (rfi_flush)
+-              return sprintf(buf, "Mitigation: RFI Flush\n");
++      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");
+ }
diff --git a/queue-4.16/powerpc-64s-move-cpu_show_meltdown.patch b/queue-4.16/powerpc-64s-move-cpu_show_meltdown.patch
new file mode 100644 (file)
index 0000000..5c22a89
--- /dev/null
@@ -0,0 +1,62 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:17 +1000
+Subject: powerpc/64s: Move cpu_show_meltdown()
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-7-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 8ad33041563a10b34988800c682ada14b2612533 upstream.
+
+This landed in setup_64.c for no good reason other than we had nowhere
+else to put it. Now that we have a security-related file, that is a
+better place for it so move it.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/kernel/security.c |   11 +++++++++++
+ arch/powerpc/kernel/setup_64.c |    8 --------
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+--- a/arch/powerpc/kernel/security.c
++++ b/arch/powerpc/kernel/security.c
+@@ -5,6 +5,8 @@
+ // Copyright 2018, Michael Ellerman, IBM Corporation.
+ #include <linux/kernel.h>
++#include <linux/device.h>
++
+ #include <asm/security_features.h>
+@@ -13,3 +15,12 @@ unsigned long powerpc_security_features
+       SEC_FTR_L1D_FLUSH_PR | \
+       SEC_FTR_BNDS_CHK_SPEC_BAR | \
+       SEC_FTR_FAVOUR_SECURITY;
++
++
++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");
++}
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -927,12 +927,4 @@ static __init int rfi_flush_debugfs_init
+ }
+ 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/queue-4.16/powerpc-64s-wire-up-cpu_show_spectre_v1.patch b/queue-4.16/powerpc-64s-wire-up-cpu_show_spectre_v1.patch
new file mode 100644 (file)
index 0000000..b6d120d
--- /dev/null
@@ -0,0 +1,40 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:21 +1000
+Subject: powerpc/64s: Wire up cpu_show_spectre_v1()
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-11-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 56986016cb8cd9050e601831fe89f332b4e3c46e upstream.
+
+Add a definition for cpu_show_spectre_v1() to override the generic
+version. Currently this just prints "Not affected" or "Vulnerable"
+based on the firmware flag.
+
+Although the kernel does have array_index_nospec() in a few places, we
+haven't yet audited all the powerpc code to see where it's necessary,
+so for now we don't list that as a mitigation.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/kernel/security.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/powerpc/kernel/security.c
++++ b/arch/powerpc/kernel/security.c
+@@ -50,3 +50,11 @@ ssize_t cpu_show_meltdown(struct device
+       return sprintf(buf, "Vulnerable\n");
+ }
++
++ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      if (!security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR))
++              return sprintf(buf, "Not affected\n");
++
++      return sprintf(buf, "Vulnerable\n");
++}
diff --git a/queue-4.16/powerpc-64s-wire-up-cpu_show_spectre_v2.patch b/queue-4.16/powerpc-64s-wire-up-cpu_show_spectre_v2.patch
new file mode 100644 (file)
index 0000000..63003d0
--- /dev/null
@@ -0,0 +1,73 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:22 +1000
+Subject: powerpc/64s: Wire up cpu_show_spectre_v2()
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-12-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit d6fbe1c55c55c6937cbea3531af7da84ab7473c3 upstream.
+
+Add a definition for cpu_show_spectre_v2() to override the generic
+version. This has several permuations, though in practice some may not
+occur we cater for any combination.
+
+The most verbose is:
+
+  Mitigation: Indirect branch serialisation (kernel only), Indirect
+  branch cache disabled, ori31 speculation barrier enabled
+
+We don't treat the ori31 speculation barrier as a mitigation on its
+own, because it has to be *used* by code in order to be a mitigation
+and we don't know if userspace is doing that. So if that's all we see
+we say:
+
+  Vulnerable, ori31 speculation barrier enabled
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/kernel/security.c |   33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+--- a/arch/powerpc/kernel/security.c
++++ b/arch/powerpc/kernel/security.c
+@@ -58,3 +58,36 @@ ssize_t cpu_show_spectre_v1(struct devic
+       return sprintf(buf, "Vulnerable\n");
+ }
++
++ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      bool bcs, ccd, ori;
++      struct seq_buf s;
++
++      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);
++      ori = security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31);
++
++      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
++              seq_buf_printf(&s, "Vulnerable");
++
++      if (ori)
++              seq_buf_printf(&s, ", ori31 speculation barrier enabled");
++
++      seq_buf_printf(&s, "\n");
++
++      return s.len;
++}
diff --git a/queue-4.16/powerpc-add-security-feature-flags-for-spectre-meltdown.patch b/queue-4.16/powerpc-add-security-feature-flags-for-spectre-meltdown.patch
new file mode 100644 (file)
index 0000000..7f7c3cd
--- /dev/null
@@ -0,0 +1,132 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:13 +1000
+Subject: powerpc: Add security feature flags for Spectre/Meltdown
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-3-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 9a868f634349e62922c226834aa23e3d1329ae7f upstream.
+
+This commit adds security feature flags to reflect the settings we
+receive from firmware regarding Spectre/Meltdown mitigations.
+
+The feature names reflect the names we are given by firmware on bare
+metal machines. See the hostboot source for details.
+
+Arguably these could be firmware features, but that then requires them
+to be read early in boot so they're available prior to asm feature
+patching, but we don't actually want to use them for patching. We may
+also want to dynamically update them in future, which would be
+incompatible with the way firmware features work (at the moment at
+least). So for now just make them separate flags.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/security_features.h |   65 +++++++++++++++++++++++++++
+ arch/powerpc/kernel/Makefile                 |    2 
+ arch/powerpc/kernel/security.c               |   15 ++++++
+ 3 files changed, 81 insertions(+), 1 deletion(-)
+ create mode 100644 arch/powerpc/include/asm/security_features.h
+ create mode 100644 arch/powerpc/kernel/security.c
+
+--- /dev/null
++++ b/arch/powerpc/include/asm/security_features.h
+@@ -0,0 +1,65 @@
++/* 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;
++
++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
++
++
++// 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
++
++#endif /* _ASM_POWERPC_SECURITY_FEATURES_H */
+--- a/arch/powerpc/kernel/Makefile
++++ b/arch/powerpc/kernel/Makefile
+@@ -42,7 +42,7 @@ obj-$(CONFIG_VDSO32)         += vdso32/
+ obj-$(CONFIG_PPC_WATCHDOG)    += watchdog.o
+ obj-$(CONFIG_HAVE_HW_BREAKPOINT)      += hw_breakpoint.o
+ obj-$(CONFIG_PPC_BOOK3S_64)   += cpu_setup_ppc970.o cpu_setup_pa6t.o
+-obj-$(CONFIG_PPC_BOOK3S_64)   += cpu_setup_power.o
++obj-$(CONFIG_PPC_BOOK3S_64)   += cpu_setup_power.o security.o
+ obj-$(CONFIG_PPC_BOOK3S_64)   += mce.o mce_power.o
+ obj-$(CONFIG_PPC_BOOK3E_64)   += exceptions-64e.o idle_book3e.o
+ obj-$(CONFIG_PPC64)           += vdso64/
+--- /dev/null
++++ b/arch/powerpc/kernel/security.c
+@@ -0,0 +1,15 @@
++// SPDX-License-Identifier: GPL-2.0+
++//
++// Security related flags and so on.
++//
++// Copyright 2018, Michael Ellerman, IBM Corporation.
++
++#include <linux/kernel.h>
++#include <asm/security_features.h>
++
++
++unsigned long powerpc_security_features __read_mostly = \
++      SEC_FTR_L1D_FLUSH_HV | \
++      SEC_FTR_L1D_FLUSH_PR | \
++      SEC_FTR_BNDS_CHK_SPEC_BAR | \
++      SEC_FTR_FAVOUR_SECURITY;
diff --git a/queue-4.16/powerpc-move-default-security-feature-flags.patch b/queue-4.16/powerpc-move-default-security-feature-flags.patch
new file mode 100644 (file)
index 0000000..bf4e39f
--- /dev/null
@@ -0,0 +1,56 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:24 +1000
+Subject: powerpc: Move default security feature flags
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-14-mpe@ellerman.id.au>
+
+From: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+
+commit e7347a86830f38dc3e40c8f7e28c04412b12a2e7 upstream.
+
+This moves the definition of the default security feature flags
+(i.e., enabled by default) closer to the security feature flags.
+
+This can be used to restore current flags to the default flags.
+
+Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/security_features.h |    8 ++++++++
+ arch/powerpc/kernel/security.c               |    7 +------
+ 2 files changed, 9 insertions(+), 6 deletions(-)
+
+--- a/arch/powerpc/include/asm/security_features.h
++++ b/arch/powerpc/include/asm/security_features.h
+@@ -63,4 +63,12 @@ static inline bool security_ftr_enabled(
+ // Firmware configuration indicates user favours security over performance
+ #define SEC_FTR_FAVOUR_SECURITY               0x0000000000000200ull
++
++// 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 */
+--- a/arch/powerpc/kernel/security.c
++++ b/arch/powerpc/kernel/security.c
+@@ -11,12 +11,7 @@
+ #include <asm/security_features.h>
+-unsigned long powerpc_security_features __read_mostly = \
+-      SEC_FTR_L1D_FLUSH_HV | \
+-      SEC_FTR_L1D_FLUSH_PR | \
+-      SEC_FTR_BNDS_CHK_SPEC_BAR | \
+-      SEC_FTR_FAVOUR_SECURITY;
+-
++unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
+ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
+ {
diff --git a/queue-4.16/powerpc-powernv-set-or-clear-security-feature-flags.patch b/queue-4.16/powerpc-powernv-set-or-clear-security-feature-flags.patch
new file mode 100644 (file)
index 0000000..bcea98f
--- /dev/null
@@ -0,0 +1,97 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:16 +1000
+Subject: powerpc/powernv: Set or clear security feature flags
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-6-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 77addf6e95c8689e478d607176b399a6242a777e upstream.
+
+Now that we have feature flags for security related things, set or
+clear them based on what we see in the device tree provided by
+firmware.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/platforms/powernv/setup.c |   56 +++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/arch/powerpc/platforms/powernv/setup.c
++++ b/arch/powerpc/platforms/powernv/setup.c
+@@ -38,9 +38,63 @@
+ #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-spec-barrier-ori31,31,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);
++
++      /*
++       * 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;
+@@ -56,6 +110,8 @@ static void pnv_setup_rfi_flush(void)
+       of_node_put(np);
+       if (fw_features) {
++              init_fw_feat_flags(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;
diff --git a/queue-4.16/powerpc-powernv-use-the-security-flags-in-pnv_setup_rfi_flush.patch b/queue-4.16/powerpc-powernv-use-the-security-flags-in-pnv_setup_rfi_flush.patch
new file mode 100644 (file)
index 0000000..22d9a20
--- /dev/null
@@ -0,0 +1,96 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:19 +1000
+Subject: powerpc/powernv: Use the security flags in pnv_setup_rfi_flush()
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-9-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 37c0bdd00d3ae83369ab60a6712c28e11e6458d5 upstream.
+
+Now that we have the security flags we can significantly simplify the
+code in pnv_setup_rfi_flush(), because we can use the flags instead of
+checking device tree properties and because the security flags have
+pessimistic defaults.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/platforms/powernv/setup.c |   41 ++++++++-------------------------
+ 1 file changed, 10 insertions(+), 31 deletions(-)
+
+--- a/arch/powerpc/platforms/powernv/setup.c
++++ b/arch/powerpc/platforms/powernv/setup.c
+@@ -66,7 +66,7 @@ static void init_fw_feat_flags(struct de
+       if (fw_feature_is("enabled", "fw-bcctrl-serialized", np))
+               security_ftr_set(SEC_FTR_BCCTRL_SERIALISED);
+-      if (fw_feature_is("enabled", "inst-spec-barrier-ori31,31,0", np))
++      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))
+@@ -99,11 +99,10 @@ 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");
+@@ -111,40 +110,20 @@ static void pnv_setup_rfi_flush(void)
+       if (fw_features) {
+               init_fw_feat_flags(fw_features);
++              of_node_put(fw_features);
+-              np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2");
+-              if (np && of_property_read_bool(np, "enabled"))
++              if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_TRIG2))
+                       type = L1D_FLUSH_MTTRIG;
+-              of_node_put(np);
+-
+-              np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0");
+-              if (np && of_property_read_bool(np, "enabled"))
++              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--;
+-
+-              np = of_get_child_by_name(fw_features, "speculation-policy-favor-security");
+-              if (np && of_property_read_bool(np, "disabled"))
+-                      enable = 0;
+-
+-              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);
+ }
+ static void __init pnv_setup_arch(void)
diff --git a/queue-4.16/powerpc-pseries-add-new-h_get_cpu_characteristics-flags.patch b/queue-4.16/powerpc-pseries-add-new-h_get_cpu_characteristics-flags.patch
new file mode 100644 (file)
index 0000000..8e88367
--- /dev/null
@@ -0,0 +1,33 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:14 +1000
+Subject: powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-4-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit c4bc36628d7f8b664657d8bd6ad1c44c177880b7 upstream.
+
+Add some additional values which have been defined for the
+H_GET_CPU_CHARACTERISTICS hypercall.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/include/asm/hvcall.h |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/powerpc/include/asm/hvcall.h
++++ b/arch/powerpc/include/asm/hvcall.h
+@@ -337,6 +337,9 @@
+ #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_BEHAV_FAVOUR_SECURITY   (1ull << 63) // IBM bit 0
+ #define H_CPU_BEHAV_L1D_FLUSH_PR      (1ull << 62) // IBM bit 1
diff --git a/queue-4.16/powerpc-pseries-fix-clearing-of-security-feature-flags.patch b/queue-4.16/powerpc-pseries-fix-clearing-of-security-feature-flags.patch
new file mode 100644 (file)
index 0000000..2b58314
--- /dev/null
@@ -0,0 +1,81 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:23 +1000
+Subject: powerpc/pseries: Fix clearing of security feature flags
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-13-mpe@ellerman.id.au>
+
+From: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+
+commit 0f9bdfe3c77091e8704d2e510eb7c2c2c6cde524 upstream.
+
+The H_CPU_BEHAV_* flags should be checked for in the 'behaviour' field
+of 'struct h_cpu_char_result' -- 'character' is for H_CPU_CHAR_*
+flags.
+
+Found by playing around with QEMU's implementation of the hypercall:
+
+  H_CPU_CHAR=0xf000000000000000
+  H_CPU_BEHAV=0x0000000000000000
+
+  This clears H_CPU_BEHAV_FAVOUR_SECURITY and H_CPU_BEHAV_L1D_FLUSH_PR
+  so pseries_setup_rfi_flush() disables 'rfi_flush'; and it also
+  clears H_CPU_CHAR_L1D_THREAD_PRIV flag. So there is no RFI flush
+  mitigation at all for cpu_show_meltdown() to report; but currently
+  it does:
+
+  Original kernel:
+
+    # cat /sys/devices/system/cpu/vulnerabilities/meltdown
+    Mitigation: RFI Flush
+
+  Patched kernel:
+
+    # cat /sys/devices/system/cpu/vulnerabilities/meltdown
+    Not affected
+
+  H_CPU_CHAR=0x0000000000000000
+  H_CPU_BEHAV=0xf000000000000000
+
+  This sets H_CPU_BEHAV_BNDS_CHK_SPEC_BAR so cpu_show_spectre_v1() should
+  report vulnerable; but currently it doesn't:
+
+  Original kernel:
+
+    # cat /sys/devices/system/cpu/vulnerabilities/spectre_v1
+    Not affected
+
+  Patched kernel:
+
+    # cat /sys/devices/system/cpu/vulnerabilities/spectre_v1
+    Vulnerable
+
+Brown-paper-bag-by: Michael Ellerman <mpe@ellerman.id.au>
+Fixes: f636c14790ea ("powerpc/pseries: Set or clear security feature flags")
+Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/platforms/pseries/setup.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -484,13 +484,13 @@ static void init_cpu_char_feature_flags(
+        * 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->character & H_CPU_BEHAV_FAVOUR_SECURITY))
++      if (!(result->behaviour & H_CPU_BEHAV_FAVOUR_SECURITY))
+               security_ftr_clear(SEC_FTR_FAVOUR_SECURITY);
+-      if (!(result->character & H_CPU_BEHAV_L1D_FLUSH_PR))
++      if (!(result->behaviour & H_CPU_BEHAV_L1D_FLUSH_PR))
+               security_ftr_clear(SEC_FTR_L1D_FLUSH_PR);
+-      if (!(result->character & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR))
++      if (!(result->behaviour & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR))
+               security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR);
+ }
diff --git a/queue-4.16/powerpc-pseries-set-or-clear-security-feature-flags.patch b/queue-4.16/powerpc-pseries-set-or-clear-security-feature-flags.patch
new file mode 100644 (file)
index 0000000..2009c71
--- /dev/null
@@ -0,0 +1,94 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:15 +1000
+Subject: powerpc/pseries: Set or clear security feature flags
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-5-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit f636c14790ead6cc22cf62279b1f8d7e11a67116 upstream.
+
+Now that we have feature flags for security related things, set or
+clear them based on what we receive from the hypercall.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/platforms/pseries/setup.c |   43 +++++++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -68,6 +68,7 @@
+ #include <asm/plpar_wrappers.h>
+ #include <asm/kexec.h>
+ #include <asm/isa-bridge.h>
++#include <asm/security_features.h>
+ #include "pseries.h"
+@@ -459,6 +460,40 @@ static void __init find_and_init_phbs(vo
+       of_pci_check_probe_only();
+ }
++static void init_cpu_char_feature_flags(struct h_cpu_char_result *result)
++{
++      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);
++
++      /*
++       * 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->character & H_CPU_BEHAV_FAVOUR_SECURITY))
++              security_ftr_clear(SEC_FTR_FAVOUR_SECURITY);
++
++      if (!(result->character & H_CPU_BEHAV_L1D_FLUSH_PR))
++              security_ftr_clear(SEC_FTR_L1D_FLUSH_PR);
++
++      if (!(result->character & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR))
++              security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR);
++}
++
+ static void pseries_setup_rfi_flush(void)
+ {
+       struct h_cpu_char_result result;
+@@ -472,6 +507,8 @@ static void pseries_setup_rfi_flush(void
+       rc = plpar_get_cpu_characteristics(&result);
+       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)
+@@ -482,6 +519,12 @@ static void pseries_setup_rfi_flush(void
+                       enable = false;
+       }
++      /*
++       * 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);
++
+       setup_rfi_flush(types, enable);
+ }
diff --git a/queue-4.16/powerpc-pseries-use-the-security-flags-in-pseries_setup_rfi_flush.patch b/queue-4.16/powerpc-pseries-use-the-security-flags-in-pseries_setup_rfi_flush.patch
new file mode 100644 (file)
index 0000000..8c9c314
--- /dev/null
@@ -0,0 +1,67 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:20 +1000
+Subject: powerpc/pseries: Use the security flags in pseries_setup_rfi_flush()
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-10-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 2e4a16161fcd324b1f9bf6cb6856529f7eaf0689 upstream.
+
+Now that we have the security flags we can simplify the code in
+pseries_setup_rfi_flush() because the security flags have pessimistic
+defaults.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/platforms/pseries/setup.c |   27 ++++++++++++---------------
+ 1 file changed, 12 insertions(+), 15 deletions(-)
+
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -501,30 +501,27 @@ static void pseries_setup_rfi_flush(void
+       bool enable;
+       long rc;
+-      /* Enable by default */
+-      enable = true;
+-      types = L1D_FLUSH_FALLBACK;
+-
+       rc = plpar_get_cpu_characteristics(&result);
+-      if (rc == H_SUCCESS) {
++      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;
+-
+-              if ((!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR)) ||
+-                  (!(result.behaviour & H_CPU_BEHAV_FAVOUR_SECURITY)))
+-                      enable = false;
+-      }
+-
+       /*
+        * 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);
++      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);
+ }
diff --git a/queue-4.16/powerpc-rfi-flush-always-enable-fallback-flush-on-pseries.patch b/queue-4.16/powerpc-rfi-flush-always-enable-fallback-flush-on-pseries.patch
new file mode 100644 (file)
index 0000000..3ce2900
--- /dev/null
@@ -0,0 +1,54 @@
+From foo@baz Wed May 23 19:18:22 CEST 2018
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Wed, 23 May 2018 00:41:12 +1000
+Subject: powerpc/rfi-flush: Always enable fallback flush on pseries
+To: greg@kroah.com
+Cc: stable@vger.kernel.org, tglx@linutronix.de, linuxppc-dev@ozlabs.org
+Message-ID: <20180522144125.10345-2-mpe@ellerman.id.au>
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 84749a58b6e382f109abf1e734bc4dd43c2c25bb upstream.
+
+This ensures the fallback flush area is always allocated on pseries,
+so in case a LPAR is migrated from a patched to an unpatched system,
+it is possible to enable the fallback flush in the target system.
+
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/powerpc/platforms/pseries/setup.c |   10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -468,26 +468,18 @@ static void pseries_setup_rfi_flush(void
+       /* Enable by default */
+       enable = true;
++      types = L1D_FLUSH_FALLBACK;
+       rc = plpar_get_cpu_characteristics(&result);
+       if (rc == H_SUCCESS) {
+-              types = L1D_FLUSH_NONE;
+-
+               if (result.character & H_CPU_CHAR_L1D_FLUSH_TRIG2)
+                       types |= L1D_FLUSH_MTTRIG;
+               if (result.character & H_CPU_CHAR_L1D_FLUSH_ORI30)
+                       types |= L1D_FLUSH_ORI;
+-              /* Use fallback if nothing set in hcall */
+-              if (types == L1D_FLUSH_NONE)
+-                      types = L1D_FLUSH_FALLBACK;
+-
+               if ((!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR)) ||
+                   (!(result.behaviour & H_CPU_BEHAV_FAVOUR_SECURITY)))
+                       enable = false;
+-      } else {
+-              /* Default to fallback if case hcall is not available */
+-              types = L1D_FLUSH_FALLBACK;
+       }
+       setup_rfi_flush(types, enable);
diff --git a/queue-4.16/s390-add-assembler-macros-for-cpu-alternatives.patch b/queue-4.16/s390-add-assembler-macros-for-cpu-alternatives.patch
new file mode 100644 (file)
index 0000000..e40b452
--- /dev/null
@@ -0,0 +1,147 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:21 +0200
+Subject: s390: add assembler macros for CPU alternatives
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-6-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit fba9eb7946251d6e420df3bdf7bc45195be7be9a ]
+
+Add a header with macros usable in assembler files to emit alternative
+code sequences. It works analog to the alternatives for inline assmeblies
+in C files, with the same restrictions and capabilities.
+The syntax is
+
+     ALTERNATIVE "<default instructions sequence>", \
+                "<alternative instructions sequence>", \
+                "<features-bit>"
+and
+
+     ALTERNATIVE_2 "<default instructions sequence>", \
+                  "<alternative instructions sqeuence #1>", \
+                  "<feature-bit #1>",
+                  "<alternative instructions sqeuence #2>", \
+                  "<feature-bit #2>"
+
+Reviewed-by: Vasily Gorbik <gor@linux.vnet.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/include/asm/alternative-asm.h |  108 ++++++++++++++++++++++++++++++++
+ 1 file changed, 108 insertions(+)
+ create mode 100644 arch/s390/include/asm/alternative-asm.h
+
+--- /dev/null
++++ b/arch/s390/include/asm/alternative-asm.h
+@@ -0,0 +1,108 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef _ASM_S390_ALTERNATIVE_ASM_H
++#define _ASM_S390_ALTERNATIVE_ASM_H
++
++#ifdef __ASSEMBLY__
++
++/*
++ * Check the length of an instruction sequence. The length may not be larger
++ * than 254 bytes and it has to be divisible by 2.
++ */
++.macro alt_len_check start,end
++      .if ( \end - \start ) > 254
++      .error "cpu alternatives does not support instructions blocks > 254 bytes\n"
++      .endif
++      .if ( \end - \start ) % 2
++      .error "cpu alternatives instructions length is odd\n"
++      .endif
++.endm
++
++/*
++ * Issue one struct alt_instr descriptor entry (need to put it into
++ * the section .altinstructions, see below). This entry contains
++ * enough information for the alternatives patching code to patch an
++ * instruction. See apply_alternatives().
++ */
++.macro alt_entry orig_start, orig_end, alt_start, alt_end, feature
++      .long   \orig_start - .
++      .long   \alt_start - .
++      .word   \feature
++      .byte   \orig_end - \orig_start
++      .byte   \alt_end - \alt_start
++.endm
++
++/*
++ * Fill up @bytes with nops. The macro emits 6-byte nop instructions
++ * for the bulk of the area, possibly followed by a 4-byte and/or
++ * a 2-byte nop if the size of the area is not divisible by 6.
++ */
++.macro alt_pad_fill bytes
++      .fill   ( \bytes ) / 6, 6, 0xc0040000
++      .fill   ( \bytes ) % 6 / 4, 4, 0x47000000
++      .fill   ( \bytes ) % 6 % 4 / 2, 2, 0x0700
++.endm
++
++/*
++ * Fill up @bytes with nops. If the number of bytes is larger
++ * than 6, emit a jg instruction to branch over all nops, then
++ * fill an area of size (@bytes - 6) with nop instructions.
++ */
++.macro alt_pad bytes
++      .if ( \bytes > 0 )
++      .if ( \bytes > 6 )
++      jg      . + \bytes
++      alt_pad_fill \bytes - 6
++      .else
++      alt_pad_fill \bytes
++      .endif
++      .endif
++.endm
++
++/*
++ * Define an alternative between two instructions. If @feature is
++ * present, early code in apply_alternatives() replaces @oldinstr with
++ * @newinstr. ".skip" directive takes care of proper instruction padding
++ * in case @newinstr is longer than @oldinstr.
++ */
++.macro ALTERNATIVE oldinstr, newinstr, feature
++      .pushsection .altinstr_replacement,"ax"
++770:  \newinstr
++771:  .popsection
++772:  \oldinstr
++773:  alt_len_check 770b, 771b
++      alt_len_check 772b, 773b
++      alt_pad ( ( 771b - 770b ) - ( 773b - 772b ) )
++774:  .pushsection .altinstructions,"a"
++      alt_entry 772b, 774b, 770b, 771b, \feature
++      .popsection
++.endm
++
++/*
++ * Define an alternative between two instructions. If @feature is
++ * present, early code in apply_alternatives() replaces @oldinstr with
++ * @newinstr. ".skip" directive takes care of proper instruction padding
++ * in case @newinstr is longer than @oldinstr.
++ */
++.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
++      .pushsection .altinstr_replacement,"ax"
++770:  \newinstr1
++771:  \newinstr2
++772:  .popsection
++773:  \oldinstr
++774:  alt_len_check 770b, 771b
++      alt_len_check 771b, 772b
++      alt_len_check 773b, 774b
++      .if ( 771b - 770b > 772b - 771b )
++      alt_pad ( ( 771b - 770b ) - ( 774b - 773b ) )
++      .else
++      alt_pad ( ( 772b - 771b ) - ( 774b - 773b ) )
++      .endif
++775:  .pushsection .altinstructions,"a"
++      alt_entry 773b, 775b, 770b, 771b,\feature1
++      alt_entry 773b, 775b, 771b, 772b,\feature2
++      .popsection
++.endm
++
++#endif        /*  __ASSEMBLY__  */
++
++#endif /* _ASM_S390_ALTERNATIVE_ASM_H */
diff --git a/queue-4.16/s390-add-automatic-detection-of-the-spectre-defense.patch b/queue-4.16/s390-add-automatic-detection-of-the-spectre-defense.patch
new file mode 100644 (file)
index 0000000..039e8f5
--- /dev/null
@@ -0,0 +1,234 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:18 +0200
+Subject: s390: add automatic detection of the spectre defense
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-3-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit 6e179d64126b909f0b288fa63cdbf07c531e9b1d ]
+
+Automatically decide between nobp vs. expolines if the spectre_v2=auto
+kernel parameter is specified or CONFIG_EXPOLINE_AUTO=y is set.
+
+The decision made at boot time due to CONFIG_EXPOLINE_AUTO=y being set
+can be overruled with the nobp, nospec and spectre_v2 kernel parameters.
+
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/Kconfig                     |    2 -
+ arch/s390/Makefile                    |    2 -
+ arch/s390/include/asm/nospec-branch.h |    6 +--
+ arch/s390/kernel/alternative.c        |    1 
+ arch/s390/kernel/module.c             |   11 ++---
+ arch/s390/kernel/nospec-branch.c      |   68 +++++++++++++++++++++-------------
+ 6 files changed, 52 insertions(+), 38 deletions(-)
+
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -576,7 +576,7 @@ choice
+ config EXPOLINE_OFF
+       bool "spectre_v2=off"
+-config EXPOLINE_MEDIUM
++config EXPOLINE_AUTO
+       bool "spectre_v2=auto"
+ config EXPOLINE_FULL
+--- a/arch/s390/Makefile
++++ b/arch/s390/Makefile
+@@ -84,7 +84,7 @@ ifdef CONFIG_EXPOLINE
+     CC_FLAGS_EXPOLINE += -mfunction-return=thunk
+     CC_FLAGS_EXPOLINE += -mindirect-branch-table
+     export CC_FLAGS_EXPOLINE
+-    cflags-y += $(CC_FLAGS_EXPOLINE)
++    cflags-y += $(CC_FLAGS_EXPOLINE) -DCC_USING_EXPOLINE
+   endif
+ endif
+--- a/arch/s390/include/asm/nospec-branch.h
++++ b/arch/s390/include/asm/nospec-branch.h
+@@ -6,12 +6,10 @@
+ #include <linux/types.h>
+-extern int nospec_call_disable;
+-extern int nospec_return_disable;
++extern int nospec_disable;
+ void nospec_init_branches(void);
+-void nospec_call_revert(s32 *start, s32 *end);
+-void nospec_return_revert(s32 *start, s32 *end);
++void nospec_revert(s32 *start, s32 *end);
+ #endif /* __ASSEMBLY__ */
+--- a/arch/s390/kernel/alternative.c
++++ b/arch/s390/kernel/alternative.c
+@@ -2,6 +2,7 @@
+ #include <linux/module.h>
+ #include <asm/alternative.h>
+ #include <asm/facility.h>
++#include <asm/nospec-branch.h>
+ #define MAX_PATCH_LEN (255 - 1)
+--- a/arch/s390/kernel/module.c
++++ b/arch/s390/kernel/module.c
+@@ -159,7 +159,7 @@ int module_frob_arch_sections(Elf_Ehdr *
+       me->core_layout.size += me->arch.got_size;
+       me->arch.plt_offset = me->core_layout.size;
+       if (me->arch.plt_size) {
+-              if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_call_disable)
++              if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable)
+                       me->arch.plt_size += PLT_ENTRY_SIZE;
+               me->core_layout.size += me->arch.plt_size;
+       }
+@@ -318,8 +318,7 @@ static int apply_rela(Elf_Rela *rela, El
+                               info->plt_offset;
+                       ip[0] = 0x0d10e310;     /* basr 1,0  */
+                       ip[1] = 0x100a0004;     /* lg   1,10(1) */
+-                      if (IS_ENABLED(CONFIG_EXPOLINE) &&
+-                          !nospec_call_disable) {
++                      if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable) {
+                               unsigned int *ij;
+                               ij = me->core_layout.base +
+                                       me->arch.plt_offset +
+@@ -440,7 +439,7 @@ int module_finalize(const Elf_Ehdr *hdr,
+       void *aseg;
+       if (IS_ENABLED(CONFIG_EXPOLINE) &&
+-          !nospec_call_disable && me->arch.plt_size) {
++          !nospec_disable && me->arch.plt_size) {
+               unsigned int *ij;
+               ij = me->core_layout.base + me->arch.plt_offset +
+@@ -467,11 +466,11 @@ int module_finalize(const Elf_Ehdr *hdr,
+               if (IS_ENABLED(CONFIG_EXPOLINE) &&
+                   (!strcmp(".nospec_call_table", secname)))
+-                      nospec_call_revert(aseg, aseg + s->sh_size);
++                      nospec_revert(aseg, aseg + s->sh_size);
+               if (IS_ENABLED(CONFIG_EXPOLINE) &&
+                   (!strcmp(".nospec_return_table", secname)))
+-                      nospec_return_revert(aseg, aseg + s->sh_size);
++                      nospec_revert(aseg, aseg + s->sh_size);
+       }
+       jump_label_apply_nops(me);
+--- a/arch/s390/kernel/nospec-branch.c
++++ b/arch/s390/kernel/nospec-branch.c
+@@ -10,10 +10,17 @@ static int __init nobp_setup_early(char
+       rc = kstrtobool(str, &enabled);
+       if (rc)
+               return rc;
+-      if (enabled && test_facility(82))
++      if (enabled && test_facility(82)) {
++              /*
++               * The user explicitely requested nobp=1, enable it and
++               * disable the expoline support.
++               */
+               __set_facility(82, S390_lowcore.alt_stfle_fac_list);
+-      else
++              if (IS_ENABLED(CONFIG_EXPOLINE))
++                      nospec_disable = 1;
++      } else {
+               __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
++      }
+       return 0;
+ }
+ early_param("nobp", nobp_setup_early);
+@@ -27,31 +34,46 @@ early_param("nospec", nospec_setup_early
+ #ifdef CONFIG_EXPOLINE
+-int nospec_call_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
+-int nospec_return_disable = !IS_ENABLED(CONFIG_EXPOLINE_FULL);
++int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
+ static int __init nospectre_v2_setup_early(char *str)
+ {
+-      nospec_call_disable = 1;
+-      nospec_return_disable = 1;
++      nospec_disable = 1;
+       return 0;
+ }
+ early_param("nospectre_v2", nospectre_v2_setup_early);
++static int __init spectre_v2_auto_early(void)
++{
++      if (IS_ENABLED(CC_USING_EXPOLINE)) {
++              /*
++               * The kernel has been compiled with expolines.
++               * Keep expolines enabled and disable nobp.
++               */
++              nospec_disable = 0;
++              __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
++      }
++      /*
++       * If the kernel has not been compiled with expolines the
++       * nobp setting decides what is done, this depends on the
++       * CONFIG_KERNEL_NP option and the nobp/nospec parameters.
++       */
++      return 0;
++}
++#ifdef CONFIG_EXPOLINE_AUTO
++early_initcall(spectre_v2_auto_early);
++#endif
++
+ static int __init spectre_v2_setup_early(char *str)
+ {
+       if (str && !strncmp(str, "on", 2)) {
+-              nospec_call_disable = 0;
+-              nospec_return_disable = 0;
+-      }
+-      if (str && !strncmp(str, "off", 3)) {
+-              nospec_call_disable = 1;
+-              nospec_return_disable = 1;
+-      }
+-      if (str && !strncmp(str, "auto", 4)) {
+-              nospec_call_disable = 0;
+-              nospec_return_disable = 1;
++              nospec_disable = 0;
++              __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
+       }
++      if (str && !strncmp(str, "off", 3))
++              nospec_disable = 1;
++      if (str && !strncmp(str, "auto", 4))
++              spectre_v2_auto_early();
+       return 0;
+ }
+ early_param("spectre_v2", spectre_v2_setup_early);
+@@ -104,15 +126,9 @@ static void __init_or_module __nospec_re
+       }
+ }
+-void __init_or_module nospec_call_revert(s32 *start, s32 *end)
+-{
+-      if (nospec_call_disable)
+-              __nospec_revert(start, end);
+-}
+-
+-void __init_or_module nospec_return_revert(s32 *start, s32 *end)
++void __init_or_module nospec_revert(s32 *start, s32 *end)
+ {
+-      if (nospec_return_disable)
++      if (nospec_disable)
+               __nospec_revert(start, end);
+ }
+@@ -120,8 +136,8 @@ extern s32 __nospec_call_start[], __nosp
+ extern s32 __nospec_return_start[], __nospec_return_end[];
+ void __init nospec_init_branches(void)
+ {
+-      nospec_call_revert(__nospec_call_start, __nospec_call_end);
+-      nospec_return_revert(__nospec_return_start, __nospec_return_end);
++      nospec_revert(__nospec_call_start, __nospec_call_end);
++      nospec_revert(__nospec_return_start, __nospec_return_end);
+ }
+ #endif /* CONFIG_EXPOLINE */
diff --git a/queue-4.16/s390-add-sysfs-attributes-for-spectre.patch b/queue-4.16/s390-add-sysfs-attributes-for-spectre.patch
new file mode 100644 (file)
index 0000000..6d43985
--- /dev/null
@@ -0,0 +1,67 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:20 +0200
+Subject: s390: add sysfs attributes for spectre
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-5-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit d424986f1d6b16079b3231db0314923f4f8deed1 ]
+
+Set CONFIG_GENERIC_CPU_VULNERABILITIES and provide the two functions
+cpu_show_spectre_v1 and cpu_show_spectre_v2 to report the spectre
+mitigations.
+
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/Kconfig                |    1 +
+ arch/s390/kernel/nospec-branch.c |   19 +++++++++++++++++++
+ 2 files changed, 20 insertions(+)
+
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -120,6 +120,7 @@ config S390
+       select GENERIC_CLOCKEVENTS
+       select GENERIC_CPU_AUTOPROBE
+       select GENERIC_CPU_DEVICES if !SMP
++      select GENERIC_CPU_VULNERABILITIES
+       select GENERIC_FIND_FIRST_BIT
+       select GENERIC_SMP_IDLE_THREAD
+       select GENERIC_TIME_VSYSCALL
+--- a/arch/s390/kernel/nospec-branch.c
++++ b/arch/s390/kernel/nospec-branch.c
+@@ -1,5 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <linux/module.h>
++#include <linux/device.h>
+ #include <asm/nospec-branch.h>
+ static int __init nobp_setup_early(char *str)
+@@ -42,6 +43,24 @@ static int __init nospec_report(void)
+ }
+ arch_initcall(nospec_report);
++#ifdef CONFIG_SYSFS
++ssize_t cpu_show_spectre_v1(struct device *dev,
++                          struct device_attribute *attr, char *buf)
++{
++      return sprintf(buf, "Mitigation: __user pointer sanitization\n");
++}
++
++ssize_t cpu_show_spectre_v2(struct device *dev,
++                          struct device_attribute *attr, char *buf)
++{
++      if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
++              return sprintf(buf, "Mitigation: execute trampolines\n");
++      if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
++              return sprintf(buf, "Mitigation: limited branch prediction.\n");
++      return sprintf(buf, "Vulnerable\n");
++}
++#endif
++
+ #ifdef CONFIG_EXPOLINE
+ int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
diff --git a/queue-4.16/s390-correct-module-section-names-for-expoline-code-revert.patch b/queue-4.16/s390-correct-module-section-names-for-expoline-code-revert.patch
new file mode 100644 (file)
index 0000000..e1d480e
--- /dev/null
@@ -0,0 +1,46 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:23 +0200
+Subject: s390: correct module section names for expoline code revert
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-8-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit 6cf09958f32b9667bb3ebadf74367c791112771b ]
+
+The main linker script vmlinux.lds.S for the kernel image merges
+the expoline code patch tables into two section ".nospec_call_table"
+and ".nospec_return_table". This is *not* done for the modules,
+there the sections retain their original names as generated by gcc:
+".s390_indirect_call", ".s390_return_mem" and ".s390_return_reg".
+
+The module_finalize code has to check for the compiler generated
+section names, otherwise no code patching is done. This slows down
+the module code in case of "spectre_v2=off".
+
+Cc: stable@vger.kernel.org # 4.16
+Fixes: f19fbd5ed6 ("s390: introduce execute-trampolines for branches")
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/module.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/s390/kernel/module.c
++++ b/arch/s390/kernel/module.c
+@@ -465,11 +465,11 @@ int module_finalize(const Elf_Ehdr *hdr,
+                       apply_alternatives(aseg, aseg + s->sh_size);
+               if (IS_ENABLED(CONFIG_EXPOLINE) &&
+-                  (!strcmp(".nospec_call_table", secname)))
++                  (!strncmp(".s390_indirect", secname, 14)))
+                       nospec_revert(aseg, aseg + s->sh_size);
+               if (IS_ENABLED(CONFIG_EXPOLINE) &&
+-                  (!strcmp(".nospec_return_table", secname)))
++                  (!strncmp(".s390_return", secname, 12)))
+                       nospec_revert(aseg, aseg + s->sh_size);
+       }
diff --git a/queue-4.16/s390-correct-nospec-auto-detection-init-order.patch b/queue-4.16/s390-correct-nospec-auto-detection-init-order.patch
new file mode 100644 (file)
index 0000000..25346db
--- /dev/null
@@ -0,0 +1,86 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:22 +0200
+Subject: s390: correct nospec auto detection init order
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-7-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit 6a3d1e81a434fc311f224b8be77258bafc18ccc6 ]
+
+With CONFIG_EXPOLINE_AUTO=y the call of spectre_v2_auto_early() via
+early_initcall is done *after* the early_param functions. This
+overwrites any settings done with the nobp/no_spectre_v2/spectre_v2
+parameters. The code patching for the kernel is done after the
+evaluation of the early parameters but before the early_initcall
+is done. The end result is a kernel image that is patched correctly
+but the kernel modules are not.
+
+Make sure that the nospec auto detection function is called before the
+early parameters are evaluated and before the code patching is done.
+
+Fixes: 6e179d64126b ("s390: add automatic detection of the spectre defense")
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/include/asm/nospec-branch.h |    1 +
+ arch/s390/kernel/nospec-branch.c      |    8 ++------
+ arch/s390/kernel/setup.c              |    3 +++
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/s390/include/asm/nospec-branch.h
++++ b/arch/s390/include/asm/nospec-branch.h
+@@ -9,6 +9,7 @@
+ extern int nospec_disable;
+ void nospec_init_branches(void);
++void nospec_auto_detect(void);
+ void nospec_revert(s32 *start, s32 *end);
+ #endif /* __ASSEMBLY__ */
+--- a/arch/s390/kernel/nospec-branch.c
++++ b/arch/s390/kernel/nospec-branch.c
+@@ -72,7 +72,7 @@ static int __init nospectre_v2_setup_ear
+ }
+ early_param("nospectre_v2", nospectre_v2_setup_early);
+-static int __init spectre_v2_auto_early(void)
++void __init nospec_auto_detect(void)
+ {
+       if (IS_ENABLED(CC_USING_EXPOLINE)) {
+               /*
+@@ -87,11 +87,7 @@ static int __init spectre_v2_auto_early(
+        * nobp setting decides what is done, this depends on the
+        * CONFIG_KERNEL_NP option and the nobp/nospec parameters.
+        */
+-      return 0;
+ }
+-#ifdef CONFIG_EXPOLINE_AUTO
+-early_initcall(spectre_v2_auto_early);
+-#endif
+ static int __init spectre_v2_setup_early(char *str)
+ {
+@@ -102,7 +98,7 @@ static int __init spectre_v2_setup_early
+       if (str && !strncmp(str, "off", 3))
+               nospec_disable = 1;
+       if (str && !strncmp(str, "auto", 4))
+-              spectre_v2_auto_early();
++              nospec_auto_detect();
+       return 0;
+ }
+ early_param("spectre_v2", spectre_v2_setup_early);
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -893,6 +893,9 @@ void __init setup_arch(char **cmdline_p)
+       init_mm.end_data = (unsigned long) &_edata;
+       init_mm.brk = (unsigned long) &_end;
++      if (IS_ENABLED(CONFIG_EXPOLINE_AUTO))
++              nospec_auto_detect();
++
+       parse_early_param();
+ #ifdef CONFIG_CRASH_DUMP
+       /* Deactivate elfcorehdr= kernel parameter */
diff --git a/queue-4.16/s390-crc32-vx-use-expoline-for-indirect-branches.patch b/queue-4.16/s390-crc32-vx-use-expoline-for-indirect-branches.patch
new file mode 100644 (file)
index 0000000..73942c6
--- /dev/null
@@ -0,0 +1,79 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:25 +0200
+Subject: s390/crc32-vx: use expoline for indirect branches
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-10-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit 467a3bf219cee12259182c5cb4821f88fd518a51 ]
+
+The return from the crc32_le_vgfm_16/crc32c_le_vgfm_16 and the
+crc32_be_vgfm_16 functions are done with "br %r14". These are indirect
+branches as well and need to use execute trampolines for CONFIG_EXPOLINE=y.
+
+Cc: stable@vger.kernel.org # 4.16
+Fixes: f19fbd5ed6 ("s390: introduce execute-trampolines for branches")
+Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/crypto/crc32be-vx.S |    5 ++++-
+ arch/s390/crypto/crc32le-vx.S |    4 +++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/arch/s390/crypto/crc32be-vx.S
++++ b/arch/s390/crypto/crc32be-vx.S
+@@ -13,6 +13,7 @@
+  */
+ #include <linux/linkage.h>
++#include <asm/nospec-insn.h>
+ #include <asm/vx-insn.h>
+ /* Vector register range containing CRC-32 constants */
+@@ -67,6 +68,8 @@
+ .previous
++      GEN_BR_THUNK %r14
++
+ .text
+ /*
+  * The CRC-32 function(s) use these calling conventions:
+@@ -203,6 +206,6 @@ ENTRY(crc32_be_vgfm_16)
+ .Ldone:
+       VLGVF   %r2,%v2,3
+-      br      %r14
++      BR_EX   %r14
+ .previous
+--- a/arch/s390/crypto/crc32le-vx.S
++++ b/arch/s390/crypto/crc32le-vx.S
+@@ -14,6 +14,7 @@
+  */
+ #include <linux/linkage.h>
++#include <asm/nospec-insn.h>
+ #include <asm/vx-insn.h>
+ /* Vector register range containing CRC-32 constants */
+@@ -76,6 +77,7 @@
+ .previous
++      GEN_BR_THUNK %r14
+ .text
+@@ -264,6 +266,6 @@ crc32_le_vgfm_generic:
+ .Ldone:
+       VLGVF   %r2,%v2,2
+-      br      %r14
++      BR_EX   %r14
+ .previous
diff --git a/queue-4.16/s390-extend-expoline-to-bc-instructions.patch b/queue-4.16/s390-extend-expoline-to-bc-instructions.patch
new file mode 100644 (file)
index 0000000..e228908
--- /dev/null
@@ -0,0 +1,182 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:30 +0200
+Subject: s390: extend expoline to BC instructions
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-15-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit 6deaa3bbca804b2a3627fd685f75de64da7be535 ]
+
+The BPF JIT uses a 'b <disp>(%r<x>)' instruction in the definition
+of the sk_load_word and sk_load_half functions.
+
+Add support for branch-on-condition instructions contained in the
+thunk code of an expoline.
+
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/include/asm/nospec-insn.h |   57 ++++++++++++++++++++++++++++++++++++
+ arch/s390/kernel/nospec-branch.c    |   25 ++++++++++++---
+ 2 files changed, 77 insertions(+), 5 deletions(-)
+
+--- a/arch/s390/include/asm/nospec-insn.h
++++ b/arch/s390/include/asm/nospec-insn.h
+@@ -35,10 +35,18 @@ _LC_BR_R1 = __LC_BR_R1
+       __THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1
+       .endm
++      .macro __THUNK_PROLOG_BC d0,r1,r2
++      __THUNK_PROLOG_NAME __s390x_indirect_branch_\d0\()_\r2\()use_\r1
++      .endm
++
+       .macro __THUNK_BR r1,r2
+       jg      __s390x_indirect_jump_r\r2\()use_r\r1
+       .endm
++      .macro __THUNK_BC d0,r1,r2
++      jg      __s390x_indirect_branch_\d0\()_\r2\()use_\r1
++      .endm
++
+       .macro __THUNK_BRASL r1,r2,r3
+       brasl   \r1,__s390x_indirect_jump_r\r3\()use_r\r2
+       .endm
+@@ -81,6 +89,23 @@ _LC_BR_R1 = __LC_BR_R1
+       .endif
+       .endm
++      .macro  __DECODE_DRR expand,disp,reg,ruse
++      .set __decode_fail,1
++      .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
++      .ifc \reg,%r\r1
++      .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
++      .ifc \ruse,%r\r2
++      \expand \disp,\r1,\r2
++      .set __decode_fail,0
++      .endif
++      .endr
++      .endif
++      .endr
++      .if __decode_fail == 1
++      .error "__DECODE_DRR failed"
++      .endif
++      .endm
++
+       .macro __THUNK_EX_BR reg,ruse
+       # Be very careful when adding instructions to this macro!
+       # The ALTERNATIVE replacement code has a .+10 which targets
+@@ -101,12 +126,30 @@ _LC_BR_R1 = __LC_BR_R1
+ 555:  br      \reg
+       .endm
++      .macro __THUNK_EX_BC disp,reg,ruse
++#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
++      exrl    0,556f
++      j       .
++#else
++      larl    \ruse,556f
++      ex      0,0(\ruse)
++      j       .
++#endif
++556:  b       \disp(\reg)
++      .endm
++
+       .macro GEN_BR_THUNK reg,ruse=%r1
+       __DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
+       __THUNK_EX_BR \reg,\ruse
+       __THUNK_EPILOG
+       .endm
++      .macro GEN_B_THUNK disp,reg,ruse=%r1
++      __DECODE_DRR __THUNK_PROLOG_BC,\disp,\reg,\ruse
++      __THUNK_EX_BC \disp,\reg,\ruse
++      __THUNK_EPILOG
++      .endm
++
+       .macro BR_EX reg,ruse=%r1
+ 557:  __DECODE_RR __THUNK_BR,\reg,\ruse
+       .pushsection .s390_indirect_branches,"a",@progbits
+@@ -114,6 +157,13 @@ _LC_BR_R1 = __LC_BR_R1
+       .popsection
+       .endm
++       .macro B_EX disp,reg,ruse=%r1
++558:  __DECODE_DRR __THUNK_BC,\disp,\reg,\ruse
++      .pushsection .s390_indirect_branches,"a",@progbits
++      .long   558b-.
++      .popsection
++      .endm
++
+       .macro BASR_EX rsave,rtarget,ruse=%r1
+ 559:  __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse
+       .pushsection .s390_indirect_branches,"a",@progbits
+@@ -125,10 +175,17 @@ _LC_BR_R1 = __LC_BR_R1
+       .macro GEN_BR_THUNK reg,ruse=%r1
+       .endm
++      .macro GEN_B_THUNK disp,reg,ruse=%r1
++      .endm
++
+        .macro BR_EX reg,ruse=%r1
+       br      \reg
+       .endm
++       .macro B_EX disp,reg,ruse=%r1
++      b       \disp(\reg)
++      .endm
++
+       .macro BASR_EX rsave,rtarget,ruse=%r1
+       basr    \rsave,\rtarget
+       .endm
+--- a/arch/s390/kernel/nospec-branch.c
++++ b/arch/s390/kernel/nospec-branch.c
+@@ -93,7 +93,6 @@ static void __init_or_module __nospec_re
+       s32 *epo;
+       /* Second part of the instruction replace is always a nop */
+-      memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x00, 0x00 }, 4);
+       for (epo = start; epo < end; epo++) {
+               instr = (u8 *) epo + *epo;
+               if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04)
+@@ -114,18 +113,34 @@ static void __init_or_module __nospec_re
+                       br = thunk + (*(int *)(thunk + 2)) * 2;
+               else
+                       continue;
+-              if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0)
++              /* Check for unconditional branch 0x07f? or 0x47f???? */
++              if ((br[0] & 0xbf) != 0x07 || (br[1] & 0xf0) != 0xf0)
+                       continue;
++
++              memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x07, 0x00 }, 4);
+               switch (type) {
+               case BRCL_EXPOLINE:
+-                      /* brcl to thunk, replace with br + nop */
+                       insnbuf[0] = br[0];
+                       insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
++                      if (br[0] == 0x47) {
++                              /* brcl to b, replace with bc + nopr */
++                              insnbuf[2] = br[2];
++                              insnbuf[3] = br[3];
++                      } else {
++                              /* brcl to br, replace with bcr + nop */
++                      }
+                       break;
+               case BRASL_EXPOLINE:
+-                      /* brasl to thunk, replace with basr + nop */
+-                      insnbuf[0] = 0x0d;
+                       insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f);
++                      if (br[0] == 0x47) {
++                              /* brasl to b, replace with bas + nopr */
++                              insnbuf[0] = 0x4d;
++                              insnbuf[2] = br[2];
++                              insnbuf[3] = br[3];
++                      } else {
++                              /* brasl to br, replace with basr + nop */
++                              insnbuf[0] = 0x0d;
++                      }
+                       break;
+               }
diff --git a/queue-4.16/s390-ftrace-use-expoline-for-indirect-branches.patch b/queue-4.16/s390-ftrace-use-expoline-for-indirect-branches.patch
new file mode 100644 (file)
index 0000000..fcd9d7b
--- /dev/null
@@ -0,0 +1,147 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:27 +0200
+Subject: s390/ftrace: use expoline for indirect branches
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-12-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit 23a4d7fd34856da8218c4cfc23dba7a6ec0a423a ]
+
+The return from the ftrace_stub, _mcount, ftrace_caller and
+return_to_handler functions is done with "br %r14" and "br %r1".
+These are indirect branches as well and need to use execute
+trampolines for CONFIG_EXPOLINE=y.
+
+The ftrace_caller function is a special case as it returns to the
+start of a function and may only use %r0 and %r1. For a pre z10
+machine the standard execute trampoline uses a LARL + EX to do
+this, but this requires *two* registers in the range %r1..%r15.
+To get around this the 'br %r1' located in the lowcore is used,
+then the EX instruction does not need an address register.
+But the lowcore trick may only be used for pre z14 machines,
+with noexec=on the mapping for the first page may not contain
+instructions. The solution for that is an ALTERNATIVE in the
+expoline THUNK generated by 'GEN_BR_THUNK %r1' to switch to
+EXRL, this relies on the fact that a machine that supports
+noexec=on has EXRL as well.
+
+Cc: stable@vger.kernel.org # 4.16
+Fixes: f19fbd5ed6 ("s390: introduce execute-trampolines for branches")
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/include/asm/nospec-insn.h |   12 ++++++++++++
+ arch/s390/kernel/asm-offsets.c      |    1 +
+ arch/s390/kernel/mcount.S           |   14 +++++++++-----
+ 3 files changed, 22 insertions(+), 5 deletions(-)
+
+--- a/arch/s390/include/asm/nospec-insn.h
++++ b/arch/s390/include/asm/nospec-insn.h
+@@ -2,12 +2,16 @@
+ #ifndef _ASM_S390_NOSPEC_ASM_H
+ #define _ASM_S390_NOSPEC_ASM_H
++#include <asm/alternative-asm.h>
++#include <asm/asm-offsets.h>
+ #include <asm/dwarf.h>
+ #ifdef __ASSEMBLY__
+ #ifdef CONFIG_EXPOLINE
++_LC_BR_R1 = __LC_BR_R1
++
+ /*
+  * The expoline macros are used to create thunks in the same format
+  * as gcc generates them. The 'comdat' section flag makes sure that
+@@ -78,13 +82,21 @@
+       .endm
+       .macro __THUNK_EX_BR reg,ruse
++      # Be very careful when adding instructions to this macro!
++      # The ALTERNATIVE replacement code has a .+10 which targets
++      # the "br \reg" after the code has been patched.
+ #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
+       exrl    0,555f
+       j       .
+ #else
++      .ifc \reg,%r1
++      ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35
++      j       .
++      .else
+       larl    \ruse,555f
+       ex      0,0(\ruse)
+       j       .
++      .endif
+ #endif
+ 555:  br      \reg
+       .endm
+--- a/arch/s390/kernel/asm-offsets.c
++++ b/arch/s390/kernel/asm-offsets.c
+@@ -179,6 +179,7 @@ int main(void)
+       OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags);
+       OFFSET(__LC_PREEMPT_COUNT, lowcore, preempt_count);
+       OFFSET(__LC_GMAP, lowcore, gmap);
++      OFFSET(__LC_BR_R1, lowcore, br_r1_trampoline);
+       /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
+       OFFSET(__LC_DUMP_REIPL, lowcore, ipib);
+       /* hardware defined lowcore locations 0x1000 - 0x18ff */
+--- a/arch/s390/kernel/mcount.S
++++ b/arch/s390/kernel/mcount.S
+@@ -9,13 +9,17 @@
+ #include <linux/linkage.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/ftrace.h>
++#include <asm/nospec-insn.h>
+ #include <asm/ptrace.h>
+ #include <asm/export.h>
++      GEN_BR_THUNK %r1
++      GEN_BR_THUNK %r14
++
+       .section .kprobes.text, "ax"
+ ENTRY(ftrace_stub)
+-      br      %r14
++      BR_EX   %r14
+ #define STACK_FRAME_SIZE  (STACK_FRAME_OVERHEAD + __PT_SIZE)
+ #define STACK_PTREGS    (STACK_FRAME_OVERHEAD)
+@@ -23,7 +27,7 @@ ENTRY(ftrace_stub)
+ #define STACK_PTREGS_PSW  (STACK_PTREGS + __PT_PSW)
+ ENTRY(_mcount)
+-      br      %r14
++      BR_EX   %r14
+ EXPORT_SYMBOL(_mcount)
+@@ -53,7 +57,7 @@ ENTRY(ftrace_caller)
+ #endif
+       lgr     %r3,%r14
+       la      %r5,STACK_PTREGS(%r15)
+-      basr    %r14,%r1
++      BASR_EX %r14,%r1
+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ # The j instruction gets runtime patched to a nop instruction.
+ # See ftrace_enable_ftrace_graph_caller.
+@@ -68,7 +72,7 @@ ftrace_graph_caller_end:
+ #endif
+       lg      %r1,(STACK_PTREGS_PSW+8)(%r15)
+       lmg     %r2,%r15,(STACK_PTREGS_GPRS+2*8)(%r15)
+-      br      %r1
++      BR_EX   %r1
+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+@@ -81,6 +85,6 @@ ENTRY(return_to_handler)
+       aghi    %r15,STACK_FRAME_OVERHEAD
+       lgr     %r14,%r2
+       lmg     %r2,%r5,32(%r15)
+-      br      %r14
++      BR_EX   %r14
+ #endif
diff --git a/queue-4.16/s390-kernel-use-expoline-for-indirect-branches.patch b/queue-4.16/s390-kernel-use-expoline-for-indirect-branches.patch
new file mode 100644 (file)
index 0000000..42fcca7
--- /dev/null
@@ -0,0 +1,167 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:28 +0200
+Subject: s390/kernel: use expoline for indirect branches
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-13-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit c50c84c3ac4d5db683904bdb3257798b6ef980ae ]
+
+The assember code in arch/s390/kernel uses a few more indirect branches
+which need to be done with execute trampolines for CONFIG_EXPOLINE=y.
+
+Cc: stable@vger.kernel.org # 4.16
+Fixes: f19fbd5ed6 ("s390: introduce execute-trampolines for branches")
+Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/base.S   |   24 ++++++++++++++----------
+ arch/s390/kernel/reipl.S  |    7 +++++--
+ arch/s390/kernel/swsusp.S |   10 ++++++----
+ 3 files changed, 25 insertions(+), 16 deletions(-)
+
+--- a/arch/s390/kernel/base.S
++++ b/arch/s390/kernel/base.S
+@@ -9,18 +9,22 @@
+ #include <linux/linkage.h>
+ #include <asm/asm-offsets.h>
++#include <asm/nospec-insn.h>
+ #include <asm/ptrace.h>
+ #include <asm/sigp.h>
++      GEN_BR_THUNK %r9
++      GEN_BR_THUNK %r14
++
+ ENTRY(s390_base_mcck_handler)
+       basr    %r13,0
+ 0:    lg      %r15,__LC_PANIC_STACK   # load panic stack
+       aghi    %r15,-STACK_FRAME_OVERHEAD
+       larl    %r1,s390_base_mcck_handler_fn
+-      lg      %r1,0(%r1)
+-      ltgr    %r1,%r1
++      lg      %r9,0(%r1)
++      ltgr    %r9,%r9
+       jz      1f
+-      basr    %r14,%r1
++      BASR_EX %r14,%r9
+ 1:    la      %r1,4095
+       lmg     %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
+       lpswe   __LC_MCK_OLD_PSW
+@@ -37,10 +41,10 @@ ENTRY(s390_base_ext_handler)
+       basr    %r13,0
+ 0:    aghi    %r15,-STACK_FRAME_OVERHEAD
+       larl    %r1,s390_base_ext_handler_fn
+-      lg      %r1,0(%r1)
+-      ltgr    %r1,%r1
++      lg      %r9,0(%r1)
++      ltgr    %r9,%r9
+       jz      1f
+-      basr    %r14,%r1
++      BASR_EX %r14,%r9
+ 1:    lmg     %r0,%r15,__LC_SAVE_AREA_ASYNC
+       ni      __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
+       lpswe   __LC_EXT_OLD_PSW
+@@ -57,10 +61,10 @@ ENTRY(s390_base_pgm_handler)
+       basr    %r13,0
+ 0:    aghi    %r15,-STACK_FRAME_OVERHEAD
+       larl    %r1,s390_base_pgm_handler_fn
+-      lg      %r1,0(%r1)
+-      ltgr    %r1,%r1
++      lg      %r9,0(%r1)
++      ltgr    %r9,%r9
+       jz      1f
+-      basr    %r14,%r1
++      BASR_EX %r14,%r9
+       lmg     %r0,%r15,__LC_SAVE_AREA_SYNC
+       lpswe   __LC_PGM_OLD_PSW
+ 1:    lpswe   disabled_wait_psw-0b(%r13)
+@@ -117,7 +121,7 @@ ENTRY(diag308_reset)
+       larl    %r4,.Lcontinue_psw      # Restore PSW flags
+       lpswe   0(%r4)
+ .Lcontinue:
+-      br      %r14
++      BR_EX   %r14
+ .align 16
+ .Lrestart_psw:
+       .long   0x00080000,0x80000000 + .Lrestart_part2
+--- a/arch/s390/kernel/reipl.S
++++ b/arch/s390/kernel/reipl.S
+@@ -7,8 +7,11 @@
+ #include <linux/linkage.h>
+ #include <asm/asm-offsets.h>
++#include <asm/nospec-insn.h>
+ #include <asm/sigp.h>
++      GEN_BR_THUNK %r9
++
+ #
+ # Issue "store status" for the current CPU to its prefix page
+ # and call passed function afterwards
+@@ -67,9 +70,9 @@ ENTRY(store_status)
+       st      %r4,0(%r1)
+       st      %r5,4(%r1)
+       stg     %r2,8(%r1)
+-      lgr     %r1,%r2
++      lgr     %r9,%r2
+       lgr     %r2,%r3
+-      br      %r1
++      BR_EX   %r9
+       .section .bss
+       .align  8
+--- a/arch/s390/kernel/swsusp.S
++++ b/arch/s390/kernel/swsusp.S
+@@ -13,6 +13,7 @@
+ #include <asm/ptrace.h>
+ #include <asm/thread_info.h>
+ #include <asm/asm-offsets.h>
++#include <asm/nospec-insn.h>
+ #include <asm/sigp.h>
+ /*
+@@ -24,6 +25,8 @@
+  * (see below) in the resume process.
+  * This function runs with disabled interrupts.
+  */
++      GEN_BR_THUNK %r14
++
+       .section .text
+ ENTRY(swsusp_arch_suspend)
+       stmg    %r6,%r15,__SF_GPRS(%r15)
+@@ -103,7 +106,7 @@ ENTRY(swsusp_arch_suspend)
+       spx     0x318(%r1)
+       lmg     %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
+       lghi    %r2,0
+-      br      %r14
++      BR_EX   %r14
+ /*
+  * Restore saved memory image to correct place and restore register context.
+@@ -197,11 +200,10 @@ pgm_check_entry:
+       larl    %r15,init_thread_union
+       ahi     %r15,1<<(PAGE_SHIFT+THREAD_SIZE_ORDER)
+       larl    %r2,.Lpanic_string
+-      larl    %r3,sclp_early_printk
+       lghi    %r1,0
+       sam31
+       sigp    %r1,%r0,SIGP_SET_ARCHITECTURE
+-      basr    %r14,%r3
++      brasl   %r14,sclp_early_printk
+       larl    %r3,.Ldisabled_wait_31
+       lpsw    0(%r3)
+ 4:
+@@ -267,7 +269,7 @@ restore_registers:
+       /* Return 0 */
+       lmg     %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
+       lghi    %r2,0
+-      br      %r14
++      BR_EX   %r14
+       .section .data..nosave,"aw",@progbits
+       .align  8
diff --git a/queue-4.16/s390-lib-use-expoline-for-indirect-branches.patch b/queue-4.16/s390-lib-use-expoline-for-indirect-branches.patch
new file mode 100644 (file)
index 0000000..eea67f9
--- /dev/null
@@ -0,0 +1,98 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:26 +0200
+Subject: s390/lib: use expoline for indirect branches
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-11-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit 97489e0663fa700d6e7febddc43b58df98d7bcda ]
+
+The return from the memmove, memset, memcpy, __memset16, __memset32 and
+__memset64 functions are done with "br %r14". These are indirect branches
+as well and need to use execute trampolines for CONFIG_EXPOLINE=y.
+
+Cc: stable@vger.kernel.org # 4.16
+Fixes: f19fbd5ed6 ("s390: introduce execute-trampolines for branches")
+Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/lib/mem.S |   19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+--- a/arch/s390/lib/mem.S
++++ b/arch/s390/lib/mem.S
+@@ -7,6 +7,9 @@
+ #include <linux/linkage.h>
+ #include <asm/export.h>
++#include <asm/nospec-insn.h>
++
++      GEN_BR_THUNK %r14
+ /*
+  * void *memmove(void *dest, const void *src, size_t n)
+@@ -33,14 +36,14 @@ ENTRY(memmove)
+ .Lmemmove_forward_remainder:
+       larl    %r5,.Lmemmove_mvc
+       ex      %r4,0(%r5)
+-      br      %r14
++      BR_EX   %r14
+ .Lmemmove_reverse:
+       ic      %r0,0(%r4,%r3)
+       stc     %r0,0(%r4,%r1)
+       brctg   %r4,.Lmemmove_reverse
+       ic      %r0,0(%r4,%r3)
+       stc     %r0,0(%r4,%r1)
+-      br      %r14
++      BR_EX   %r14
+ .Lmemmove_mvc:
+       mvc     0(1,%r1),0(%r3)
+ EXPORT_SYMBOL(memmove)
+@@ -77,7 +80,7 @@ ENTRY(memset)
+ .Lmemset_clear_remainder:
+       larl    %r3,.Lmemset_xc
+       ex      %r4,0(%r3)
+-      br      %r14
++      BR_EX   %r14
+ .Lmemset_fill:
+       cghi    %r4,1
+       lgr     %r1,%r2
+@@ -95,10 +98,10 @@ ENTRY(memset)
+       stc     %r3,0(%r1)
+       larl    %r5,.Lmemset_mvc
+       ex      %r4,0(%r5)
+-      br      %r14
++      BR_EX   %r14
+ .Lmemset_fill_exit:
+       stc     %r3,0(%r1)
+-      br      %r14
++      BR_EX   %r14
+ .Lmemset_xc:
+       xc      0(1,%r1),0(%r1)
+ .Lmemset_mvc:
+@@ -121,7 +124,7 @@ ENTRY(memcpy)
+ .Lmemcpy_remainder:
+       larl    %r5,.Lmemcpy_mvc
+       ex      %r4,0(%r5)
+-      br      %r14
++      BR_EX   %r14
+ .Lmemcpy_loop:
+       mvc     0(256,%r1),0(%r3)
+       la      %r1,256(%r1)
+@@ -159,10 +162,10 @@ ENTRY(__memset\bits)
+       \insn   %r3,0(%r1)
+       larl    %r5,.L__memset_mvc\bits
+       ex      %r4,0(%r5)
+-      br      %r14
++      BR_EX   %r14
+ .L__memset_exit\bits:
+       \insn   %r3,0(%r2)
+-      br      %r14
++      BR_EX   %r14
+ .L__memset_mvc\bits:
+       mvc     \bytes(1,%r1),0(%r1)
+ .endm
diff --git a/queue-4.16/s390-move-expoline-assembler-macros-to-a-header.patch b/queue-4.16/s390-move-expoline-assembler-macros-to-a-header.patch
new file mode 100644 (file)
index 0000000..29b916c
--- /dev/null
@@ -0,0 +1,412 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:24 +0200
+Subject: s390: move expoline assembler macros to a header
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-9-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit 6dd85fbb87d1d6b87a3b1f02ca28d7b2abd2e7ba ]
+
+To be able to use the expoline branches in different assembler
+files move the associated macros from entry.S to a new header
+nospec-insn.h.
+
+While we are at it make the macros a bit nicer to use.
+
+Cc: stable@vger.kernel.org # 4.16
+Fixes: f19fbd5ed6 ("s390: introduce execute-trampolines for branches")
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/include/asm/nospec-insn.h |  127 ++++++++++++++++++++++++++++++++++++
+ arch/s390/kernel/entry.S            |  105 ++++++-----------------------
+ 2 files changed, 151 insertions(+), 81 deletions(-)
+ create mode 100644 arch/s390/include/asm/nospec-insn.h
+
+--- /dev/null
++++ b/arch/s390/include/asm/nospec-insn.h
+@@ -0,0 +1,127 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef _ASM_S390_NOSPEC_ASM_H
++#define _ASM_S390_NOSPEC_ASM_H
++
++#include <asm/dwarf.h>
++
++#ifdef __ASSEMBLY__
++
++#ifdef CONFIG_EXPOLINE
++
++/*
++ * The expoline macros are used to create thunks in the same format
++ * as gcc generates them. The 'comdat' section flag makes sure that
++ * the various thunks are merged into a single copy.
++ */
++      .macro __THUNK_PROLOG_NAME name
++      .pushsection .text.\name,"axG",@progbits,\name,comdat
++      .globl \name
++      .hidden \name
++      .type \name,@function
++\name:
++      CFI_STARTPROC
++      .endm
++
++      .macro __THUNK_EPILOG
++      CFI_ENDPROC
++      .popsection
++      .endm
++
++      .macro __THUNK_PROLOG_BR r1,r2
++      __THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1
++      .endm
++
++      .macro __THUNK_BR r1,r2
++      jg      __s390x_indirect_jump_r\r2\()use_r\r1
++      .endm
++
++      .macro __THUNK_BRASL r1,r2,r3
++      brasl   \r1,__s390x_indirect_jump_r\r3\()use_r\r2
++      .endm
++
++      .macro  __DECODE_RR expand,reg,ruse
++      .set __decode_fail,1
++      .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
++      .ifc \reg,%r\r1
++      .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
++      .ifc \ruse,%r\r2
++      \expand \r1,\r2
++      .set __decode_fail,0
++      .endif
++      .endr
++      .endif
++      .endr
++      .if __decode_fail == 1
++      .error "__DECODE_RR failed"
++      .endif
++      .endm
++
++      .macro  __DECODE_RRR expand,rsave,rtarget,ruse
++      .set __decode_fail,1
++      .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
++      .ifc \rsave,%r\r1
++      .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
++      .ifc \rtarget,%r\r2
++      .irp r3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
++      .ifc \ruse,%r\r3
++      \expand \r1,\r2,\r3
++      .set __decode_fail,0
++      .endif
++      .endr
++      .endif
++      .endr
++      .endif
++      .endr
++      .if __decode_fail == 1
++      .error "__DECODE_RRR failed"
++      .endif
++      .endm
++
++      .macro __THUNK_EX_BR reg,ruse
++#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
++      exrl    0,555f
++      j       .
++#else
++      larl    \ruse,555f
++      ex      0,0(\ruse)
++      j       .
++#endif
++555:  br      \reg
++      .endm
++
++      .macro GEN_BR_THUNK reg,ruse=%r1
++      __DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
++      __THUNK_EX_BR \reg,\ruse
++      __THUNK_EPILOG
++      .endm
++
++      .macro BR_EX reg,ruse=%r1
++557:  __DECODE_RR __THUNK_BR,\reg,\ruse
++      .pushsection .s390_indirect_branches,"a",@progbits
++      .long   557b-.
++      .popsection
++      .endm
++
++      .macro BASR_EX rsave,rtarget,ruse=%r1
++559:  __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse
++      .pushsection .s390_indirect_branches,"a",@progbits
++      .long   559b-.
++      .popsection
++      .endm
++
++#else
++      .macro GEN_BR_THUNK reg,ruse=%r1
++      .endm
++
++       .macro BR_EX reg,ruse=%r1
++      br      \reg
++      .endm
++
++      .macro BASR_EX rsave,rtarget,ruse=%r1
++      basr    \rsave,\rtarget
++      .endm
++#endif
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* _ASM_S390_NOSPEC_ASM_H */
+--- a/arch/s390/kernel/entry.S
++++ b/arch/s390/kernel/entry.S
+@@ -27,6 +27,7 @@
+ #include <asm/setup.h>
+ #include <asm/nmi.h>
+ #include <asm/export.h>
++#include <asm/nospec-insn.h>
+ __PT_R0      =        __PT_GPRS
+ __PT_R1      =        __PT_GPRS + 8
+@@ -223,67 +224,9 @@ _PIF_WORK = (_PIF_PER_TRAP | _PIF_SYSCAL
+       .popsection
+       .endm
+-#ifdef CONFIG_EXPOLINE
+-
+-      .macro GEN_BR_THUNK name,reg,tmp
+-      .section .text.\name,"axG",@progbits,\name,comdat
+-      .globl \name
+-      .hidden \name
+-      .type \name,@function
+-\name:
+-      CFI_STARTPROC
+-#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
+-      exrl    0,0f
+-#else
+-      larl    \tmp,0f
+-      ex      0,0(\tmp)
+-#endif
+-      j       .
+-0:    br      \reg
+-      CFI_ENDPROC
+-      .endm
+-
+-      GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1
+-      GEN_BR_THUNK __s390x_indirect_jump_r1use_r14,%r14,%r1
+-      GEN_BR_THUNK __s390x_indirect_jump_r11use_r14,%r14,%r11
+-
+-      .macro BASR_R14_R9
+-0:    brasl   %r14,__s390x_indirect_jump_r1use_r9
+-      .pushsection .s390_indirect_branches,"a",@progbits
+-      .long   0b-.
+-      .popsection
+-      .endm
+-
+-      .macro BR_R1USE_R14
+-0:    jg      __s390x_indirect_jump_r1use_r14
+-      .pushsection .s390_indirect_branches,"a",@progbits
+-      .long   0b-.
+-      .popsection
+-      .endm
+-
+-      .macro BR_R11USE_R14
+-0:    jg      __s390x_indirect_jump_r11use_r14
+-      .pushsection .s390_indirect_branches,"a",@progbits
+-      .long   0b-.
+-      .popsection
+-      .endm
+-
+-#else /* CONFIG_EXPOLINE */
+-
+-      .macro BASR_R14_R9
+-      basr    %r14,%r9
+-      .endm
+-
+-      .macro BR_R1USE_R14
+-      br      %r14
+-      .endm
+-
+-      .macro BR_R11USE_R14
+-      br      %r14
+-      .endm
+-
+-#endif /* CONFIG_EXPOLINE */
+-
++      GEN_BR_THUNK %r9
++      GEN_BR_THUNK %r14
++      GEN_BR_THUNK %r14,%r11
+       .section .kprobes.text, "ax"
+ .Ldummy:
+@@ -300,7 +243,7 @@ _PIF_WORK  = (_PIF_PER_TRAP | _PIF_SYSCAL
+ ENTRY(__bpon)
+       .globl __bpon
+       BPON
+-      BR_R1USE_R14
++      BR_EX   %r14
+ /*
+  * Scheduler resume function, called by switch_to
+@@ -326,7 +269,7 @@ ENTRY(__switch_to)
+       TSTMSK  __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
+       jz      0f
+       .insn   s,0xb2800000,__LC_LPP           # set program parameter
+-0:    BR_R1USE_R14
++0:    BR_EX   %r14
+ .L__critical_start:
+@@ -393,7 +336,7 @@ sie_exit:
+       xgr     %r5,%r5
+       lmg     %r6,%r14,__SF_GPRS(%r15)        # restore kernel registers
+       lg      %r2,__SF_EMPTY+16(%r15)         # return exit reason code
+-      BR_R1USE_R14
++      BR_EX   %r14
+ .Lsie_fault:
+       lghi    %r14,-EFAULT
+       stg     %r14,__SF_EMPTY+16(%r15)        # set exit reason code
+@@ -452,7 +395,7 @@ ENTRY(system_call)
+       lgf     %r9,0(%r8,%r10)                 # get system call add.
+       TSTMSK  __TI_flags(%r12),_TIF_TRACE
+       jnz     .Lsysc_tracesys
+-      BASR_R14_R9                             # call sys_xxxx
++      BASR_EX %r14,%r9                        # call sys_xxxx
+       stg     %r2,__PT_R2(%r11)               # store return value
+ .Lsysc_return:
+@@ -637,7 +580,7 @@ ENTRY(system_call)
+       lmg     %r3,%r7,__PT_R3(%r11)
+       stg     %r7,STACK_FRAME_OVERHEAD(%r15)
+       lg      %r2,__PT_ORIG_GPR2(%r11)
+-      BASR_R14_R9                     # call sys_xxx
++      BASR_EX %r14,%r9                # call sys_xxx
+       stg     %r2,__PT_R2(%r11)       # store return value
+ .Lsysc_tracenogo:
+       TSTMSK  __TI_flags(%r12),_TIF_TRACE
+@@ -661,7 +604,7 @@ ENTRY(ret_from_fork)
+       lmg     %r9,%r10,__PT_R9(%r11)  # load gprs
+ ENTRY(kernel_thread_starter)
+       la      %r2,0(%r10)
+-      BASR_R14_R9
++      BASR_EX %r14,%r9
+       j       .Lsysc_tracenogo
+ /*
+@@ -743,7 +686,7 @@ ENTRY(pgm_check_handler)
+       je      .Lpgm_return
+       lgf     %r9,0(%r10,%r1)         # load address of handler routine
+       lgr     %r2,%r11                # pass pointer to pt_regs
+-      BASR_R14_R9                     # branch to interrupt-handler
++      BASR_EX %r14,%r9                # branch to interrupt-handler
+ .Lpgm_return:
+       LOCKDEP_SYS_EXIT
+       tm      __PT_PSW+1(%r11),0x01   # returning to user ?
+@@ -1061,7 +1004,7 @@ ENTRY(psw_idle)
+       stpt    __TIMER_IDLE_ENTER(%r2)
+ .Lpsw_idle_lpsw:
+       lpswe   __SF_EMPTY(%r15)
+-      BR_R1USE_R14
++      BR_EX   %r14
+ .Lpsw_idle_end:
+ /*
+@@ -1103,7 +1046,7 @@ ENTRY(save_fpu_regs)
+ .Lsave_fpu_regs_done:
+       oi      __LC_CPU_FLAGS+7,_CIF_FPU
+ .Lsave_fpu_regs_exit:
+-      BR_R1USE_R14
++      BR_EX   %r14
+ .Lsave_fpu_regs_end:
+ EXPORT_SYMBOL(save_fpu_regs)
+@@ -1149,7 +1092,7 @@ load_fpu_regs:
+ .Lload_fpu_regs_done:
+       ni      __LC_CPU_FLAGS+7,255-_CIF_FPU
+ .Lload_fpu_regs_exit:
+-      BR_R1USE_R14
++      BR_EX   %r14
+ .Lload_fpu_regs_end:
+ .L__critical_end:
+@@ -1366,7 +1309,7 @@ cleanup_critical:
+       jl      0f
+       clg     %r9,BASED(.Lcleanup_table+104)  # .Lload_fpu_regs_end
+       jl      .Lcleanup_load_fpu_regs
+-0:    BR_R11USE_R14
++0:    BR_EX   %r14
+       .align  8
+ .Lcleanup_table:
+@@ -1402,7 +1345,7 @@ cleanup_critical:
+       ni      __SIE_PROG0C+3(%r9),0xfe        # no longer in SIE
+       lctlg   %c1,%c1,__LC_USER_ASCE          # load primary asce
+       larl    %r9,sie_exit                    # skip forward to sie_exit
+-      BR_R11USE_R14
++      BR_EX   %r14
+ #endif
+ .Lcleanup_system_call:
+@@ -1456,7 +1399,7 @@ cleanup_critical:
+       stg     %r15,56(%r11)           # r15 stack pointer
+       # set new psw address and exit
+       larl    %r9,.Lsysc_do_svc
+-      BR_R11USE_R14
++      BR_EX   %r14,%r11
+ .Lcleanup_system_call_insn:
+       .quad   system_call
+       .quad   .Lsysc_stmg
+@@ -1468,7 +1411,7 @@ cleanup_critical:
+ .Lcleanup_sysc_tif:
+       larl    %r9,.Lsysc_tif
+-      BR_R11USE_R14
++      BR_EX   %r14,%r11
+ .Lcleanup_sysc_restore:
+       # check if stpt has been executed
+@@ -1485,14 +1428,14 @@ cleanup_critical:
+       mvc     0(64,%r11),__PT_R8(%r9)
+       lmg     %r0,%r7,__PT_R0(%r9)
+ 1:    lmg     %r8,%r9,__LC_RETURN_PSW
+-      BR_R11USE_R14
++      BR_EX   %r14,%r11
+ .Lcleanup_sysc_restore_insn:
+       .quad   .Lsysc_exit_timer
+       .quad   .Lsysc_done - 4
+ .Lcleanup_io_tif:
+       larl    %r9,.Lio_tif
+-      BR_R11USE_R14
++      BR_EX   %r14,%r11
+ .Lcleanup_io_restore:
+       # check if stpt has been executed
+@@ -1506,7 +1449,7 @@ cleanup_critical:
+       mvc     0(64,%r11),__PT_R8(%r9)
+       lmg     %r0,%r7,__PT_R0(%r9)
+ 1:    lmg     %r8,%r9,__LC_RETURN_PSW
+-      BR_R11USE_R14
++      BR_EX   %r14,%r11
+ .Lcleanup_io_restore_insn:
+       .quad   .Lio_exit_timer
+       .quad   .Lio_done - 4
+@@ -1559,17 +1502,17 @@ cleanup_critical:
+       # prepare return psw
+       nihh    %r8,0xfcfd              # clear irq & wait state bits
+       lg      %r9,48(%r11)            # return from psw_idle
+-      BR_R11USE_R14
++      BR_EX   %r14,%r11
+ .Lcleanup_idle_insn:
+       .quad   .Lpsw_idle_lpsw
+ .Lcleanup_save_fpu_regs:
+       larl    %r9,save_fpu_regs
+-      BR_R11USE_R14
++      BR_EX   %r14,%r11
+ .Lcleanup_load_fpu_regs:
+       larl    %r9,load_fpu_regs
+-      BR_R11USE_R14
++      BR_EX   %r14,%r11
+ /*
+  * Integer constants
diff --git a/queue-4.16/s390-move-nobp-parameter-functions-to-nospec-branch.c.patch b/queue-4.16/s390-move-nobp-parameter-functions-to-nospec-branch.c.patch
new file mode 100644 (file)
index 0000000..97c3f64
--- /dev/null
@@ -0,0 +1,111 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:17 +0200
+Subject: s390: move nobp parameter functions to nospec-branch.c
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-2-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit b2e2f43a01bace1a25bdbae04c9f9846882b727a ]
+
+Keep the code for the nobp parameter handling with the code for
+expolines. Both are related to the spectre v2 mitigation.
+
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/Makefile        |    4 ++--
+ arch/s390/kernel/alternative.c   |   23 -----------------------
+ arch/s390/kernel/nospec-branch.c |   27 +++++++++++++++++++++++++++
+ 3 files changed, 29 insertions(+), 25 deletions(-)
+
+--- a/arch/s390/kernel/Makefile
++++ b/arch/s390/kernel/Makefile
+@@ -61,11 +61,11 @@ obj-y      += debug.o irq.o ipl.o dis.o diag.
+ obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o
+ obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o
+ obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o
++obj-y += nospec-branch.o
+ extra-y                               += head.o head64.o vmlinux.lds
+-obj-$(CONFIG_EXPOLINE)                += nospec-branch.o
+-CFLAGS_REMOVE_expoline.o      += $(CC_FLAGS_EXPOLINE)
++CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE)
+ obj-$(CONFIG_MODULES)         += module.o
+ obj-$(CONFIG_SMP)             += smp.o
+--- a/arch/s390/kernel/alternative.c
++++ b/arch/s390/kernel/alternative.c
+@@ -15,29 +15,6 @@ static int __init disable_alternative_in
+ early_param("noaltinstr", disable_alternative_instructions);
+-static int __init nobp_setup_early(char *str)
+-{
+-      bool enabled;
+-      int rc;
+-
+-      rc = kstrtobool(str, &enabled);
+-      if (rc)
+-              return rc;
+-      if (enabled && test_facility(82))
+-              __set_facility(82, S390_lowcore.alt_stfle_fac_list);
+-      else
+-              __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
+-      return 0;
+-}
+-early_param("nobp", nobp_setup_early);
+-
+-static int __init nospec_setup_early(char *str)
+-{
+-      __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
+-      return 0;
+-}
+-early_param("nospec", nospec_setup_early);
+-
+ struct brcl_insn {
+       u16 opc;
+       s32 disp;
+--- a/arch/s390/kernel/nospec-branch.c
++++ b/arch/s390/kernel/nospec-branch.c
+@@ -2,6 +2,31 @@
+ #include <linux/module.h>
+ #include <asm/nospec-branch.h>
++static int __init nobp_setup_early(char *str)
++{
++      bool enabled;
++      int rc;
++
++      rc = kstrtobool(str, &enabled);
++      if (rc)
++              return rc;
++      if (enabled && test_facility(82))
++              __set_facility(82, S390_lowcore.alt_stfle_fac_list);
++      else
++              __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
++      return 0;
++}
++early_param("nobp", nobp_setup_early);
++
++static int __init nospec_setup_early(char *str)
++{
++      __clear_facility(82, S390_lowcore.alt_stfle_fac_list);
++      return 0;
++}
++early_param("nospec", nospec_setup_early);
++
++#ifdef CONFIG_EXPOLINE
++
+ int nospec_call_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
+ int nospec_return_disable = !IS_ENABLED(CONFIG_EXPOLINE_FULL);
+@@ -98,3 +123,5 @@ void __init nospec_init_branches(void)
+       nospec_call_revert(__nospec_call_start, __nospec_call_end);
+       nospec_return_revert(__nospec_return_start, __nospec_return_end);
+ }
++
++#endif /* CONFIG_EXPOLINE */
diff --git a/queue-4.16/s390-move-spectre-sysfs-attribute-code.patch b/queue-4.16/s390-move-spectre-sysfs-attribute-code.patch
new file mode 100644 (file)
index 0000000..2eacb00
--- /dev/null
@@ -0,0 +1,92 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:29 +0200
+Subject: s390: move spectre sysfs attribute code
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-14-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit 4253b0e0627ee3461e64c2495c616f1c8f6b127b ]
+
+The nospec-branch.c file is compiled without the gcc options to
+generate expoline thunks. The return branch of the sysfs show
+functions cpu_show_spectre_v1 and cpu_show_spectre_v2 is an indirect
+branch as well. These need to be compiled with expolines.
+
+Move the sysfs functions for spectre reporting to a separate file
+and loose an '.' for one of the messages.
+
+Cc: stable@vger.kernel.org # 4.16
+Fixes: d424986f1d ("s390: add sysfs attributes for spectre")
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/Makefile        |    1 +
+ arch/s390/kernel/nospec-branch.c |   18 ------------------
+ arch/s390/kernel/nospec-sysfs.c  |   21 +++++++++++++++++++++
+ 3 files changed, 22 insertions(+), 18 deletions(-)
+ create mode 100644 arch/s390/kernel/nospec-sysfs.c
+
+--- a/arch/s390/kernel/Makefile
++++ b/arch/s390/kernel/Makefile
+@@ -65,6 +65,7 @@ obj-y        += nospec-branch.o
+ extra-y                               += head.o head64.o vmlinux.lds
++obj-$(CONFIG_SYSFS)           += nospec-sysfs.o
+ CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE)
+ obj-$(CONFIG_MODULES)         += module.o
+--- a/arch/s390/kernel/nospec-branch.c
++++ b/arch/s390/kernel/nospec-branch.c
+@@ -43,24 +43,6 @@ static int __init nospec_report(void)
+ }
+ arch_initcall(nospec_report);
+-#ifdef CONFIG_SYSFS
+-ssize_t cpu_show_spectre_v1(struct device *dev,
+-                          struct device_attribute *attr, char *buf)
+-{
+-      return sprintf(buf, "Mitigation: __user pointer sanitization\n");
+-}
+-
+-ssize_t cpu_show_spectre_v2(struct device *dev,
+-                          struct device_attribute *attr, char *buf)
+-{
+-      if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
+-              return sprintf(buf, "Mitigation: execute trampolines\n");
+-      if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
+-              return sprintf(buf, "Mitigation: limited branch prediction.\n");
+-      return sprintf(buf, "Vulnerable\n");
+-}
+-#endif
+-
+ #ifdef CONFIG_EXPOLINE
+ int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
+--- /dev/null
++++ b/arch/s390/kernel/nospec-sysfs.c
+@@ -0,0 +1,21 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <linux/device.h>
++#include <linux/cpu.h>
++#include <asm/facility.h>
++#include <asm/nospec-branch.h>
++
++ssize_t cpu_show_spectre_v1(struct device *dev,
++                          struct device_attribute *attr, char *buf)
++{
++      return sprintf(buf, "Mitigation: __user pointer sanitization\n");
++}
++
++ssize_t cpu_show_spectre_v2(struct device *dev,
++                          struct device_attribute *attr, char *buf)
++{
++      if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
++              return sprintf(buf, "Mitigation: execute trampolines\n");
++      if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
++              return sprintf(buf, "Mitigation: limited branch prediction\n");
++      return sprintf(buf, "Vulnerable\n");
++}
diff --git a/queue-4.16/s390-report-spectre-mitigation-via-syslog.patch b/queue-4.16/s390-report-spectre-mitigation-via-syslog.patch
new file mode 100644 (file)
index 0000000..8bc1331
--- /dev/null
@@ -0,0 +1,42 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:19 +0200
+Subject: s390: report spectre mitigation via syslog
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-4-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit bc035599718412cfba9249aa713f90ef13f13ee9 ]
+
+Add a boot message if either of the spectre defenses is active.
+The message is
+    "Spectre V2 mitigation: execute trampolines."
+or  "Spectre V2 mitigation: limited branch prediction."
+
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/nospec-branch.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/s390/kernel/nospec-branch.c
++++ b/arch/s390/kernel/nospec-branch.c
+@@ -32,6 +32,16 @@ static int __init nospec_setup_early(cha
+ }
+ early_param("nospec", nospec_setup_early);
++static int __init nospec_report(void)
++{
++      if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable)
++              pr_info("Spectre V2 mitigation: execute trampolines.\n");
++      if (__test_facility(82, S390_lowcore.alt_stfle_fac_list))
++              pr_info("Spectre V2 mitigation: limited branch prediction.\n");
++      return 0;
++}
++arch_initcall(nospec_report);
++
+ #ifdef CONFIG_EXPOLINE
+ int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
diff --git a/queue-4.16/s390-use-expoline-thunks-in-the-bpf-jit.patch b/queue-4.16/s390-use-expoline-thunks-in-the-bpf-jit.patch
new file mode 100644 (file)
index 0000000..0b087e0
--- /dev/null
@@ -0,0 +1,193 @@
+From foo@baz Wed May 23 19:22:17 CEST 2018
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Date: Wed, 23 May 2018 18:22:31 +0200
+Subject: s390: use expoline thunks in the BPF JIT
+To: stable@vger.kernel.org
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Message-ID: <1527092551-24476-16-git-send-email-schwidefsky@de.ibm.com>
+
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[ Upstream commit de5cb6eb514ebe241e3edeb290cb41deb380b81d ]
+
+The BPF JIT need safe guarding against spectre v2 in the sk_load_xxx
+assembler stubs and the indirect branches generated by the JIT itself
+need to be converted to expolines.
+
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/net/bpf_jit.S      |   16 ++++++----
+ arch/s390/net/bpf_jit_comp.c |   63 +++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 71 insertions(+), 8 deletions(-)
+
+--- a/arch/s390/net/bpf_jit.S
++++ b/arch/s390/net/bpf_jit.S
+@@ -9,6 +9,7 @@
+  */
+ #include <linux/linkage.h>
++#include <asm/nospec-insn.h>
+ #include "bpf_jit.h"
+ /*
+@@ -54,7 +55,7 @@ ENTRY(sk_load_##NAME##_pos);                                         \
+       clg     %r3,STK_OFF_HLEN(%r15); /* Offset + SIZE > hlen? */     \
+       jh      sk_load_##NAME##_slow;                                  \
+       LOAD    %r14,-SIZE(%r3,%r12);   /* Get data from skb */         \
+-      b       OFF_OK(%r6);            /* Return */                    \
++      B_EX    OFF_OK,%r6;             /* Return */                    \
+                                                                       \
+ sk_load_##NAME##_slow:;                                                       \
+       lgr     %r2,%r7;                /* Arg1 = skb pointer */        \
+@@ -64,11 +65,14 @@ sk_load_##NAME##_slow:;                                                    \
+       brasl   %r14,skb_copy_bits;     /* Get data from skb */         \
+       LOAD    %r14,STK_OFF_TMP(%r15); /* Load from temp bufffer */    \
+       ltgr    %r2,%r2;                /* Set cc to (%r2 != 0) */      \
+-      br      %r6;                    /* Return */
++      BR_EX   %r6;                    /* Return */
+ sk_load_common(word, 4, llgf) /* r14 = *(u32 *) (skb->data+offset) */
+ sk_load_common(half, 2, llgh) /* r14 = *(u16 *) (skb->data+offset) */
++      GEN_BR_THUNK %r6
++      GEN_B_THUNK OFF_OK,%r6
++
+ /*
+  * Load 1 byte from SKB (optimized version)
+  */
+@@ -80,7 +84,7 @@ ENTRY(sk_load_byte_pos)
+       clg     %r3,STK_OFF_HLEN(%r15)  # Offset >= hlen?
+       jnl     sk_load_byte_slow
+       llgc    %r14,0(%r3,%r12)        # Get byte from skb
+-      b       OFF_OK(%r6)             # Return OK
++      B_EX    OFF_OK,%r6              # Return OK
+ sk_load_byte_slow:
+       lgr     %r2,%r7                 # Arg1 = skb pointer
+@@ -90,7 +94,7 @@ sk_load_byte_slow:
+       brasl   %r14,skb_copy_bits      # Get data from skb
+       llgc    %r14,STK_OFF_TMP(%r15)  # Load result from temp buffer
+       ltgr    %r2,%r2                 # Set cc to (%r2 != 0)
+-      br      %r6                     # Return cc
++      BR_EX   %r6                     # Return cc
+ #define sk_negative_common(NAME, SIZE, LOAD)                          \
+ sk_load_##NAME##_slow_neg:;                                           \
+@@ -104,7 +108,7 @@ sk_load_##NAME##_slow_neg:;                                                \
+       jz      bpf_error;                                              \
+       LOAD    %r14,0(%r2);            /* Get data from pointer */     \
+       xr      %r3,%r3;                /* Set cc to zero */            \
+-      br      %r6;                    /* Return cc */
++      BR_EX   %r6;                    /* Return cc */
+ sk_negative_common(word, 4, llgf)
+ sk_negative_common(half, 2, llgh)
+@@ -113,4 +117,4 @@ sk_negative_common(byte, 1, llgc)
+ bpf_error:
+ # force a return 0 from jit handler
+       ltgr    %r15,%r15       # Set condition code
+-      br      %r6
++      BR_EX   %r6
+--- a/arch/s390/net/bpf_jit_comp.c
++++ b/arch/s390/net/bpf_jit_comp.c
+@@ -25,6 +25,8 @@
+ #include <linux/bpf.h>
+ #include <asm/cacheflush.h>
+ #include <asm/dis.h>
++#include <asm/facility.h>
++#include <asm/nospec-branch.h>
+ #include <asm/set_memory.h>
+ #include "bpf_jit.h"
+@@ -41,6 +43,8 @@ struct bpf_jit {
+       int base_ip;            /* Base address for literal pool */
+       int ret0_ip;            /* Address of return 0 */
+       int exit_ip;            /* Address of exit */
++      int r1_thunk_ip;        /* Address of expoline thunk for 'br %r1' */
++      int r14_thunk_ip;       /* Address of expoline thunk for 'br %r14' */
+       int tail_call_start;    /* Tail call start offset */
+       int labels[1];          /* Labels for local jumps */
+ };
+@@ -250,6 +254,19 @@ static inline void reg_set_seen(struct b
+       REG_SET_SEEN(b2);                                       \
+ })
++#define EMIT6_PCREL_RILB(op, b, target)                               \
++({                                                            \
++      int rel = (target - jit->prg) / 2;                      \
++      _EMIT6(op | reg_high(b) << 16 | rel >> 16, rel & 0xffff);       \
++      REG_SET_SEEN(b);                                        \
++})
++
++#define EMIT6_PCREL_RIL(op, target)                           \
++({                                                            \
++      int rel = (target - jit->prg) / 2;                      \
++      _EMIT6(op | rel >> 16, rel & 0xffff);                   \
++})
++
+ #define _EMIT6_IMM(op, imm)                                   \
+ ({                                                            \
+       unsigned int __imm = (imm);                             \
+@@ -469,8 +486,45 @@ static void bpf_jit_epilogue(struct bpf_
+       EMIT4(0xb9040000, REG_2, BPF_REG_0);
+       /* Restore registers */
+       save_restore_regs(jit, REGS_RESTORE, stack_depth);
++      if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) {
++              jit->r14_thunk_ip = jit->prg;
++              /* Generate __s390_indirect_jump_r14 thunk */
++              if (test_facility(35)) {
++                      /* exrl %r0,.+10 */
++                      EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10);
++              } else {
++                      /* larl %r1,.+14 */
++                      EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14);
++                      /* ex 0,0(%r1) */
++                      EMIT4_DISP(0x44000000, REG_0, REG_1, 0);
++              }
++              /* j . */
++              EMIT4_PCREL(0xa7f40000, 0);
++      }
+       /* br %r14 */
+       _EMIT2(0x07fe);
++
++      if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable &&
++          (jit->seen & SEEN_FUNC)) {
++              jit->r1_thunk_ip = jit->prg;
++              /* Generate __s390_indirect_jump_r1 thunk */
++              if (test_facility(35)) {
++                      /* exrl %r0,.+10 */
++                      EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10);
++                      /* j . */
++                      EMIT4_PCREL(0xa7f40000, 0);
++                      /* br %r1 */
++                      _EMIT2(0x07f1);
++              } else {
++                      /* larl %r1,.+14 */
++                      EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14);
++                      /* ex 0,S390_lowcore.br_r1_tampoline */
++                      EMIT4_DISP(0x44000000, REG_0, REG_0,
++                                 offsetof(struct lowcore, br_r1_trampoline));
++                      /* j . */
++                      EMIT4_PCREL(0xa7f40000, 0);
++              }
++      }
+ }
+ /*
+@@ -966,8 +1020,13 @@ static noinline int bpf_jit_insn(struct
+               /* lg %w1,<d(imm)>(%l) */
+               EMIT6_DISP_LH(0xe3000000, 0x0004, REG_W1, REG_0, REG_L,
+                             EMIT_CONST_U64(func));
+-              /* basr %r14,%w1 */
+-              EMIT2(0x0d00, REG_14, REG_W1);
++              if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) {
++                      /* brasl %r14,__s390_indirect_jump_r1 */
++                      EMIT6_PCREL_RILB(0xc0050000, REG_14, jit->r1_thunk_ip);
++              } else {
++                      /* basr %r14,%w1 */
++                      EMIT2(0x0d00, REG_14, REG_W1);
++              }
+               /* lgr %b0,%r2: load return value into %b0 */
+               EMIT4(0xb9040000, BPF_REG_0, REG_2);
+               if ((jit->seen & SEEN_SKB) &&
index 8f8fd865f0069c10e231632cd145aa5a9f6ee957..2d598167f4774fe2a2793666b1354f1e98930ab5 100644 (file)
@@ -31,3 +31,33 @@ qed-ll2-flush-isles-when-connection-is-closed.patch
 qed-fix-possibility-of-list-corruption-during-rmmod-flows.patch
 qed-fix-ll2-race-during-connection-terminate.patch
 sparc-vio-use-put_device-instead-of-kfree.patch
+ext2-fix-a-block-leak.patch
+powerpc-rfi-flush-always-enable-fallback-flush-on-pseries.patch
+powerpc-add-security-feature-flags-for-spectre-meltdown.patch
+powerpc-pseries-add-new-h_get_cpu_characteristics-flags.patch
+powerpc-pseries-set-or-clear-security-feature-flags.patch
+powerpc-powernv-set-or-clear-security-feature-flags.patch
+powerpc-64s-move-cpu_show_meltdown.patch
+powerpc-64s-enhance-the-information-in-cpu_show_meltdown.patch
+powerpc-powernv-use-the-security-flags-in-pnv_setup_rfi_flush.patch
+powerpc-pseries-use-the-security-flags-in-pseries_setup_rfi_flush.patch
+powerpc-64s-wire-up-cpu_show_spectre_v1.patch
+powerpc-64s-wire-up-cpu_show_spectre_v2.patch
+powerpc-pseries-fix-clearing-of-security-feature-flags.patch
+powerpc-move-default-security-feature-flags.patch
+powerpc-64s-add-support-for-a-store-forwarding-barrier-at-kernel-entry-exit.patch
+s390-move-nobp-parameter-functions-to-nospec-branch.c.patch
+s390-add-automatic-detection-of-the-spectre-defense.patch
+s390-report-spectre-mitigation-via-syslog.patch
+s390-add-sysfs-attributes-for-spectre.patch
+s390-add-assembler-macros-for-cpu-alternatives.patch
+s390-correct-nospec-auto-detection-init-order.patch
+s390-correct-module-section-names-for-expoline-code-revert.patch
+s390-move-expoline-assembler-macros-to-a-header.patch
+s390-crc32-vx-use-expoline-for-indirect-branches.patch
+s390-lib-use-expoline-for-indirect-branches.patch
+s390-ftrace-use-expoline-for-indirect-branches.patch
+s390-kernel-use-expoline-for-indirect-branches.patch
+s390-move-spectre-sysfs-attribute-code.patch
+s390-extend-expoline-to-bc-instructions.patch
+s390-use-expoline-thunks-in-the-bpf-jit.patch