Skip to contentSkip to conversation

powerpc: Split mmu_context handling

PATCH In review Benjamin Herrenschmidt 3 participants 5 messages Dec 4, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 2/3 powerpc: Split mmu_context handling

This splits the mmu_context handling between 32-bit hash based processors, 64-bit hash based processors and everybody else. This is preliminary work for adding SMP support for BookE processors.

---

 arch/powerpc/include/asm/bug.h               |    9 
 arch/powerpc/include/asm/mmu_context.h       |  266 +++------------------------
 arch/powerpc/kernel/asm-offsets.c            |    1 
 arch/powerpc/kernel/head_32.S                |   14 +
 arch/powerpc/kernel/ppc_ksyms.c              |    3 
 arch/powerpc/kernel/swsusp.c                 |    2 
 arch/powerpc/mm/Makefile                     |    6 
 arch/powerpc/mm/mmu_context_hash32.c         |  101 ++++++++++
 arch/powerpc/mm/mmu_context_hash64.c         |   78 +++++++
 arch/powerpc/mm/mmu_context_nohash.c         |  168 +++++++++++++++++
 arch/powerpc/platforms/Kconfig.cputype       |   18 +
 arch/powerpc/platforms/powermac/cpufreq_32.c |    2 
 drivers/macintosh/via-pmu.c                  |    4 
 13 files changed, 430 insertions(+), 242 deletions(-)
arch/powerpc/include/asm/bug.h +8 -1
@@ -26,7 +26,7 @@
 	 .previous
 .endm
 #else
- .macro EMIT_BUG_ENTRY addr,file,line,flags
+.macro EMIT_BUG_ENTRY addr,file,line,flags
 	 .section __bug_table,"a"
 5001:	 PPC_LONG \addr
 	 .short \flags
@@ -113,6 +113,13 @@
 #define HAVE_ARCH_BUG_ON
 #define HAVE_ARCH_WARN_ON
 #endif /* __ASSEMBLY __ */
+#else
+#ifdef __ASSEMBLY__
+.macro EMIT_BUG_ENTRY addr,file,line,flags
+.endm
+#else /* !__ASSEMBLY__ */
+#define _EMIT_BUG_ENTRY
+#endif
 #endif /* CONFIG_BUG */
 
 #include <asm-generic/bug.h>
arch/powerpc/include/asm/mmu_context.h +36 -230

312 lines not on this page · raw message

