[SRU][Bionic][PATCH 1/2] Revert "powerpc/64s: Add support for a store forwarding barrier at kernel entry/exit"

Joseph Salisbury joseph.salisbury at canonical.com
Fri May 25 22:39:56 UTC 2018


BugLink: http://bugs.launchpad.net/bugs/1773162

IBM believes the backport of this patch was done incorrectly.  Revert
this commit, and a new version of the commit is being set in this patch
set.

This reverts commit 06f7e3d39f2fa4f648d94a51d809b10f98399f91.

Signed-off-by: Joseph Salisbury <joseph.salisbury at canonical.com>
---
 arch/powerpc/include/asm/exception-64s.h  |  29 --------
 arch/powerpc/include/asm/feature-fixups.h |  19 -----
 arch/powerpc/include/asm/setup.h          |  12 +--
 arch/powerpc/kernel/exceptions-64s.S      |  19 +----
 arch/powerpc/kernel/setup_64.c            | 119 +-----------------------------
 arch/powerpc/kernel/vmlinux.lds.S         |  14 ----
 arch/powerpc/lib/feature-fixups.c         | 105 --------------------------
 arch/powerpc/platforms/powernv/setup.c    |   1 -
 arch/powerpc/platforms/pseries/setup.c    |   1 -
 9 files changed, 8 insertions(+), 311 deletions(-)

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index d89411a..7197b17 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -74,27 +74,6 @@
  */
 #define EX_R3		EX_DAR
 
-#define STF_ENTRY_BARRIER_SLOT						\
-	STF_ENTRY_BARRIER_FIXUP_SECTION;				\
-	mflr	r10;							\
-	bl	stf_barrier_fallback;					\
-	mtlr	r10
-
-#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
  *
@@ -111,19 +90,16 @@
 	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
@@ -132,25 +108,21 @@
 	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
@@ -282,7 +254,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
 #define __EXCEPTION_PROLOG_1(area, extra, vec)				\
 	OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR);		\
 	OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);		\
-	INTERRUPT_TO_KERNEL;						\
 	SAVE_CTR(r10, area);						\
 	mfcr	r9;							\
 	extra(vec);							\
diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h
index a9b64df..1e82eb3 100644
--- a/arch/powerpc/include/asm/feature-fixups.h
+++ b/arch/powerpc/include/asm/feature-fixups.h
@@ -187,22 +187,6 @@ 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";		\
@@ -215,9 +199,6 @@ label##3:					       	\
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 
-extern long stf_barrier_fallback;
-extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup;
-extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
 extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
 
 void apply_feature_fixups(void);
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 39baa94..bbcdf929 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -39,17 +39,9 @@ static inline void pseries_big_endian_exceptions(void) {}
 static inline void pseries_little_endian_exceptions(void) {}
 #endif /* CONFIG_PPC_PSERIES */
 
-/* These are bit flags */
-enum stf_barrier_type {
-	STF_BARRIER_NONE	= 0x1,
-	STF_BARRIER_FALLBACK	= 0x2,
-	STF_BARRIER_EIEIO	= 0x4,
-	STF_BARRIER_SYNC_ORI	= 0x8,
-};
-
-void setup_stf_barrier(void);
-void do_stf_barrier_fixups(enum stf_barrier_type types);
+void rfi_flush_enable(bool enable);
 
+/* These are bit flags */
 enum l1d_flush_type {
 	L1D_FLUSH_NONE		= 0x1,
 	L1D_FLUSH_FALLBACK	= 0x2,
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 9a853e6..efde0d6 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -882,7 +882,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
 #endif
 
 
-EXC_REAL_OOL_MASKABLE(decrementer, 0x900, 0x80)
+EXC_REAL_MASKABLE(decrementer, 0x900, 0x80)
 EXC_VIRT_MASKABLE(decrementer, 0x4900, 0x80, 0x900)
 TRAMP_KVM(PACA_EXGEN, 0x900)
 EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt)
