diff mbox

sparc64: swapper_tsb and swapper_4m_tsb phys correction

Message ID 20140918.154312.1505148212511781262.davem@davemloft.net
State Superseded
Delegated to: David Miller
Headers show

Commit Message

David Miller Sept. 18, 2014, 7:43 p.m. UTC
From: David Miller <davem@davemloft.net>
Date: Wed, 17 Sep 2014 13:16:22 -0400 (EDT)

> [PATCH] sparc64: Adjust KTSB assembler to support larger physical addresses.

Bob, just a quick update.

I've adjusted this patch of mine to support arbitrary physical addresses,
not just up to 54-bits.

With the other related changes being discussed, we will have no
limitations to deal with wrt. physical addressing ever again and
honestly I don't want to have to play with this area any more :)

--------------------
[PATCH] sparc64: Adjust KTSB assembler to support larger physical addresses.

As currently coded the KTSB accesses in the kernel only support up to
47 bits of physical addressing.

Adjust the instruction and patching sequence in order to support
arbitrary 64 bits addresses.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 arch/sparc/include/asm/tsb.h | 30 ++++++++++++------------------
 arch/sparc/mm/init_64.c      | 28 +++++++++++++++++++++++++---
 2 files changed, 37 insertions(+), 21 deletions(-)

Comments

Bob Picco Sept. 18, 2014, 10:15 p.m. UTC | #1
David Miller wrote:	[Thu Sep 18 2014, 03:43:12PM EDT]
> From: David Miller <davem@davemloft.net>
> Date: Wed, 17 Sep 2014 13:16:22 -0400 (EDT)
> 
> > [PATCH] sparc64: Adjust KTSB assembler to support larger physical addresses.
> 
> Bob, just a quick update.
> 
> I've adjusted this patch of mine to support arbitrary physical addresses,
> not just up to 54-bits.
> 
> With the other related changes being discussed, we will have no
> limitations to deal with wrt. physical addressing ever again and
> honestly I don't want to have to play with this area any more :)
Honestly, me too :) It boots fine on T5-2. I'll hopefully take it for
a test drive on M7-4 tomorrow.
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller Sept. 18, 2014, 11:16 p.m. UTC | #2
From: Bob Picco <bpicco@meloft.net>
Date: Thu, 18 Sep 2014 18:15:30 -0400

> David Miller wrote:	[Thu Sep 18 2014, 03:43:12PM EDT]
>> From: David Miller <davem@davemloft.net>
>> Date: Wed, 17 Sep 2014 13:16:22 -0400 (EDT)
>> 
>> > [PATCH] sparc64: Adjust KTSB assembler to support larger physical addresses.
>> 
>> Bob, just a quick update.
>> 
>> I've adjusted this patch of mine to support arbitrary physical addresses,
>> not just up to 54-bits.
>> 
>> With the other related changes being discussed, we will have no
>> limitations to deal with wrt. physical addressing ever again and
>> honestly I don't want to have to play with this area any more :)
> Honestly, me too :) It boots fine on T5-2. I'll hopefully take it for
> a test drive on M7-4 tomorrow.

Thanks for all of your help and testing so far.

So I'll consider this patch good to go.

I'm half-way done with the "use kernel page tables for everything"
patch, and will post once I have something that at least work for
me.

BTW, with all of the static table removals, my images currently fit in
just 2 locked TLB entries :-)
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller Sept. 19, 2014, 7:28 p.m. UTC | #3
From: David Miller <davem@davemloft.net>
Date: Thu, 18 Sep 2014 19:16:37 -0400 (EDT)

> I'm half-way done with the "use kernel page tables for everything"
> patch, and will post once I have something that at least work for
> me.

Bob, I ran into a major roadblock which is going to delay this work
a little bit.

In fact it pointed out a bug we introduced when increasing max phys
bits to 47.  We broke DEBUG_PAGEALLOC completely.  The issue is that
the page table layout only supports up to 43-bits.

I'll brain storm about this over the weekend.
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Bob Picco Sept. 19, 2014, 7:57 p.m. UTC | #4
Hi,
David Miller wrote:	[Fri Sep 19 2014, 03:28:46PM EDT]
> From: David Miller <davem@davemloft.net>
> Date: Thu, 18 Sep 2014 19:16:37 -0400 (EDT)
> 
> > I'm half-way done with the "use kernel page tables for everything"
> > patch, and will post once I have something that at least work for
> > me.
> 
> Bob, I ran into a major roadblock which is going to delay this work
> a little bit.
Okay.
> 
> In fact it pointed out a bug we introduced when increasing max phys
> bits to 47.  We broke DEBUG_PAGEALLOC completely.  The issue is that
> the page table layout only supports up to 43-bits.
Oh bugger yes. I recall testing this when first introducting four level
page table layout in late 2012 and early 2013. It just isn't an everyday
thought but VERY nice to have.
> 
> I'll brain storm about this over the weekend.
Me too.
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h
index 90916f9..11c5047 100644
--- a/arch/sparc/include/asm/tsb.h
+++ b/arch/sparc/include/asm/tsb.h
@@ -246,8 +246,6 @@  extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
 	(KERNEL_TSB_SIZE_BYTES / 16)
 #define KERNEL_TSB4M_NENTRIES	4096
 
