linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] powerpc: Make VSID_BITS* dependency explicit
       [not found] <a>
@ 2013-02-14  8:36 ` Aneesh Kumar K.V
  2013-02-14  8:36   ` [PATCH 2/4] powerpc: Update kernel VSID range Aneesh Kumar K.V
                     ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Aneesh Kumar K.V @ 2013-02-14  8:36 UTC (permalink / raw)
  To: benh, paulus, phileas-fogg, geoff; +Cc: linuxppc-dev, Aneesh Kumar K.V

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

VSID_BITS and VSID_BITS_1T depends on the context bits  and user esid
bits. Make the dependency explicit

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

diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 2fdb47a..5f8c2bd 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -381,21 +381,22 @@ extern void slb_set_size(u16 size);
  * hash collisions.
  */
 
+#define CONTEXT_BITS		19
+#define USER_ESID_BITS		18
+#define USER_ESID_BITS_1T	6
+
 /*
  * This should be computed such that protovosid * vsid_mulitplier
  * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
  */
 #define VSID_MULTIPLIER_256M	ASM_CONST(12538073)	/* 24-bit prime */
-#define VSID_BITS_256M		38
+#define VSID_BITS_256M		(CONTEXT_BITS + USER_ESID_BITS + 1)
 #define VSID_MODULUS_256M	((1UL<<VSID_BITS_256M)-1)
 
 #define VSID_MULTIPLIER_1T	ASM_CONST(12538073)	/* 24-bit prime */
-#define VSID_BITS_1T		26
+#define VSID_BITS_1T		(CONTEXT_BITS + USER_ESID_BITS_1T + 1)
 #define VSID_MODULUS_1T		((1UL<<VSID_BITS_1T)-1)
 
-#define CONTEXT_BITS		19
-#define USER_ESID_BITS		18
-#define USER_ESID_BITS_1T	6
 
 #define USER_VSID_RANGE	(1UL << (USER_ESID_BITS + SID_SHIFT))
 
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] powerpc: Update kernel VSID range
  2013-02-14  8:36 ` [PATCH 1/4] powerpc: Make VSID_BITS* dependency explicit Aneesh Kumar K.V
@ 2013-02-14  8:36   ` Aneesh Kumar K.V
  2013-02-14 17:21     ` Aneesh Kumar K.V
  2013-02-15  4:42     ` Paul Mackerras
  2013-02-14  8:36   ` [PATCH 3/4] powerpc: Don't update r10 early in the call Aneesh Kumar K.V
  2013-02-14  8:36   ` [PATCH 4/4] powerpc: Add vm debug code to catch errors Aneesh Kumar K.V
  2 siblings, 2 replies; 7+ messages in thread
From: Aneesh Kumar K.V @ 2013-02-14  8:36 UTC (permalink / raw)
  To: benh, paulus, phileas-fogg, geoff; +Cc: linuxppc-dev, Aneesh Kumar K.V

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

This patch change the kernel VSID range so that we limit VSID_BITS to 37.
This enables us to support 64TB with 65 bit VA (37+28). Without this patch
we have boot hangs on platforms that only support 65 bit VA.

With this patch we now have proto vsid generated as below:

We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
from mmu context id and effective segment id of the address.

