[PATCH 4/4] powerpc: Add vm debug code to catch errors

Aneesh Kumar K.V aneesh.kumar at linux.vnet.ibm.com
Thu Feb 14 19:36:23 EST 2013


From: "Aneesh Kumar K.V" <aneesh.kumar at linux.vnet.ibm.com>

We need to make sure that we don't have higher bits of kernel effective
address set. That would result in multiple kernel segments having same
proto vsid. Add debug code to make sure we capture this.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/mmu-hash64.h |   49 +++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 0e08252..3e297ea 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -22,6 +22,13 @@
  */
 #include <asm/pgtable-ppc64.h>
 
+#ifdef CONFIG_DEBUG_VM
+#ifndef __ASSEMBLY__
+#include <asm/udbg.h>
+#include <asm/bug.h>
+#endif
+#endif
+
 /*
  * Segment table
  */
@@ -522,11 +529,32 @@ static inline int user_segment_size(unsigned long addr)
 static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
 				     int ssize)
 {
-	if (ssize == MMU_SEGSIZE_256M)
-		return vsid_scramble((context << USER_ESID_BITS)
-				     | (ea >> SID_SHIFT), 256M);
-	return vsid_scramble((context << USER_ESID_BITS_1T)
-			     | (ea >> SID_SHIFT_1T), 1T);
+	if (ssize == MMU_SEGSIZE_256M) {
+		context = context << USER_ESID_BITS;
+		ea = ea >> SID_SHIFT;
+#ifdef CONFIG_DEBUG_VM
+		/*
+		 * context and ea should not overlap.
+		 */
+		if (context & ea) {
+			udbg_printf("Overlapping bits %lx %lx\n", context, ea);
+			WARN_ON(1);
+		}
+#endif
+		return vsid_scramble(context | ea, 256M);
+	}
+	context = context << USER_ESID_BITS_1T;
+	ea = ea >> SID_SHIFT_1T;
+#ifdef CONFIG_DEBUG_VM
+	/*
+	 * context and ea should not overlap.
+	 */
+	if (context & ea) {
+		udbg_printf("Overlapping bits for 1T %lx %lx\n", context, ea);
+		WARN_ON(1);
+	}
+#endif
+	return vsid_scramble(context | ea, 1T);
 }
 
 /*
@@ -540,11 +568,20 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
  */
 static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
 {
+	unsigned int c_index;
 	unsigned long context;
 	/*
 	 * kernel take the top 4 context from the available range
 	 */
-	context = (MAX_CONTEXT - 4) +  ((ea >> 60) - 0xc);
+	c_index =   ((ea >> 60) - 0xc);
+	context = (MAX_CONTEXT - 4) + c_index;
+#ifdef CONFIG_DEBUG_VM
+	/*
+	 * Drop the c_index related bits from ea, so we get
+	 * non overlapping context and ea.
+	 */
+	ea = ea - ((0xcUL + c_index) << 60);
+#endif
 	return get_vsid(context, ea, ssize);
 }
 #endif /* __ASSEMBLY__ */
-- 
1.7.10



More information about the Linuxppc-dev mailing list