arch/powerpc/kernel/asm-offsets.c +1 -0
Index: linux-work/arch/powerpc/kernel/asm-offsets.c
===================================================================
@@ -60,6 +60,7 @@ int main(void)
 {
 	DEFINE(THREAD, offsetof(struct task_struct, thread));
 	DEFINE(MM, offsetof(struct task_struct, mm));
+	DEFINE(MMCONTEXTID, offsetof(struct mm_struct, context.id));
 #ifdef CONFIG_PPC64
 	DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
 #else
arch/powerpc/kernel/head_32.S +12 -2
Index: linux-work/arch/powerpc/kernel/head_32.S
===================================================================
@@ -31,6 +31,7 @@
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/ptrace.h>
+#include <asm/bug.h>
 
 /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
 #define LOAD_BAT(n, reg, RA, RB)	\
@@ -1050,7 +1051,7 @@ start_here:
 	 * We do this here because we know the mmu is disabled, and
 	 * will be enabled for real in just a few instructions.
 	 */
-	lis	r5, abatron_pteptrs@h
+	lis	r5, abatron_pteptrs@h\
 	ori	r5, r5, abatron_pteptrs@l
 	stw	r5, 0xf0(r0)	/* This much match your Abatron config */
 	lis	r6, swapper_pg_dir@h
@@ -1070,9 +1071,14 @@ start_here:
 	RFI
 
 /*
+ * void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next);
+ *
  * Set up the segment registers for a new context.
  */
-_ENTRY(set_context)
+_ENTRY(switch_mmu_context)
+	lwz	r3,MMCONTEXTID(r4)
+	cmpwi	cr0,r3,0
+	blt-	4f
 	mulli	r3,r3,897	/* multiply context by skew factor */
 	rlwinm	r3,r3,4,8,27	/* VSID = (context & 0xfffff) << 4 */
 	addis	r3,r3,0x6000	/* Set Ks, Ku bits */
@@ -1083,6 +1089,7 @@ _ENTRY(set_context)
 	/* Context switch the PTE pointer for the Abatron BDI2000.
 	 * The PGDIR is passed as second argument.
 	 */
+	lwz	r4,MM_PGD(r4)
 	lis	r5, KERNELBASE@h
 	lwz	r5, 0xf0(r5)
 	stw	r4, 0x4(r5)
@@ -1098,6 +1105,9 @@ _ENTRY(set_context)
 	sync
 	isync
 	blr
+4:	trap
+	EMIT_BUG_ENTRY 4b,__FILE__,__LINE__,BUGFLAG_WARNING
+	blr
 
 /*
  * An undocumented "feature" of 604e requires that the v bit
arch/powerpc/kernel/ppc_ksyms.c +1 -2
Index: linux-work/arch/powerpc/kernel/ppc_ksyms.c
===================================================================
@@ -174,8 +174,7 @@ EXPORT_SYMBOL(cacheable_memcpy);
 #endif
 
 #ifdef CONFIG_PPC32
-EXPORT_SYMBOL(next_mmu_context);
-EXPORT_SYMBOL(set_context);
+EXPORT_SYMBOL(switch_mmu_context);
 #endif
 
 #ifdef CONFIG_PPC_STD_MMU_32
arch/powerpc/kernel/swsusp.c +1 -1
Index: linux-work/arch/powerpc/kernel/swsusp.c
===================================================================
@@ -34,6 +34,6 @@ void save_processor_state(void)
 void restore_processor_state(void)
 {
 #ifdef CONFIG_PPC32
-	set_context(current->active_mm->context.id, current->active_mm->pgd);
+	switch_mmu_context(NULL, current->active_mm);
 #endif
 }
arch/powerpc/mm/Makefile +4 -2
Index: linux-work/arch/powerpc/mm/Makefile
===================================================================
@@ -8,8 +8,10 @@ endif
 
 obj-y				:= fault.o mem.o pgtable.o \
 				   init_$(CONFIG_WORD_SIZE).o \
-				   pgtable_$(CONFIG_WORD_SIZE).o \
-				   mmu_context_$(CONFIG_WORD_SIZE).o
+				   pgtable_$(CONFIG_WORD_SIZE).o
+obj-$(CONFIG_PPC_STD_MMU_32)	+= mmu_context_hash32.o
+obj-$(CONFIG_PPC_STD_MMU_64)	+= mmu_context_hash64.o
+obj-$(CONFIG_PPC_MMU_NOHASH)	+= mmu_context_nohash.o
 hash-$(CONFIG_PPC_NATIVE)	:= hash_native_64.o
 obj-$(CONFIG_PPC64)		+= hash_utils_64.o \
 				   slb_low.o slb.o stab.o \
arch/powerpc/mm/mmu_context_hash32.c new file +101 -0

101 lines not on this page · raw message

arch/powerpc/mm/mmu_context_hash64.c new file +78 -0

78 lines not on this page · raw message

arch/powerpc/mm/mmu_context_nohash.c new file +168 -0

168 lines not on this page · raw message

arch/powerpc/platforms/Kconfig.cputype +17 -1
Index: linux-work/arch/powerpc/platforms/Kconfig.cputype
===================================================================
@@ -195,13 +195,29 @@ config SPE
 
 config PPC_STD_MMU
 	bool
-	depends on 6xx || POWER3 || POWER4 || PPC64
+	depends on 6xx || PPC64
 	default y
 
 config PPC_STD_MMU_32
 	def_bool y
 	depends on PPC_STD_MMU && PPC32
 
+config PPC_STD_MMU_64
+	def_bool y
+	depends on PPC_STD_MMU && PPC64
+
+config PPC_MMU_NOHASH
+	def_bool y
+	depends on !PPC_STD_MMU
+
+config PPC_MMU_NOHASH_32
+	def_bool y
+	depends on PPC_MMU_NOHASH && PPC32
+
+config PPC_MMU_NOHASH_64
+	def_bool y
+	depends on PPC_MMU_NOHASH && PPC64
+
 config PPC_MM_SLICES
 	bool
 	default y if HUGETLB_PAGE || PPC_64K_PAGES
arch/powerpc/platforms/powermac/cpufreq_32.c +1 -1
Index: linux-work/arch/powerpc/platforms/powermac/cpufreq_32.c
===================================================================
@@ -310,7 +310,7 @@ static int pmu_set_cpu_speed(int low_spe
  		_set_L3CR(save_l3cr);
 
 	/* Restore userland MMU context */
-	set_context(current->active_mm->context.id, current->active_mm->pgd);
+	switch_mmu_context(NULL, current->active_mm);
 
 #ifdef DEBUG_FREQ
 	printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
drivers/macintosh/via-pmu.c +2 -2
Index: linux-work/drivers/macintosh/via-pmu.c
===================================================================
@@ -1814,7 +1814,7 @@ static int powerbook_sleep_grackle(void)
  		_set_L2CR(save_l2cr);
 	
 	/* Restore userland MMU context */
-	set_context(current->active_mm->context.id, current->active_mm->pgd);
+	switch_mmu_context(NULL, current->active_mm);
 
 	/* Power things up */
 	pmu_unlock();
@@ -1903,7 +1903,7 @@ powerbook_sleep_Core99(void)
  		_set_L3CR(save_l3cr);
 	
 	/* Restore userland MMU context */
-	set_context(current->active_mm->context.id, current->active_mm->pgd);
+	switch_mmu_context(NULL, current->active_mm);
 
 	/* Tell PMU we are ready */
 	pmu_unlock();
#1 lore raw

Hi Ben,

arch/powerpc/include/asm/bug.h line 29

Quoted 9 lines · On Thu, 04 Dec 2008 16:41:48 +1100 Benjamin Herrenschmidt…
arch/powerpc/include/asm/bug.h +1 -1
@@ -26,7 +26,7 @@
 	 .previous
 .endm
 #else
- .macro EMIT_BUG_ENTRY addr,file,line,flags
+.macro EMIT_BUG_ENTRY addr,file,line,flags

Please don't make unrelated trivial fixups - they just make us look hard to see if something really changed.

arch/powerpc/include/asm/bug.h line 30

Quoted 3 lines
arch/powerpc/include/asm/bug.h +1 -2
-/*
- * switch_mm is the entry point called from the architecture independent
+/* switch_mm is the entry point called from the architecture independent

The same goes for just changing the comment style away from the usual ...

arch/powerpc/include/asm/bug.h

Quoted 3 lines
arch/powerpc/include/asm/bug.h +1 -2
-/*
- * After we have set current->mm to a new value, this activates
+/* After we have set current->mm to a new value, this activates

Ditto

arch/powerpc/kernel/head_32.S start_here: · line 1054

Quoted 8 lines
arch/powerpc/kernel/head_32.S +1 -1
@@ -1050,7 +1051,7 @@ start_here:
 	 * We do this here because we know the mmu is disabled, and
 	 * will be enabled for real in just a few instructions.
 	 */
-	lis	r5, abatron_pteptrs@h
+	lis	r5, abatron_pteptrs@h\
                                     ^

Is this right?

arch/powerpc/kernel/head_32.S start_here:

Quoted 11 lines
arch/powerpc/kernel/head_32.S +11 -0
+++ linux-work/arch/powerpc/mm/mmu_context_hash32.c	2008-12-03 13:50:18.000000000 +1100
+/*
+ * This function defines the mapping from contexts to VSIDs (virtual
+ * segment IDs).  We use a skew on both the context and the high 4 bits
+ * of the 32-bit virtual address (the "effective segment ID") in order
+ * to spread out the entries in the MMU hash table.  Note, if this
+ * function is changed then arch/ppc/mm/hashtable.S will have to be
+ * changed to correspond.
+ */
+#define CTX_TO_VSID(ctx, va)	(((ctx) * (897 * 16) + ((va) >> 28) * 0x111) \
+				 & 0xffffff)