For user processes max context id is limited to ((1ul << 19) - 6)
for kernel space, we use the top 4 context ids to map address as below
0x7fffb -  [ 0xc000000000000000 - 0xcfffffffffffffff ]
0x7fffc -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
0x7fffd -  [ 0xe000000000000000 - 0xefffffffffffffff ]
0x7fffe -  [ 0xf000000000000000 - 0xffffffffffffffff ]

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/mmu-hash64.h |  101 ++++++++++++++-------------------
 arch/powerpc/kernel/exceptions-64s.S  |   17 ++++--
 arch/powerpc/mm/mmu_context_hash64.c  |   11 +---
 arch/powerpc/mm/slb_low.S             |   22 +++++--
 4 files changed, 74 insertions(+), 77 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 5f8c2bd..0e08252 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -343,17 +343,15 @@ extern void slb_set_size(u16 size);
 /*
  * VSID allocation (256MB segment)
  *
- * We first generate a 38-bit "proto-VSID".  For kernel addresses this
- * is equal to the ESID | 1 << 37, for user addresses it is:
- *	(context << USER_ESID_BITS) | (esid & ((1U << USER_ESID_BITS) - 1)
+ * We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
+ * from mmu context id and effective segment id of the address.
  *
- * This splits the proto-VSID into the below range
- *  0 - (2^(CONTEXT_BITS + USER_ESID_BITS) - 1) : User proto-VSID range
- *  2^(CONTEXT_BITS + USER_ESID_BITS) - 2^(VSID_BITS) : Kernel proto-VSID range
- *
- * We also have CONTEXT_BITS + USER_ESID_BITS = VSID_BITS - 1
- * That is, we assign half of the space to user processes and half
- * to the kernel.
+ * For user processes max context id is limited to ((1ul << 19) - 6)
+ * for kernel space, we use the top 4 context ids to map address as below
+ * 0x7fffb -  [ 0xc000000000000000 - 0xcfffffffffffffff ]
+ * 0x7fffc -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
+ * 0x7fffd -  [ 0xe000000000000000 - 0xefffffffffffffff ]
+ * 0x7fffe -  [ 0xf000000000000000 - 0xffffffffffffffff ]
  *
  * The proto-VSIDs are then scrambled into real VSIDs with the
  * multiplicative hash:
@@ -363,22 +361,9 @@ extern void slb_set_size(u16 size);
  * VSID_MULTIPLIER is prime, so in particular it is
  * co-prime to VSID_MODULUS, making this a 1:1 scrambling function.
  * Because the modulus is 2^n-1 we can compute it efficiently without
- * a divide or extra multiply (see below).
- *
- * This scheme has several advantages over older methods:
- *
- *	- We have VSIDs allocated for every kernel address
- * (i.e. everything above 0xC000000000000000), except the very top
- * segment, which simplifies several things.
- *
- *	- We allow for USER_ESID_BITS significant bits of ESID and
- * CONTEXT_BITS  bits of context for user addresses.
- *  i.e. 64T (46 bits) of address space for up to half a million contexts.
- *
- *	- The scramble function gives robust scattering in the hash
- * table (at least based on some initial results).  The previous
- * method was more susceptible to pathological cases giving excessive
- * hash collisions.
+ * a divide or extra multiply (see below). The scramble function gives
+ * robust scattering in the hash * table (at least based on some initial
+ * results).
  */
 
 #define CONTEXT_BITS		19
@@ -386,15 +371,25 @@ extern void slb_set_size(u16 size);
 #define USER_ESID_BITS_1T	6
 
 /*
+ * 256MB segment
+ * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
+ * available for user + kernel mapping. The top 4 contexts are used for
+ * kernel mapping. Each segment contains 2^28 bytes. Each
+ * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
+ * (19 == 37 + 28 - 46).
+ */
+#define MAX_CONTEXT	((ASM_CONST(1) << CONTEXT_BITS) - 1)
+
+/*
  * This should be computed such that protovosid * vsid_mulitplier
  * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus
  */
 #define VSID_MULTIPLIER_256M	ASM_CONST(12538073)	/* 24-bit prime */
-#define VSID_BITS_256M		(CONTEXT_BITS + USER_ESID_BITS + 1)
+#define VSID_BITS_256M		(CONTEXT_BITS + USER_ESID_BITS)
 #define VSID_MODULUS_256M	((1UL<<VSID_BITS_256M)-1)
 
 #define VSID_MULTIPLIER_1T	ASM_CONST(12538073)	/* 24-bit prime */
