@@ -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__ */