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);
next prev parent 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 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.