-#define VSID_BITS_1T		(CONTEXT_BITS + USER_ESID_BITS_1T + 1)
+#define VSID_BITS_1T		(CONTEXT_BITS + USER_ESID_BITS_1T)
 #define VSID_MODULUS_1T		((1UL<<VSID_BITS_1T)-1)
 
 
@@ -422,7 +417,8 @@ extern void slb_set_size(u16 size);
 	srdi	rx,rt,VSID_BITS_##size;					\
 	clrldi	rt,rt,(64-VSID_BITS_##size);				\
 	add	rt,rt,rx;		/* add high and low bits */	\
-	/* Now, r3 == VSID (mod 2^36-1), and lies between 0 and		\
+	/* NOTE: explanation based on VSID_BITS_##size = 36		\
+	 * Now, r3 == VSID (mod 2^36-1), and lies between 0 and		\
 	 * 2^36-1+2^28-1.  That in particular means that if r3 >=	\
 	 * 2^36-1, then r3+1 has the 2^36 bit set.  So, if r3+1 has	\
 	 * the bit clear, r3 already has the answer we want, if it	\
@@ -514,34 +510,6 @@ typedef struct {
 	})
 #endif /* 1 */
 
-/*
- * This is only valid for addresses >= PAGE_OFFSET
- * The proto-VSID space is divided into two class
- * User:   0 to 2^(CONTEXT_BITS + USER_ESID_BITS) -1
- * kernel: 2^(CONTEXT_BITS + USER_ESID_BITS) to 2^(VSID_BITS) - 1
- *
- * With KERNEL_START at 0xc000000000000000, the proto vsid for
- * the kernel ends up with 0xc00000000 (36 bits). With 64TB
- * support we need to have kernel proto-VSID in the
- * [2^37 to 2^38 - 1] range due to the increased USER_ESID_BITS.
- */
-static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
-{
-	unsigned long proto_vsid;
-	/*
-	 * We need to make sure proto_vsid for the kernel is
-	 * >= 2^(CONTEXT_BITS + USER_ESID_BITS[_1T])
-	 */
-	if (ssize == MMU_SEGSIZE_256M) {
-		proto_vsid = ea >> SID_SHIFT;
-		proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS));
-		return vsid_scramble(proto_vsid, 256M);
-	}
-	proto_vsid = ea >> SID_SHIFT_1T;
-	proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS_1T));
-	return vsid_scramble(proto_vsid, 1T);
-}
-
 /* Returns the segment size indicator for a user address */
 static inline int user_segment_size(unsigned long addr)
 {
@@ -551,7 +519,6 @@ static inline int user_segment_size(unsigned long addr)
 	return MMU_SEGSIZE_256M;
 }
 
-/* This is only valid for user addresses (which are below 2^44) */
 static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
 				     int ssize)
 {
@@ -562,6 +529,24 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
 			     | (ea >> SID_SHIFT_1T), 1T);
 }
 
+/*
+ * This is only valid for addresses >= PAGE_OFFSET
+ *
+ * For kernel space, we use the top 4 context ids to map address as below
+ * 0x7fffb -  [ 0xc000000000000000 - 0xcfffffffffffffff ]
+ * 0x7fffc -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
+ * 0x7fffd -  [ 0xe000000000000000 - 0xefffffffffffffff ]
+ * 0x7fffe -  [ 0xf000000000000000 - 0xffffffffffffffff ]
+ */
+static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
+{
+	unsigned long context;
+	/*
+	 * kernel take the top 4 context from the available range
+	 */
+	context = (MAX_CONTEXT - 4) +  ((ea >> 60) - 0xc);
+	return get_vsid(context, ea, ssize);
+}
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_MMU_HASH64_H_ */
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 4665e82..d8f6804 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1268,17 +1268,24 @@ do_ste_alloc:
 _GLOBAL(do_stab_bolted)
 	stw	r9,PACA_EXSLB+EX_CCR(r13)	/* save CR in exc. frame */
 	std	r11,PACA_EXSLB+EX_SRR0(r13)	/* save SRR0 in exc. frame */