@@ -958,7 +958,6 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
 	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;
@@ -967,8 +966,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
 #define SYSCALL_KVMTEST							\
 	HMT_MEDIUM;							\
 	mr	r9,r13;							\
-	GET_PACA(r13);							\
-	INTERRUPT_TO_KERNEL;
+	GET_PACA(r13);
 #endif
 	
 #define LOAD_SYSCALL_HANDLER(reg)					\
@@ -1506,19 +1504,6 @@ 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);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 288389e..b8e2b5c 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -69,7 +69,6 @@
 #include <asm/livepatch.h>
 #include <asm/opal.h>
 #include <asm/cputhreads.h>
-#include <asm/security_features.h>
 
 #include "setup.h"
 
@@ -805,48 +804,11 @@ static int __init disable_hardlockup_detector(void)
 early_initcall(disable_hardlockup_detector);
 
 #ifdef CONFIG_PPC_BOOK3S_64
-static enum stf_barrier_type stf_enabled_flush_types;
-static bool no_stf_barrier;
-bool stf_barrier;
-
-static enum l1d_flush_type rfi_enabled_flush_types;
+static enum l1d_flush_type enabled_flush_types;
 static void *l1d_flush_fallback_area;
 static bool no_rfi_flush;
 bool rfi_flush;
 
-static int __init handle_no_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, "off", 3) == 0) {
-		handle_no_stf_barrier(NULL);
-		return 0;
-	} else if (strncmp(p, "auto", 5) == 0 || strncmp(p, "on", 2) == 0 )
-		/* Until firmware tells us, we have the barrier with auto */
-		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 int __init handle_no_rfi_flush(char *p)
 {
 	pr_info("rfi-flush: disabled on command line.");
@@ -875,21 +837,10 @@ static void do_nothing(void *unused)
 	 */
 }
 
-static void stf_barrier_enable(bool enable)
-{
-	if (enable) {
-		do_stf_barrier_fixups(stf_enabled_flush_types);
-		on_each_cpu(do_nothing, NULL, 1);
-	} else
-		do_stf_barrier_fixups(STF_BARRIER_NONE);
-
-	stf_barrier = enable;
-}
-
-static void rfi_flush_enable(bool enable)
+void rfi_flush_enable(bool enable)
 {
 	if (enable) {
-		do_rfi_flush_fixups(rfi_enabled_flush_types);
+		do_rfi_flush_fixups(enabled_flush_types);
 		on_each_cpu(do_nothing, NULL, 1);
 	} else
 		do_rfi_flush_fixups(L1D_FLUSH_NONE);
@@ -897,41 +848,6 @@ static void rfi_flush_enable(bool enable)
 	rfi_flush = 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);
-}
-
 static void init_fallback_flush(void)
 {
 	u64 l1d_size, limit;
@@ -982,39 +898,13 @@ void setup_rfi_flush(enum l1d_flush_type types, bool enable)
 	if (types & L1D_FLUSH_MTTRIG)
 		pr_info("rfi-flush: mttrig type flush available\n");
 
-	rfi_enabled_flush_types = types;
+	enabled_flush_types = types;
 
 	if (!no_rfi_flush)
 		rfi_flush_enable(enable);
 }
 
 #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 int rfi_flush_set(void *data, u64 val)
 {
 	bool enable;
@@ -1044,7 +934,6 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_rfi_flush, rfi_flush_get, rfi_flush_set, "%llu\n");
 static __init int rfi_flush_debugfs_init(void)
 {
 	debugfs_create_file("rfi_flush", 0600, powerpc_debugfs_root, NULL, &fops_rfi_flush);
-	debugfs_create_file("stf_barrier", 0600, powerpc_debugfs_root, NULL, &fops_stf_barrier);
 	return 0;
 }
 device_initcall(rfi_flush_debugfs_init);
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index c89ffb88..307843d 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -134,20 +134,6 @@ 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)
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index c26866c..acfc81e 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -117,111 +117,6 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
 }
 
 #ifdef CONFIG_PPC_BOOK3S_64
