linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Matt Mackall <mpm@selenic.com>
Cc: linuxppc-dev list <linuxppc-dev@ozlabs.org>,
	Josh Boyer <jdub@us.ibm.com>,
	Kumar Gala <galak@gate.crashing.org>,
	linuxppc-embedded@ozlabs.org
Subject: [PATCH/RFC] powerpc: Pass PID argument to _tlbie (WAS: Apparent kernel bug with GDB on ppc405)
Date: Sat, 27 Oct 2007 17:32:02 +1000	[thread overview]
Message-ID: <1193470322.18243.63.camel@pasglop> (raw)
In-Reply-To: <1193448653.18243.9.camel@pasglop>

Allright, so Matt, let me know if that fixes your problem with gdb, and
I'll clean the patch up a bit and submit it. I want to double check if
something similar may be needed for freescale booke.

Basically, the problem is that things like get_user_pages() can cause
COW operations which in turn call _tlbie() to be called for translations
that aren't in the current address space.

The current 40x and 44x implementation of _tlbie doesn't handle that
properly as it only invalidates entries in the current PID.

This is an attempt at fixing it. Untested, I just checked it builds for
arch/powerpc and arch/ppc. I also haven't looked whether the freescale
BookE _tlbie needs similar treatement (it will get passed the pid in r4
with that patch, so if it needs to do something with it, it can). Kumar,
can you have a look ?

Index: linux-work/arch/powerpc/mm/fault.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/fault.c	2007-10-27 14:44:05.000000000 +1000
+++ linux-work/arch/powerpc/mm/fault.c	2007-10-27 16:57:50.000000000 +1000
@@ -309,7 +309,7 @@ good_area:
 					set_bit(PG_arch_1, &page->flags);
 				}
 				pte_update(ptep, 0, _PAGE_HWEXEC);
-				_tlbie(address);
+				_tlbie(address, mm->context.id);
 				pte_unmap_unlock(ptep, ptl);
 				up_read(&mm->mmap_sem);
 				return 0;
Index: linux-work/include/asm-powerpc/tlbflush.h
===================================================================
--- linux-work.orig/include/asm-powerpc/tlbflush.h	2007-10-27 14:44:19.000000000 +1000
+++ linux-work/include/asm-powerpc/tlbflush.h	2007-10-27 16:57:50.000000000 +1000
@@ -1,5 +1,8 @@
 #ifndef _ASM_POWERPC_TLBFLUSH_H
 #define _ASM_POWERPC_TLBFLUSH_H
+
+#include <linux/mm.h>
+
 /*
  * TLB flushing:
  *
@@ -16,9 +19,6 @@
  */
 #ifdef __KERNEL__
 
-struct mm_struct;
-struct vm_area_struct;
-
 #if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE)
 /*
  * TLB flushing for software loaded TLB chips
@@ -28,7 +28,7 @@ struct vm_area_struct;
  * specific tlbie's
  */
 
-extern void _tlbie(unsigned long address);
+extern void _tlbie(unsigned long address, unsigned int pid);
 
 #if defined(CONFIG_40x) || defined(CONFIG_8xx)
 #define _tlbia()	asm volatile ("tlbia; sync" : : : "memory")