+	mfspr	r11,SPRN_DAR			/* ea */
+
+	/*
+	 * Calculate VSID:
+	 * This is the kernel vsid, we take the top for context from
+	 * the range. context = (MAX_CONTEXT - 4) + ((ea >> 60) - 0xc)
+	 */
+	srdi	r9,r11,60
+	subi	r9,r9,(0xc + 4 + 1)
+	lis	r10,8
+	add	r9,r9,r10		/* context */
 
 	/* Hash to the primary group */
 	ld	r10,PACASTABVIRT(r13)
-	mfspr	r11,SPRN_DAR
 	srdi	r11,r11,28
 	rldimi	r10,r11,7,52	/* r10 = first ste of the group */
 
-	/* Calculate VSID */
-	/* This is a kernel address, so protovsid = ESID | 1 << 37 */
-	li	r9,0x1
-	rldimi  r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0
+	rldimi  r11,r9,USER_ESID_BITS,0 /* proto vsid */
 	ASM_VSID_SCRAMBLE(r11, r9, 256M)
 	rldic	r9,r11,12,16	/* r9 = vsid << 12 */
 
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
index 40bc5b0..9c84b16 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -29,15 +29,6 @@
 static DEFINE_SPINLOCK(mmu_context_lock);
 static DEFINE_IDA(mmu_context_ida);
 
