From: Greg Kroah-Hartman Date: Wed, 23 May 2018 17:23:11 +0000 (+0200) Subject: 4.16-stable patches X-Git-Tag: v3.18.110~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d046cfbf0c920a0d0a078e9ea2f25fc74483cf30;p=thirdparty%2Fkernel%2Fstable-queue.git 4.16-stable patches 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 --- 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 index 00000000000..bd5bddc83d4 --- /dev/null +++ b/queue-4.16/ext2-fix-a-block-leak.patch @@ -0,0 +1,49 @@ +From 5aa1437d2d9a068c0334bd7c9dafa8ec4f97f13b Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Thu, 17 May 2018 17:18:30 -0400 +Subject: ext2: fix a block leak + +From: Al Viro + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0bef878ef0f --- /dev/null +++ b/queue-4.16/powerpc-64s-add-support-for-a-store-forwarding-barrier-at-kernel-entry-exit.patch @@ -0,0 +1,575 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Mauricio Faria de Oliveira +Signed-off-by: Michael Neuling +Signed-off-by: Michal Suchánek +Signed-off-by: Michael Ellerman +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + 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 + ++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 + #include + ++#include + #include + + +@@ -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 + #include + #include ++#include + #include + + 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 index 00000000000..adffb540813 --- /dev/null +++ b/queue-4.16/powerpc-64s-enhance-the-information-in-cpu_show_meltdown.patch @@ -0,0 +1,78 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include ++#include + + #include + +@@ -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 index 00000000000..5c22a895c7d --- /dev/null +++ b/queue-4.16/powerpc-64s-move-cpu_show_meltdown.patch @@ -0,0 +1,62 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++#include ++ + #include + + +@@ -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 index 00000000000..b6d120d0786 --- /dev/null +++ b/queue-4.16/powerpc-64s-wire-up-cpu_show_spectre_v1.patch @@ -0,0 +1,40 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..63003d0de1a --- /dev/null +++ b/queue-4.16/powerpc-64s-wire-up-cpu_show_spectre_v2.patch @@ -0,0 +1,73 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..7f7c3cd2fde --- /dev/null +++ b/queue-4.16/powerpc-add-security-feature-flags-for-spectre-meltdown.patch @@ -0,0 +1,132 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++#include ++ ++ ++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 index 00000000000..bf4e39f6b76 --- /dev/null +++ b/queue-4.16/powerpc-move-default-security-feature-flags.patch @@ -0,0 +1,56 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman +--- + 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 + + +-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 index 00000000000..bcea98f6759 --- /dev/null +++ b/queue-4.16/powerpc-powernv-set-or-clear-security-feature-flags.patch @@ -0,0 +1,97 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + #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 index 00000000000..22d9a20e50c --- /dev/null +++ b/queue-4.16/powerpc-powernv-use-the-security-flags-in-pnv_setup_rfi_flush.patch @@ -0,0 +1,96 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..8e88367d0e6 --- /dev/null +++ b/queue-4.16/powerpc-pseries-add-new-h_get_cpu_characteristics-flags.patch @@ -0,0 +1,33 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +commit c4bc36628d7f8b664657d8bd6ad1c44c177880b7 upstream. + +Add some additional values which have been defined for the +H_GET_CPU_CHARACTERISTICS hypercall. + +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..2b583142717 --- /dev/null +++ b/queue-4.16/powerpc-pseries-fix-clearing-of-security-feature-flags.patch @@ -0,0 +1,81 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Fixes: f636c14790ea ("powerpc/pseries: Set or clear security feature flags") +Signed-off-by: Mauricio Faria de Oliveira +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..2009c715297 --- /dev/null +++ b/queue-4.16/powerpc-pseries-set-or-clear-security-feature-flags.patch @@ -0,0 +1,94 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + #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 index 00000000000..8c9c3148306 --- /dev/null +++ b/queue-4.16/powerpc-pseries-use-the-security-flags-in-pseries_setup_rfi_flush.patch @@ -0,0 +1,67 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..3ce2900826f --- /dev/null +++ b/queue-4.16/powerpc-rfi-flush-always-enable-fallback-flush-on-pseries.patch @@ -0,0 +1,54 @@ +From foo@baz Wed May 23 19:18:22 CEST 2018 +From: Michael Ellerman +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 + +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 +Signed-off-by: Mauricio Faria de Oliveira +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..e40b4525dd1 --- /dev/null +++ b/queue-4.16/s390-add-assembler-macros-for-cpu-alternatives.patch @@ -0,0 +1,147 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-6-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 "", \ + "", \ + "" +and + + ALTERNATIVE_2 "", \ + "", \ + "", + "", \ + "" + +Reviewed-by: Vasily Gorbik +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..039e8f5f4b0 --- /dev/null +++ b/queue-4.16/s390-add-automatic-detection-of-the-spectre-defense.patch @@ -0,0 +1,234 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-3-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + +-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 + #include + #include ++#include + + #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 index 00000000000..6d439858a3e --- /dev/null +++ b/queue-4.16/s390-add-sysfs-attributes-for-spectre.patch @@ -0,0 +1,67 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +Date: Wed, 23 May 2018 18:22:20 +0200 +Subject: s390: add sysfs attributes for spectre +To: stable@vger.kernel.org +Cc: Martin Schwidefsky +Message-ID: <1527092551-24476-5-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++#include + #include + + 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 index 00000000000..e1d480ee290 --- /dev/null +++ b/queue-4.16/s390-correct-module-section-names-for-expoline-code-revert.patch @@ -0,0 +1,46 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-8-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..25346db1985 --- /dev/null +++ b/queue-4.16/s390-correct-nospec-auto-detection-init-order.patch @@ -0,0 +1,86 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-7-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..73942c6b15a --- /dev/null +++ b/queue-4.16/s390-crc32-vx-use-expoline-for-indirect-branches.patch @@ -0,0 +1,79 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-10-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++#include + #include + + /* 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 ++#include + #include + + /* 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 index 00000000000..e228908a7d5 --- /dev/null +++ b/queue-4.16/s390-extend-expoline-to-bc-instructions.patch @@ -0,0 +1,182 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +Date: Wed, 23 May 2018 18:22:30 +0200 +Subject: s390: extend expoline to BC instructions +To: stable@vger.kernel.org +Cc: Martin Schwidefsky +Message-ID: <1527092551-24476-15-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ Upstream commit 6deaa3bbca804b2a3627fd685f75de64da7be535 ] + +The BPF JIT uses a 'b (%r)' 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..fcd9d7b2eac --- /dev/null +++ b/queue-4.16/s390-ftrace-use-expoline-for-indirect-branches.patch @@ -0,0 +1,147 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-12-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++#include + #include + + #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 + #include + #include ++#include + #include + #include + ++ 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 index 00000000000..42fcca7a26e --- /dev/null +++ b/queue-4.16/s390-kernel-use-expoline-for-indirect-branches.patch @@ -0,0 +1,167 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-13-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include ++#include + #include + #include + ++ 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 + #include ++#include + #include + ++ 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 + #include + #include ++#include + #include + + /* +@@ -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 index 00000000000..eea67f93d9e --- /dev/null +++ b/queue-4.16/s390-lib-use-expoline-for-indirect-branches.patch @@ -0,0 +1,98 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-11-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include ++#include ++ ++ 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 index 00000000000..29b916c0d48 --- /dev/null +++ b/queue-4.16/s390-move-expoline-assembler-macros-to-a-header.patch @@ -0,0 +1,412 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-9-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++ ++#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 + #include + #include ++#include + + __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 index 00000000000..97c3f6494b1 --- /dev/null +++ b/queue-4.16/s390-move-nobp-parameter-functions-to-nospec-branch.c.patch @@ -0,0 +1,111 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-2-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + ++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 index 00000000000..2eacb00b4b5 --- /dev/null +++ b/queue-4.16/s390-move-spectre-sysfs-attribute-code.patch @@ -0,0 +1,92 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +Date: Wed, 23 May 2018 18:22:29 +0200 +Subject: s390: move spectre sysfs attribute code +To: stable@vger.kernel.org +Cc: Martin Schwidefsky +Message-ID: <1527092551-24476-14-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++#include ++#include ++#include ++ ++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 index 00000000000..8bc13315f27 --- /dev/null +++ b/queue-4.16/s390-report-spectre-mitigation-via-syslog.patch @@ -0,0 +1,42 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +Date: Wed, 23 May 2018 18:22:19 +0200 +Subject: s390: report spectre mitigation via syslog +To: stable@vger.kernel.org +Cc: Martin Schwidefsky +Message-ID: <1527092551-24476-4-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..0b087e026a4 --- /dev/null +++ b/queue-4.16/s390-use-expoline-thunks-in-the-bpf-jit.patch @@ -0,0 +1,193 @@ +From foo@baz Wed May 23 19:22:17 CEST 2018 +From: Martin Schwidefsky +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 +Message-ID: <1527092551-24476-16-git-send-email-schwidefsky@de.ibm.com> + +From: Martin Schwidefsky + +[ 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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 ++#include + #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 + #include + #include ++#include ++#include + #include + #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,(%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) && diff --git a/queue-4.16/series b/queue-4.16/series index 8f8fd865f00..2d598167f47 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -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