Any reason this is not a static inline function? Hmmm, actually it doesn't look like it is used anywhere ... I guess its just for documentation?

Quoted 5 lines

+++ linux-work/arch/powerpc/mm/mmu_context_nohash.c 2008-12-03 13:50:18.000000000 +1100

arch/powerpc/kernel/head_32.S +4 -0
+#ifdef CONFIG_8xx
+#define NO_CONTEXT      	16
+#define LAST_CONTEXT    	15
+#define FIRST_CONTEXT    	0

arch/powerpc/kernel/head_32.S

Quoted 10 lines
arch/powerpc/kernel/head_32.S +10 -0
+
+#elif defined(CONFIG_4xx)
+#define NO_CONTEXT      	256
+#define LAST_CONTEXT    	255
+#define FIRST_CONTEXT    	1
+
+#elif defined(CONFIG_E200) || defined(CONFIG_E500)
+#define NO_CONTEXT      	256
+#define LAST_CONTEXT    	255
+#define FIRST_CONTEXT    	1

Why not combine these last two?

arch/powerpc/kernel/head_32.S

Quoted 5 lines
arch/powerpc/kernel/head_32.S +4 -0
+static unsigned long next_mmu_context;
 
+	/* free up context `next_mmu_context' */
+	/* if we shouldn't free context 0, don't... */
+	if (next_mmu_context < FIRST_CONTEXT)