-/*
- * 256MB segment
- * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments
- * available for user mappings. Each segment contains 2^28 bytes. Each
- * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts
- * (19 == 37 + 28 - 46).
- */
-#define MAX_CONTEXT	((1UL << CONTEXT_BITS) - 1)
-
 int __init_new_context(void)
 {
 	int index;
@@ -56,7 +47,7 @@ again:
 	else if (err)
 		return err;
 
-	if (index > MAX_CONTEXT) {
+	if (index > (MAX_CONTEXT - 4)) {
 		spin_lock(&mmu_context_lock);
 		ida_remove(&mmu_context_ida, index);
 		spin_unlock(&mmu_context_lock);
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index 1a16ca2..487f998 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -56,12 +56,19 @@ _GLOBAL(slb_allocate_realmode)
 	 */
 _GLOBAL(slb_miss_kernel_load_linear)
 	li	r11,0
-	li	r9,0x1
+	/*
+	 * context = (MAX_CONTEXT - 4) + ((ea >> 60) - 0xc)
+	 */
+	srdi	r9,r3,60
+	subi	r9,r9,(0xc + 4 + 1)
+	lis	r10, 8
+	add	r9,r9,r10
+	srdi	r10,r3,28 /* FIXME!! doing it twice */
 	/*
 	 * for 1T we shift 12 bits more.  slb_finish_load_1T will do
 	 * the necessary adjustment
 	 */
-	rldimi  r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
+	rldimi  r10,r9,USER_ESID_BITS,0
 BEGIN_FTR_SECTION
 	b	slb_finish_load
 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
@@ -91,12 +98,19 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
 	_GLOBAL(slb_miss_kernel_load_io)
 	li	r11,0
 6:
-	li	r9,0x1
+	/*
+	 * context = (MAX_CONTEXT - 4) + ((ea >> 60) - 0xc)
+	 */
+	srdi	r9,r3,60
+	subi	r9,r9,(0xc + 4 + 1)
+	lis	r10,8
+	add	r9,r9,r10
+	srdi	r10,r3,28 /* FIXME!! doing it twice */
 	/*
 	 * for 1T we shift 12 bits more.  slb_finish_load_1T will do
 	 * the necessary adjustment
 	 */
-	rldimi  r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0
+	rldimi  r10,r9,USER_ESID_BITS,0
 BEGIN_FTR_SECTION
 	b	slb_finish_load
 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] powerpc: Don't update r10 early in the call
  2013-02-14  8:36 ` [PATCH 1/4] powerpc: Make VSID_BITS* dependency explicit Aneesh Kumar K.V
  2013-02-14  8:36   ` [PATCH 2/4] powerpc: Update kernel VSID range Aneesh Kumar K.V
@ 2013-02-14  8:36   ` Aneesh Kumar K.V
  2013-02-14  8:36   ` [PATCH 4/4] powerpc: Add vm debug code to catch errors Aneesh Kumar K.V
  2 siblings, 0 replies; 7+ messages in thread
From: Aneesh Kumar K.V @ 2013-02-14  8:36 UTC (permalink / raw)
  To: benh, paulus, phileas-fogg, geoff; +Cc: linuxppc-dev, Aneesh Kumar K.V

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

This enables us to use r10 as scratch in the code.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/mm/slb_low.S |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index 487f998..2a233cb 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -34,7 +34,6 @@ _GLOBAL(slb_allocate_realmode)
 	/* r3 = faulting address */
 
 	srdi	r9,r3,60		/* get region */
-	srdi	r10,r3,28		/* get esid */
 	cmpldi	cr7,r9,0xc		/* cmp PAGE_OFFSET for later use */
 
 	/* r3 = address, r10 = esid, cr7 = <> PAGE_OFFSET */
@@ -63,7 +62,7 @@ _GLOBAL(slb_miss_kernel_load_linear)
 	subi	r9,r9,(0xc + 4 + 1)
 	lis	r10, 8
 	add	r9,r9,r10
-	srdi	r10,r3,28 /* FIXME!! doing it twice */
+	srdi	r10,r3,SID_SHIFT	/* get esid */
 	/*
 	 * for 1T we shift 12 bits more.  slb_finish_load_1T will do
 	 * the necessary adjustment
@@ -75,6 +74,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
 	b	slb_finish_load_1T
 
 1:
+	srdi	r10,r3,SID_SHIFT	/* get esid */
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 	/* Check virtual memmap region. To be patches at kernel boot */
 	cmpldi	cr0,r9,0xf
@@ -116,9 +116,11 @@ BEGIN_FTR_SECTION
 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
 	b	slb_finish_load_1T
 
-0:	/* user address: proto-VSID = context << 15 | ESID. First check
+0:	/*
+	 * user address: proto-VSID = context << 15 | ESID. First check
 	 * if the address is within the boundaries of the user region
 	 */
+	srdi	r10,r3,SID_SHIFT	/* get esid */
 	srdi.	r9,r10,USER_ESID_BITS
 	bne-	8f			/* invalid ea bits set */
 
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] powerpc: Add vm debug code to catch errors
  2013-02-14  8:36 ` [PATCH 1/4] powerpc: Make VSID_BITS* dependency explicit Aneesh Kumar K.V
  2013-02-14  8:36   ` [PATCH 2/4] powerpc: Update kernel VSID range Aneesh Kumar K.V
  2013-02-14  8:36   ` [PATCH 3/4] powerpc: Don't update r10 early in the call Aneesh Kumar K.V
@ 2013-02-14  8:36   ` Aneesh Kumar K.V
  2013-02-15  4:46     ` Paul Mackerras
  2 siblings, 1 reply; 7+ messages in thread
From: Aneesh Kumar K.V @ 2013-02-14  8:36 UTC (permalink / raw)
  To: benh, paulus, phileas-fogg, geoff; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@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@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

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/4] powerpc: Update kernel VSID range
  2013-02-14  8:36   ` [PATCH 2/4] powerpc: Update kernel VSID range Aneesh Kumar K.V
@ 2013-02-14 17:21     ` Aneesh Kumar K.V
  2013-02-15  4:42     ` Paul Mackerras
  1 sibling, 0 replies; 7+ messages in thread
From: Aneesh Kumar K.V @ 2013-02-14 17:21 UTC (permalink / raw)
  To: benh, paulus, phileas-fogg, geoff; +Cc: linuxppc-dev

"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> writes:

> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>
> This patch change the kernel VSID range so that we limit VSID_BITS to 37.
> This enables us to support 64TB with 65 bit VA (37+28). Without this patch
> we have boot hangs on platforms that only support 65 bit VA.
>
> With this patch we now have proto vsid generated as below:
>
> We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
> from mmu context id and effective segment id of the address.
>
> For user processes max context id is limited to ((1ul << 19) - 6)
> for kernel space, we use the top 4 context ids to map address as below
> 0x7fffb -  [ 0xc000000000000000 - 0xcfffffffffffffff ]
> 0x7fffc -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
> 0x7fffd -  [ 0xe000000000000000 - 0xefffffffffffffff ]
> 0x7fffe -  [ 0xf000000000000000 - 0xffffffffffffffff ]

I guess we can do this as below

 0x7fffc -  [ 0xc000000000000000 - 0xcfffffffffffffff ]
 0x7fffd -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
 0x7fffe -  [ 0xe000000000000000 - 0xefffffffffffffff ]
 0x7ffff -  [ 0xf000000000000000 - 0xffffffffffffffff ]

Will update this as part of next revision after I get full review.

diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 3e297ea..71c69e6 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -355,10 +355,10 @@ extern void slb_set_size(u16 size);
  *
  * For user processes max context id is limited to ((1ul << 19) - 6)
  * for kernel space, we use the top 4 context ids to map address as below
- * 0x7fffb -  [ 0xc000000000000000 - 0xcfffffffffffffff ]
- * 0x7fffc -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
- * 0x7fffd -  [ 0xe000000000000000 - 0xefffffffffffffff ]
- * 0x7fffe -  [ 0xf000000000000000 - 0xffffffffffffffff ]
+ * 0x7fffc -  [ 0xc000000000000000 - 0xcfffffffffffffff ]
+ * 0x7fffd -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
+ * 0x7fffe -  [ 0xe000000000000000 - 0xefffffffffffffff ]
+ * 0x7ffff -  [ 0xf000000000000000 - 0xffffffffffffffff ]
  *
  * The proto-VSIDs are then scrambled into real VSIDs with the
  * multiplicative hash:
@@ -561,10 +561,10 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
  * This is only valid for addresses >= PAGE_OFFSET
  *
  * For kernel space, we use the top 4 context ids to map address as below
- * 0x7fffb -  [ 0xc000000000000000 - 0xcfffffffffffffff ]
- * 0x7fffc -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
- * 0x7fffd -  [ 0xe000000000000000 - 0xefffffffffffffff ]
- * 0x7fffe -  [ 0xf000000000000000 - 0xffffffffffffffff ]
+ * 0x7fffc -  [ 0xc000000000000000 - 0xcfffffffffffffff ]
+ * 0x7fffd -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
+ * 0x7fffe -  [ 0xe000000000000000 - 0xefffffffffffffff ]
+ * 0x7ffff -  [ 0xf000000000000000 - 0xffffffffffffffff ]
  */
 static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
 {
@@ -574,7 +574,7 @@ static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
 	 * kernel take the top 4 context from the available range
 	 */
 	c_index =   ((ea >> 60) - 0xc);
-	context = (MAX_CONTEXT - 4) + c_index;
+	context = (MAX_CONTEXT - 3) + c_index;
 #ifdef CONFIG_DEBUG_VM
 	/*
 	 * Drop the c_index related bits from ea, so we get
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index d8f6804..cb6404b 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1273,10 +1273,10 @@ _GLOBAL(do_stab_bolted)
 	/*
 	 * Calculate VSID:
 	 * This is the kernel vsid, we take the top for context from
-	 * the range. context = (MAX_CONTEXT - 4) + ((ea >> 60) - 0xc)
+	 * the range. context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
 	 */
 	srdi	r9,r11,60
-	subi	r9,r9,(0xc + 4 + 1)
+	subi	r9,r9,(0xc + 3 + 1)
 	lis	r10,8
 	add	r9,r9,r10		/* context */
 
diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c
index 9c84b16..59cd773 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -48,6 +48,7 @@ again:
 		return err;
 
 	if (index > (MAX_CONTEXT - 4)) {
+		/* Top 4 context id values are used for kernel */
 		spin_lock(&mmu_context_lock);
 		ida_remove(&mmu_context_ida, index);
 		spin_unlock(&mmu_context_lock);
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index 2a233cb..2c9524b 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -56,10 +56,10 @@ _GLOBAL(slb_allocate_realmode)
 _GLOBAL(slb_miss_kernel_load_linear)
 	li	r11,0
 	/*
-	 * context = (MAX_CONTEXT - 4) + ((ea >> 60) - 0xc)
+	 * context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
 	 */
 	srdi	r9,r3,60
-	subi	r9,r9,(0xc + 4 + 1)
+	subi	r9,r9,(0xc + 3 + 1)
 	lis	r10, 8
 	add	r9,r9,r10
 	srdi	r10,r3,SID_SHIFT	/* get esid */
@@ -99,10 +99,10 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
 	li	r11,0
 6:
 	/*
-	 * context = (MAX_CONTEXT - 4) + ((ea >> 60) - 0xc)
+	 * context = (MAX_CONTEXT - 3) + ((ea >> 60) - 0xc)
 	 */
 	srdi	r9,r3,60
-	subi	r9,r9,(0xc + 4 + 1)
+	subi	r9,r9,(0xc + 3 + 1)
 	lis	r10,8
 	add	r9,r9,r10
 	srdi	r10,r3,28 /* FIXME!! doing it twice */

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/4] powerpc: Update kernel VSID range
  2013-02-14  8:36   ` [PATCH 2/4] powerpc: Update kernel VSID range Aneesh Kumar K.V
  2013-02-14 17:21     ` Aneesh Kumar K.V
@ 2013-02-15  4:42     ` Paul Mackerras
  1 sibling, 0 replies; 7+ messages in thread
From: Paul Mackerras @ 2013-02-15  4:42 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: phileas-fogg, linuxppc-dev, geoff

On Thu, Feb 14, 2013 at 02:06:21PM +0530, Aneesh Kumar K.V wrote:
> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
> 
> This patch change the kernel VSID range so that we limit VSID_BITS to 37.
> This enables us to support 64TB with 65 bit VA (37+28). Without this patch
> we have boot hangs on platforms that only support 65 bit VA.
> 
> With this patch we now have proto vsid generated as below:
> 
> We first generate a 37-bit "proto-VSID". Proto-VSIDs are generated
> from mmu context id and effective segment id of the address.
> 
> For user processes max context id is limited to ((1ul << 19) - 6)
> for kernel space, we use the top 4 context ids to map address as below
> 0x7fffb -  [ 0xc000000000000000 - 0xcfffffffffffffff ]

Actually, each context only gives us 64TB, so the range here would be
0xc000000000000000 - 0xc0003fffffffffff.  Similarly for the others.

> 0x7fffc -  [ 0xd000000000000000 - 0xdfffffffffffffff ]
> 0x7fffd -  [ 0xe000000000000000 - 0xefffffffffffffff ]
> 0x7fffe -  [ 0xf000000000000000 - 0xffffffffffffffff ]

We could increase all these context numbers by 1.  We have to avoid
the last ESID of the last context because of the modulo operation in
the vsid scramble, but the vmemmap (which is what uses region 0xf)
will never be close to 64TB in size (it's 56 bytes per page of system
memory).

[snip]
> +static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
> +{
> +	unsigned long context;
> +	/*
> +	 * kernel take the top 4 context from the available range
> +	 */

You should check the ea here, and if it is out of range (below 0xc...,
or with any of the 0x0fffc00000000000 bits set), return 0, which is
the reserved vsid.

> +	context = (MAX_CONTEXT - 4) +  ((ea >> 60) - 0xc);
> +	return get_vsid(context, ea, ssize);
> +}
>  #endif /* __ASSEMBLY__ */
>  
>  #endif /* _ASM_POWERPC_MMU_HASH64_H_ */
> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
> index 4665e82..d8f6804 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -1268,17 +1268,24 @@ do_ste_alloc:
>  _GLOBAL(do_stab_bolted)
>  	stw	r9,PACA_EXSLB+EX_CCR(r13)	/* save CR in exc. frame */
>  	std	r11,PACA_EXSLB+EX_SRR0(r13)	/* save SRR0 in exc. frame */
> +	mfspr	r11,SPRN_DAR			/* ea */
> +
> +	/*
> +	 * Calculate VSID:
> +	 * This is the kernel vsid, we take the top for context from
> +	 * the range. context = (MAX_CONTEXT - 4) + ((ea >> 60) - 0xc)
> +	 */
> +	srdi	r9,r11,60
> +	subi	r9,r9,(0xc + 4 + 1)
> +	lis	r10,8
> +	add	r9,r9,r10		/* context */

At this point we know the top 4 bits of EA are 0xc, so the context is
a constant which we can load with 2 instructions.  We do also need to
check the middle bits (0x0fff_c000_0000_0000) and use a VSID of 0 if
any of them are set.

> diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
> index 1a16ca2..487f998 100644
> --- a/arch/powerpc/mm/slb_low.S
> +++ b/arch/powerpc/mm/slb_low.S
> @@ -56,12 +56,19 @@ _GLOBAL(slb_allocate_realmode)
>  	 */
>  _GLOBAL(slb_miss_kernel_load_linear)
>  	li	r11,0
> -	li	r9,0x1
> +	/*
> +	 * context = (MAX_CONTEXT - 4) + ((ea >> 60) - 0xc)
> +	 */
> +	srdi	r9,r3,60
> +	subi	r9,r9,(0xc + 4 + 1)
> +	lis	r10, 8
> +	add	r9,r9,r10
> +	srdi	r10,r3,28 /* FIXME!! doing it twice */

Also need to check the middle bits here and for the 1T case.

Paul.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 4/4] powerpc: Add vm debug code to catch errors
  2013-02-14  8:36   ` [PATCH 4/4] powerpc: Add vm debug code to catch errors Aneesh Kumar K.V
@ 2013-02-15  4:46     ` Paul Mackerras
  0 siblings, 0 replies; 7+ messages in thread
From: Paul Mackerras @ 2013-02-15  4:46 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: phileas-fogg, linuxppc-dev, geoff

On Thu, Feb 14, 2013 at 02:06:23PM +0530, Aneesh Kumar K.V wrote:
> From: "Aneesh Kumar K.V" <aneesh.kumar@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.

I'm not sure that WARN_ON is the best way to handle this, since this
code is called from low levels of the MMU management code, and a
WARN_ON will cause a trap that could possibly come at a time when we
can't handle a trap very well.  I think instead these functions should
return a vsid of 0 for bad addresses, and the callers should detect
that case and handle it appropriately, e.g. hash_page() should return
an error.

Paul.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-02-15  4:46 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <a>
2013-02-14  8:36 ` [PATCH 1/4] powerpc: Make VSID_BITS* dependency explicit Aneesh Kumar K.V
2013-02-14  8:36   ` [PATCH 2/4] powerpc: Update kernel VSID range Aneesh Kumar K.V
2013-02-14 17:21     ` Aneesh Kumar K.V
2013-02-15  4:42     ` Paul Mackerras
2013-02-14  8:36   ` [PATCH 3/4] powerpc: Don't update r10 early in the call Aneesh Kumar K.V
2013-02-14  8:36   ` [PATCH 4/4] powerpc: Add vm debug code to catch errors Aneesh Kumar K.V
2013-02-15  4:46     ` Paul Mackerras

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).