diff mbox series

[SRU,Xenial,2/2] UBUNTU: SAUCE: rfi-flush: Make it possible to call setup_rfi_flush() again

Message ID 20180530093539.11917-3-juergh@canonical.com
State New
Headers show
Series rfi-flush: Switch to new linear fallback flush (LP #1744173) | expand

Commit Message

Juerg Haefliger May 30, 2018, 9:35 a.m. UTC
From: Michael Ellerman <mpe@ellerman.id.au>

BugLink: https://bugs.launchpad.net/bugs/1744173

For PowerVM migration we want to be able to call setup_rfi_flush()
again after we've migrated the partition.

To support that we need to check that we're not trying to allocate the
fallback flush area after memblock has gone away. If so we just fail,
we don't support migrating from a patched to an unpatched machine. Or
we do support it, but there will be no RFI flush enabled on the
destination.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Breno Leitao <brenohl@br.ibm.com>
Signed-off-by: Juerg Haefliger <juergh@canonical.com>
---
 arch/powerpc/kernel/setup_64.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 70dfe49868e1..efc6371d62b3 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -961,14 +961,22 @@  void setup_stf_barrier(void)
 		stf_barrier_enable(enable);
 }
 
-static void init_fallback_flush(void)
+static bool init_fallback_flush(void)
 {
 	u64 l1d_size, limit;
 	int cpu;
 
 	/* Only allocate the fallback flush area once (at boot time). */
 	if (l1d_flush_fallback_area)
-		return;
+		return true;
+
+	/*
+	 * Once the slab allocator is up it's too late to allocate the fallback
+	 * flush area, so return an error. This could happen if we migrated from
+	 * a patched machine to an unpatched machine.
+	 */
+	if (slab_is_available())
+		return false;
 
 	l1d_size = ppc64_caches.dsize;
 	limit = min(safe_stack_limit(), ppc64_rma_size);
@@ -985,13 +993,19 @@  static void init_fallback_flush(void)
 		paca[cpu].rfi_flush_fallback_area = l1d_flush_fallback_area;
 		paca[cpu].l1d_flush_size = l1d_size;
 	}
+
+	return true;
 }
 
 void setup_rfi_flush(enum l1d_flush_type types, bool enable)
 {
 	if (types & L1D_FLUSH_FALLBACK) {
-		pr_info("rfi-flush: fallback displacement flush available\n");
-		init_fallback_flush();
+		if (init_fallback_flush())
+			pr_info("rfi-flush: Using fallback displacement flush\n");
+		else {
+			pr_warn("rfi-flush: Error unable to use fallback displacement flush!\n");
+			types &= ~L1D_FLUSH_FALLBACK;
+		}
 	}
 
 	if (types & L1D_FLUSH_ORI)