All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] powerpc/kernel: Fix L1D_SIZE to a non-zero value on missing cache nodes
@ 2018-01-17 19:03 Madhavan Srinivasan
  0 siblings, 0 replies; only message in thread
From: Madhavan Srinivasan @ 2018-01-17 19:03 UTC (permalink / raw)
  To: mpe; +Cc: linuxppc-dev, Madhavan Srinivasan

parse_cache_info() parse device tree to detect various [i/d] cache properties.
But if no cache nodes found in device tree, these properties are set to zero
as default in init_cache_info().

Having a zero value could cause a infinite loop in rfi_flush_callback() since
l1d_size is used to determine the lid_flush_set parameter which is used as
the upper bounce in L1D cache flush loop. So default the l1d_size to 64K if
it is zero.

Fixes: aa8a5e0062ac9 ('powerpc/64s: Add support for RFI flush of L1-D cache')
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/setup.h |  2 ++
 arch/powerpc/kernel/setup_64.c   | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 469b7fdc9be4..12954bf2d3fe 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -41,6 +41,8 @@ static inline void pseries_little_endian_exceptions(void) {}
 
 void rfi_flush_enable(bool enable);
 
+#define DEFAULT_L1D_SIZE	(1024 * 64)
+
 /* These are bit flags */
 enum l1d_flush_type {
 	L1D_FLUSH_NONE		= 0x1,
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 491be4179ddd..7a3077a2cd5c 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -856,6 +856,22 @@ static void init_fallback_flush(void)
 	int cpu;
 
 	l1d_size = ppc64_caches.l1d.size;
+
+	/*
+	 * If there is no cache node in cpus/ device tree,
+	 * l1d_size could be zero. This in turn make l1d_flush_sets as
+	 * zero, which will be an issue in RFI_FLUSH_CALLBACK.
+	 *
+	 * RFI_FLUSH_CALLBACK use the l1d_flush_sets value as upper bounce
+	 * (loaded in CTR) and loop with a `bdnz` instruction. If the CTR
+	 * happen to zero, instruction (as per definition) will decrement
+	 * CTR first and then compare. So we end up in a really big
+	 * loop (becos of negative value in CTR). Avoid this by defaulting
+	 * to a sane value (64kb).
+	 */
+	if (!l1d_size)
+		l1d_size = DEFAULT_L1D_SIZE;
+
 	limit = min(safe_stack_limit(), ppc64_rma_size);
 
 	/*
-- 
2.7.4

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2018-01-17 19:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-17 19:03 [PATCH] powerpc/kernel: Fix L1D_SIZE to a non-zero value on missing cache nodes Madhavan Srinivasan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.