From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
phileas-fogg@mail.ru, geoff@infradead.org
Cc: linuxppc-dev@lists.ozlabs.org, paulus@samba.org
Subject: Re: [PATCH 2/2] powerpc: Make context bits depend on virtual addr size.
Date: Wed, 13 Feb 2013 17:10:47 +0530 [thread overview]
Message-ID: <87pq04jvb4.fsf@linux.vnet.ibm.com> (raw)
In-Reply-To: <1360727211.2035.30.camel@pasglop>
Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
> On Wed, 2013-02-13 at 08:54 +0530, Aneesh Kumar K.V wrote:
>> > A compile option ? Really ? Ugh...
>>
>> I actually wanted that to be done in Kconfig.cputype, but haven't found
>> a nice way to do it. Considering we are switching between only two
>> values, I was thinking an #ifdef would work.
>
> No, we want to support all those processor types from a single kernel image.
Ok. How about the below patch. This is based on the suggestion from
Paulus. I still have to take care of few comments in the code.
We now split the proto-vsid range differently.
User: 0 to [2^(CONTEXT_BITS) - 4 + 2^(USER_ESID_BITS)]
kernel: [2^(CONTEXT_BITS) - 4 + 2^(USER_ESID_BITS)] to 2^(VSID_BITS) - 1
Phileas and Geoff,
Can we check whether this fix the PS3 boot hang ?
-aneesh
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 2fdb47a..1e65a01 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -381,21 +381,33 @@ extern void slb_set_size(u16 size);
* hash collisions.
*/
+#define CONTEXT_BITS 19
+#define USER_ESID_BITS 18
+#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 38
+#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 26
+#define VSID_BITS_1T (CONTEXT_BITS + USER_ESID_BITS_1T)
#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))
@@ -513,34 +525,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)
{
@@ -561,6 +545,26 @@ 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
+ * The proto-VSID space is divided into two class
+ * User: 0 to 2^(CONTEXT_BITS) - 4 + 2^(USER_ESID_BITS)
+ * kernel: 2^(CONTEXT_BITS) - 4 + 2^(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). We use one context
+ * for 0xc, 0xd, 0xe and 0xf.
+ *
+ */
+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..78c6d0b 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1269,16 +1269,23 @@ _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
+ srdi r9,r11,60 /* ea >> 60 */
+ srdi r11,r11,SID_SHIFT
+
+ /* Calculate VSID:
+ * This is the kernel vsid, we take the top for context from
+ * the range. context = (MAX_CONTEXT - 4) + ((ea >> 60) - 0xc)
+ */
+ subi r9,r9,(0xc + 4 + 1)
+ lis r10,8
+ add r9,r9,r10
+
/* 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 */
+ rldimi r11,r9,USER_ESID_BITS,0 /* proto vsid */
- /* Calculate VSID */
- /* This is a kernel address, so protovsid = ESID | 1 << 37 */
- li r9,0x1
- rldimi r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0
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)
next prev parent reply other threads:[~2013-02-13 11:40 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-12 18:31 [PATCH 1/2] powerpc: Make VSID_BITS* dependency explicit Aneesh Kumar K.V
2013-02-12 18:31 ` [PATCH 2/2] powerpc: Make context bits depend on virtual addr size Aneesh Kumar K.V
2013-02-12 20:33 ` Benjamin Herrenschmidt
2013-02-13 3:24 ` Aneesh Kumar K.V
2013-02-13 3:46 ` Benjamin Herrenschmidt
2013-02-13 11:40 ` Aneesh Kumar K.V [this message]
2013-02-13 13:27 ` David Laight
2013-02-13 14:26 ` Aneesh Kumar K.V
2013-02-13 18:07 ` Aneesh Kumar K.V
2013-02-13 18:13 ` Re[2]: " Phileas Fogg
2013-02-13 20:09 ` Geoff Levand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87pq04jvb4.fsf@linux.vnet.ibm.com \
--to=aneesh.kumar@linux.vnet.ibm.com \
--cc=benh@kernel.crashing.org \
--cc=geoff@infradead.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=paulus@samba.org \
--cc=phileas-fogg@mail.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.