If FIRST_CONTEXT is 0, this will generate a compiler warning (as next_mmu_context can't be < 0).

arch/powerpc/kernel/head_32.S

Quoted 7 lines
arch/powerpc/kernel/head_32.S +7 -0
+config PPC_MMU_NOHASH_32
+	def_bool y
+	depends on PPC_MMU_NOHASH && PPC32
+
+config PPC_MMU_NOHASH_64
+	def_bool y
+	depends on PPC_MMU_NOHASH && PPC64

Neither of these are used anywhere.

Signature · 3 lines
Cheers,
Stephen Rothwell                    [email protected]
http://www.canb.auug.org.au/~sfr/
#2 lore raw
Quoted 2 lines · Stephen Rothwell

Please don't make unrelated trivial fixups - they just make us look hard to see if something really changed.

Ooops... caught :-)

Quoted 5 lines

arch/powerpc/include/asm/mmu_context.h line 26

Quoted 3 lines
arch/powerpc/include/asm/mmu_context.h +1 -2
-/*
- * switch_mm is the entry point called from the architecture independent
+/* switch_mm is the entry point called from the architecture independent

The same goes for just changing the comment style away from the usual ...

Yeah, I felt that file had way too much white space in it :-)

Quoted 10 lines

arch/powerpc/kernel/head_32.S start_here: · line 1054

Quoted 8 lines
arch/powerpc/kernel/head_32.S +1 -1
@@ -1050,7 +1051,7 @@ start_here:
 	 * We do this here because we know the mmu is disabled, and
 	 * will be enabled for real in just a few instructions.
 	 */
-	lis	r5, abatron_pteptrs@h
+	lis	r5, abatron_pteptrs@h\
                                     ^

Is this right?

Nope.

I really should review my own patches before posting them :-) Guess I was in a hurry to go home.

Quoted 7 lines
Quoted 7 lines
arch/powerpc/kernel/head_32.S +7 -0
+++ linux-work/arch/powerpc/mm/mmu_context_hash32.c	2008-12-03 13:50:18.000000000 +1100
+/*
+ * This function defines the mapping from contexts to VSIDs (virtual
+ * segment IDs).  We use a skew on both the context and the high 4 bits
+ * of the 32-bit virtual address (the "effective segment ID") in order
+ * to spread out the entries in the MMU hash table.  Note, if this
+ * function is changed then arch/ppc/mm/hashtable.S will have to be
Quoted 8 lines

arch/powerpc/kernel/head_32.S

Quoted 4 lines

+ * changed to correspond.
+ */