@@ -44,13 +44,13 @@ static inline void flush_tlb_mm(struct m
 static inline void flush_tlb_page(struct vm_area_struct *vma,
 				  unsigned long vmaddr)
 {
-	_tlbie(vmaddr);
+	_tlbie(vmaddr, vma->vm_mm->context.id);
 }
 
 static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
 					 unsigned long vmaddr)
 {
-	_tlbie(vmaddr);
+	_tlbie(vmaddr, vma->vm_mm->context.id);
 }
 
 static inline void flush_tlb_range(struct vm_area_struct *vma,
Index: linux-work/arch/powerpc/kernel/misc_32.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/misc_32.S	2007-10-27 16:58:33.000000000 +1000
+++ linux-work/arch/powerpc/kernel/misc_32.S	2007-10-27 17:08:32.000000000 +1000
@@ -288,7 +288,16 @@ _GLOBAL(_tlbia)
  */
 _GLOBAL(_tlbie)
 #if defined(CONFIG_40x)
+	/* We run the search with interrupts disabled because we have to change
+	 * the PID and I don't want to preempt when that happens.
+	 */
+	mfmsr	r5
+	mfspr	r6,SPRN_PID
+	wrteei	0
+	mtspr	SPRN_PID,r4
 	tlbsx.	r3, 0, r3
+	mtspr	SPRN_PID,r6
+	wrtee	r5
 	bne	10f
 	sync
 	/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
@@ -297,23 +306,23 @@ _GLOBAL(_tlbie)
 	tlbwe	r3, r3, TLB_TAG
 	isync
 10:
+
 #elif defined(CONFIG_44x)
-	mfspr	r4,SPRN_MMUCR
-	mfspr	r5,SPRN_PID			/* Get PID */
-	rlwimi	r4,r5,0,24,31			/* Set TID */
+	mfspr	r5,SPRN_MMUCR
+	rlwimi	r5,r4,0,24,31			/* Set TID */
 
 	/* We have to run the search with interrupts disabled, even critical
 	 * and debug interrupts (in fact the only critical exceptions we have
 	 * are debug and machine check).  Otherwise  an interrupt which causes
 	 * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
-	mfmsr	r5
+	mfmsr	r4
 	lis	r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
 	addi	r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
-	andc	r6,r5,r6
+	andc	r6,r4,r6
 	mtmsr	r6
-	mtspr	SPRN_MMUCR,r4
+	mtspr	SPRN_MMUCR,r5
 	tlbsx.	r3, 0, r3
-	mtmsr	r5
+	mtmsr	r4
 	bne	10f
 	sync
 	/* There are only 64 TLB entries, so r3 < 64,
Index: linux-work/arch/powerpc/mm/mmu_decl.h
===================================================================
--- linux-work.orig/arch/powerpc/mm/mmu_decl.h	2007-10-27 17:11:33.000000000 +1000
+++ linux-work/arch/powerpc/mm/mmu_decl.h	2007-10-27 17:11:58.000000000 +1000
@@ -61,12 +61,12 @@ extern unsigned long total_lowmem;
 #define mmu_mapin_ram()		(0UL)
 
 #elif defined(CONFIG_4xx)
-#define flush_HPTE(X, va, pg)	_tlbie(va)
+#define flush_HPTE(pid, va, pg)	_tlbie(va, pid)
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(void);
 
 #elif defined(CONFIG_FSL_BOOKE)
-#define flush_HPTE(X, va, pg)	_tlbie(va)
+#define flush_HPTE(pid, va, pg)	_tlbie(va, pid)
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(void);
 extern void adjust_total_lowmem(void);
Index: linux-work/arch/ppc/kernel/misc.S
===================================================================
--- linux-work.orig/arch/ppc/kernel/misc.S	2007-10-27 17:15:25.000000000 +1000
+++ linux-work/arch/ppc/kernel/misc.S	2007-10-27 17:15:59.000000000 +1000
@@ -224,7 +224,16 @@ _GLOBAL(_tlbia)
  */
 _GLOBAL(_tlbie)
 #if defined(CONFIG_40x)
+	/* We run the search with interrupts disabled because we have to change
+	 * the PID and I don't want to preempt when that happens.
+	 */
+	mfmsr	r5
+	mfspr	r6,SPRN_PID
+	wrteei	0
+	mtspr	SPRN_PID,r4
 	tlbsx.	r3, 0, r3
+	mtspr	SPRN_PID,r6
+	wrtee	r5
 	bne	10f
 	sync
 	/* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
@@ -234,22 +243,21 @@ _GLOBAL(_tlbie)
 	isync
 10:
 #elif defined(CONFIG_44x)
-	mfspr	r4,SPRN_MMUCR
-	mfspr	r5,SPRN_PID			/* Get PID */
-	rlwimi	r4,r5,0,24,31			/* Set TID */
+	mfspr	r5,SPRN_MMUCR
+	rlwimi	r5,r4,0,24,31			/* Set TID */
 
 	/* We have to run the search with interrupts disabled, even critical
 	 * and debug interrupts (in fact the only critical exceptions we have
 	 * are debug and machine check).  Otherwise  an interrupt which causes
 	 * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
-	mfmsr	r5
+	mfmsr	r4
 	lis	r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
 	addi	r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
-	andc	r6,r5,r6
+	andc	r6,r4,r6
 	mtmsr	r6
-	mtspr	SPRN_MMUCR,r4
+	mtspr	SPRN_MMUCR,r5
 	tlbsx.	r3, 0, r3
-	mtmsr	r5
+	mtmsr	r4
 	bne	10f
 	sync
 	/* There are only 64 TLB entries, so r3 < 64,
Index: linux-work/arch/ppc/mm/fault.c
===================================================================
--- linux-work.orig/arch/ppc/mm/fault.c	2007-10-27 17:14:09.000000000 +1000
+++ linux-work/arch/ppc/mm/fault.c	2007-10-27 17:14:13.000000000 +1000
@@ -227,7 +227,7 @@ good_area:
 					set_bit(PG_arch_1, &page->flags);
 				}
 				pte_update(ptep, 0, _PAGE_HWEXEC);
-				_tlbie(address);
+				_tlbie(address, mm->context.id);
 				pte_unmap_unlock(ptep, ptl);
 				up_read(&mm->mmap_sem);
 				return 0;
Index: linux-work/arch/ppc/mm/mmu_decl.h
===================================================================
--- linux-work.orig/arch/ppc/mm/mmu_decl.h	2007-10-27 17:14:43.000000000 +1000
+++ linux-work/arch/ppc/mm/mmu_decl.h	2007-10-27 17:14:54.000000000 +1000
@@ -54,12 +54,12 @@ extern unsigned int num_tlbcam_entries;
 #define mmu_mapin_ram()		(0UL)
 
 #elif defined(CONFIG_4xx)
-#define flush_HPTE(X, va, pg)	_tlbie(va)
+#define flush_HPTE(pid, va, pg)	_tlbie(va, pid)
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(void);
 
 #elif defined(CONFIG_FSL_BOOKE)
-#define flush_HPTE(X, va, pg)	_tlbie(va)
+#define flush_HPTE(pid, va, pg)	_tlbie(va, pid)
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(void);
 extern void adjust_total_lowmem(void);
Index: linux-work/arch/ppc/platforms/4xx/ebony.c
===================================================================
--- linux-work.orig/arch/ppc/platforms/4xx/ebony.c	2007-10-27 17:13:38.000000000 +1000
+++ linux-work/arch/ppc/platforms/4xx/ebony.c	2007-10-27 17:13:40.000000000 +1000
@@ -236,7 +236,7 @@ ebony_early_serial_map(void)
 	gen550_init(0, &port);
 
 	/* Purge TLB entry added in head_44x.S for early serial access */
-	_tlbie(UART0_IO_BASE);
+	_tlbie(UART0_IO_BASE, 0);
 #endif
 
 	port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
Index: linux-work/arch/ppc/platforms/4xx/ocotea.c
===================================================================
--- linux-work.orig/arch/ppc/platforms/4xx/ocotea.c	2007-10-27 17:13:26.000000000 +1000
+++ linux-work/arch/ppc/platforms/4xx/ocotea.c	2007-10-27 17:13:28.000000000 +1000
@@ -259,7 +259,7 @@ ocotea_early_serial_map(void)
 	gen550_init(0, &port);
 
 	/* Purge TLB entry added in head_44x.S for early serial access */
-	_tlbie(UART0_IO_BASE);
+	_tlbie(UART0_IO_BASE, 0);
 #endif
 
 	port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
Index: linux-work/arch/ppc/platforms/4xx/taishan.c
===================================================================
--- linux-work.orig/arch/ppc/platforms/4xx/taishan.c	2007-10-27 17:13:47.000000000 +1000
+++ linux-work/arch/ppc/platforms/4xx/taishan.c	2007-10-27 17:13:50.000000000 +1000
@@ -316,7 +316,7 @@ taishan_early_serial_map(void)
 	gen550_init(0, &port);
 
 	/* Purge TLB entry added in head_44x.S for early serial access */
-	_tlbie(UART0_IO_BASE);
+	_tlbie(UART0_IO_BASE, 0);
 #endif
 
 	port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);

  reply	other threads:[~2007-10-27  7:32 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-24 19:46 Apparent kernel bug with GDB on ppc405 Matt Mackall
2007-10-24 20:28 ` Grant Likely
2007-10-24 20:42   ` Matt Mackall
2007-10-24 20:46     ` Grant Likely
2007-10-24 21:54     ` Matt Mackall
2007-10-24 22:27       ` Grant Likely
2007-10-24 22:32         ` Matt Mackall
2007-10-24 22:39           ` Grant Likely
2007-10-24 22:40             ` Grant Likely
2007-10-26  1:50               ` Benjamin Herrenschmidt
2007-10-24 22:41           ` Daniel Jacobowitz
2007-10-26  1:51             ` Benjamin Herrenschmidt
2007-10-26 20:41               ` Josh Boyer
2007-10-27  1:36                 ` Benjamin Herrenschmidt
2007-10-27  1:27                   ` Josh Boyer
2007-10-24 20:34 ` David Daney
2007-10-26  1:52   ` Benjamin Herrenschmidt
2007-10-26  1:46 ` Benjamin Herrenschmidt
2007-10-26  2:45   ` Grant Likely
2007-10-26  3:23     ` Benjamin Herrenschmidt
2007-10-26 14:41       ` Matt Mackall
2007-10-27  1:30         ` Benjamin Herrenschmidt
2007-10-27  7:32           ` Benjamin Herrenschmidt [this message]
2007-10-29 12:08             ` [PATCH/RFC] powerpc: Pass PID argument to _tlbie (WAS: Apparent kernel bug with GDB on ppc405) Josh Boyer
2007-10-29 20:15               ` Josh Boyer
2007-10-29 20:35                 ` Benjamin Herrenschmidt
2007-10-29 21:13                   ` Matt Mackall

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=1193470322.18243.63.camel@pasglop \
    --to=benh@kernel.crashing.org \
    --cc=galak@gate.crashing.org \
    --cc=jdub@us.ibm.com \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=linuxppc-embedded@ozlabs.org \
    --cc=mpm@selenic.com \
    /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 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).