-void do_stf_entry_barrier_fixups(enum stf_barrier_type types)
-{
-	unsigned int instrs[3], *dest;
-	long *start, *end;
-	int i;
-
-	start = PTRRELOC(&__start___stf_entry_barrier_fixup),
-	end = PTRRELOC(&__stop___stf_entry_barrier_fixup);
-
-	instrs[0] = 0x60000000; /* nop */
-	instrs[1] = 0x60000000; /* nop */
-	instrs[2] = 0x60000000; /* nop */
-
-	i = 0;
-	if (types & STF_BARRIER_FALLBACK) {
-		instrs[i++] = 0x7d4802a6; /* mflr r10		*/
-		instrs[i++] = 0x60000000; /* branch patched below */
-		instrs[i++] = 0x7d4803a6; /* mtlr r10		*/
-	} else if (types & STF_BARRIER_EIEIO) {
-		instrs[i++] = 0x7e0006ac; /* eieio + bit 6 hint */
-	} else if (types & STF_BARRIER_SYNC_ORI) {
-		instrs[i++] = 0x7c0004ac; /* hwsync		*/
-		instrs[i++] = 0xe94d0000; /* ld r10,0(r13)	*/
-		instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
-	}
-
-	for (i = 0; start < end; start++, i++) {
-		dest = (void *)start + *start;
-
-		pr_devel("patching dest %lx\n", (unsigned long)dest);
-
-		patch_instruction(dest, instrs[0]);
-
-		if (types & STF_BARRIER_FALLBACK)
-			patch_branch(dest + 1, (unsigned long)&stf_barrier_fallback,
-				     BRANCH_SET_LINK);
-		else
-			patch_instruction(dest + 1, instrs[1]);
-
-		patch_instruction(dest + 2, instrs[2]);
-	}
-
-	printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s barrier)\n", i,
-		(types == STF_BARRIER_NONE)                  ? "no" :
-		(types == STF_BARRIER_FALLBACK)              ? "fallback" :
-		(types == STF_BARRIER_EIEIO)                 ? "eieio" :
-		(types == (STF_BARRIER_SYNC_ORI))            ? "hwsync"
-		                                           : "unknown");
-}
-
-void do_stf_exit_barrier_fixups(enum stf_barrier_type types)
-{
-	unsigned int instrs[6], *dest;
-	long *start, *end;
-	int i;
-
-	start = PTRRELOC(&__start___stf_exit_barrier_fixup),
-	end = PTRRELOC(&__stop___stf_exit_barrier_fixup);
-
-	instrs[0] = 0x60000000; /* nop */
-	instrs[1] = 0x60000000; /* nop */
-	instrs[2] = 0x60000000; /* nop */
-	instrs[3] = 0x60000000; /* nop */
-	instrs[4] = 0x60000000; /* nop */
-	instrs[5] = 0x60000000; /* nop */
-
-	i = 0;
-	if (types & STF_BARRIER_FALLBACK || types & STF_BARRIER_SYNC_ORI) {
-		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 */
-		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;
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 62ecc66..7de050a 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -130,7 +130,6 @@ static void __init pnv_setup_arch(void)
 {
 	set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
 
-	setup_stf_barrier();
 	pnv_setup_rfi_flush();
 
 	/* Initialize SMP */
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 8492bc2..3cb12d2 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -543,7 +543,6 @@ static void __init pSeries_setup_arch(void)
 	fwnmi_init();
 
 	pseries_setup_rfi_flush();
-	setup_stf_barrier();
 
 	/* By default, only probe PCI (can be overridden by rtas_pci) */
 	pci_add_flags(PCI_PROBE_ONLY);
-- 
2.7.4





More information about the kernel-team mailing list