arch/powerpc/kernel/head_32.S +2 -0
+#define CTX_TO_VSID(ctx, va)	(((ctx) * (897 * 16) + ((va) >> 28) * 0x111) \
+				 & 0xffffff)

Any reason this is not a static inline function? Hmmm, actually it doesn't look like it is used anywhere ... I guess its just for documentation?

This is just moved from it's previous location in mmu_context.h, and yes, as it is, it's mostly documentation.

Quoted 9 lines
Quoted 9 lines

+++ linux-work/arch/powerpc/mm/mmu_context_nohash.c 2008-12-03 13:50:18.000000000 +1100

arch/powerpc/kernel/head_32.S +8 -0
+#ifdef CONFIG_8xx
+#define NO_CONTEXT      	16
+#define LAST_CONTEXT    	15
+#define FIRST_CONTEXT    	0
+
+#elif defined(CONFIG_4xx)
+#define NO_CONTEXT      	256
+#define LAST_CONTEXT    	255
Quoted 8 lines

arch/powerpc/kernel/head_32.S

Quoted 6 lines
arch/powerpc/kernel/head_32.S +6 -0
+#define FIRST_CONTEXT    	1
+
+#elif defined(CONFIG_E200) || defined(CONFIG_E500)
+#define NO_CONTEXT      	256
+#define LAST_CONTEXT    	255
+#define FIRST_CONTEXT    	1

Why not combine these last two?

I think some FSL can get more contexts, dunno, this is also just existing code moved. In any case, I plan to remove those and make the whole context count runtime selected anyway.

Quoted 8 lines

arch/powerpc/kernel/head_32.S

Quoted 5 lines
arch/powerpc/kernel/head_32.S +4 -0
+static unsigned long next_mmu_context;
 
+	/* free up context `next_mmu_context' */
+	/* if we shouldn't free context 0, don't... */
+	if (next_mmu_context < FIRST_CONTEXT)

If FIRST_CONTEXT is 0, this will generate a compiler warning (as next_mmu_context can't be < 0).

Same as above, existing code moved from mmu_context_32.c, not the place to change that though it's a good catch. I don't think I still have this issue after the next patch but I'll dbl check.

Quoted 9 lines

arch/powerpc/kernel/head_32.S

Quoted 7 lines
arch/powerpc/kernel/head_32.S +7 -0
+config PPC_MMU_NOHASH_32
+	def_bool y
+	depends on PPC_MMU_NOHASH && PPC32
+
+config PPC_MMU_NOHASH_64
+	def_bool y
+	depends on PPC_MMU_NOHASH && PPC64

Neither of these are used anywhere.

Right well... I had something in mind for those that didn't make it into this patch, I can remove them.

Cheers,
Ben.

#3 lore raw
In reply to Benjamin Herrenschmidt

On Thu, 04 Dec 2008 16:41:48 +1100
Benjamin Herrenschmidt <[email protected]> wrote:

Stephen had a bunch of comments as well, so I'll spare you those again...

arch/powerpc/mm/mmu_context_nohash.c line 6

Quoted 11 lines

Index: linux-work/arch/powerpc/mm/mmu_context_nohash.c
===================================================================

arch/powerpc/mm/mmu_context_nohash.c new file +6 -0
@@ -0,0 +1,168 @@
+/*
+ * This file contains the routines for handling the MMU on those
+ * PowerPC implementations where the MMU substantially follows the
+ * architecture specification.  This includes the 6xx, 7xx, 7xxx,
+ * 8260, and POWER3 implementations but excludes the 8xx and 4xx.
+ *  -- paulus

..but I couldn't let this one go. Totally incorrect comments here given that the file is _for_ 8xx and 4xx. I suspect an errant copy/paste :).

josh

#4 lore raw
Quoted 2 lines · Josh Boyer

..but I couldn't let this one go. Totally incorrect comments here given that the file is _for_ 8xx and 4xx. I suspect an errant copy/paste :).

Or rather blame "cp" :-) I just duplicated mmu_context_32.c and modified both versions differently. Forgot that comment obviously, thanks.

Ben.