-#define KTSB_PHYS_SHIFT		15
-
 	/* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL
 	 * on TSB hit.  REG1, REG2, REG3, and REG4 are used as temporaries
 	 * and the found TTE will be left in REG1.  REG3 and REG4 must
@@ -256,17 +254,15 @@  extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
 	 * VADDR and TAG will be preserved and not clobbered by this macro.
 	 */
 #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
-661:	sethi		%hi(swapper_tsb), REG1;			\
-	or		REG1, %lo(swapper_tsb), REG1; \
+661:	sethi		%uhi(swapper_tsb), REG1; \
+	sethi		%hi(swapper_tsb), REG2; \
+	or		REG1, %ulo(swapper_tsb), REG1; \
+	or		REG2, %lo(swapper_tsb), REG2; \
 	.section	.swapper_tsb_phys_patch, "ax"; \
 	.word		661b; \
 	.previous; \
-661:	nop; \
-	.section	.tsb_ldquad_phys_patch, "ax"; \
-	.word		661b; \
-	sllx		REG1, KTSB_PHYS_SHIFT, REG1; \
-	sllx		REG1, KTSB_PHYS_SHIFT, REG1; \
-	.previous; \
+	sllx		REG1, 32, REG1; \
+	or		REG1, REG2, REG1; \
 	srlx		VADDR, PAGE_SHIFT, REG2; \
 	and		REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \
 	sllx		REG2, 4, REG2; \
@@ -281,17 +277,15 @@  extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
 	 * we can make use of that for the index computation.
 	 */
 #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
-661:	sethi		%hi(swapper_4m_tsb), REG1;	     \
-	or		REG1, %lo(swapper_4m_tsb), REG1; \
+661:	sethi		%uhi(swapper_4m_tsb), REG1; \
+	sethi		%hi(swapper_4m_tsb), REG2; \
+	or		REG1, %ulo(swapper_4m_tsb), REG1; \
+	or		REG2, %lo(swapper_4m_tsb), REG2; \
 	.section	.swapper_4m_tsb_phys_patch, "ax"; \
 	.word		661b; \
 	.previous; \
-661:	nop; \
-	.section	.tsb_ldquad_phys_patch, "ax"; \
-	.word		661b; \
-	sllx		REG1, KTSB_PHYS_SHIFT, REG1; \
-	sllx		REG1, KTSB_PHYS_SHIFT, REG1; \
-	.previous; \
+	sllx		REG1, 32, REG1; \
+	or		REG1, REG2, REG1; \
 	and		TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
 	sllx		REG2, 4, REG2; \
 	add		REG1, REG2, REG2; \
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index c8bccaf..971ac36 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1705,19 +1705,41 @@  static void __init tsb_phys_patch(void)
 static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR];
 extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES];
 
+/* The swapper TSBs are loaded with a base sequence of:
+ *
+ *	sethi	%uhi(SYMBOL), REG1
+ *	sethi	%hi(SYMBOL), REG2
+ *	or	REG1, %ulo(SYMBOL), REG1
+ *	or	REG2, %lo(SYMBOL), REG2
+ *	sllx	REG1, 32, REG1
+ *	or	REG1, REG2, REG1
+ *
+ * When we use physical addressing for the TSB accesses, we patch the
+ * first four instructions in the above sequence.
+ */
+
 static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa)
 {
-	pa >>= KTSB_PHYS_SHIFT;
+	unsigned long high_bits, low_bits;
+
+	high_bits = (pa >> 32) & 0xffffffff;
+	low_bits = (pa >> 0) & 0xffffffff;
 
 	while (start < end) {
 		unsigned int *ia = (unsigned int *)(unsigned long)*start;
 
-		ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10);
+		ia[0] = (ia[0] & ~0x3fffff) | (high_bits >> 10);
 		__asm__ __volatile__("flush	%0" : : "r" (ia));
 
-		ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff);
+		ia[1] = (ia[1] & ~0x3fffff) | (low_bits >> 10);
 		__asm__ __volatile__("flush	%0" : : "r" (ia + 1));
 
+		ia[2] = (ia[2] & ~0x1fff) | (high_bits & 0x3ff);
+		__asm__ __volatile__("flush	%0" : : "r" (ia + 2));
+
+		ia[3] = (ia[3] & ~0x1fff) | (low_bits & 0x3ff);
+		__asm__ __volatile__("flush	%0" : : "r" (ia + 3));
+
 		start++;
 	}
 }