Home Home > GIT Browse
diff options
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2004-06-06 00:18:49 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-06-06 00:18:49 -0700
commit223666271d410d5f7e295ec0cb31dda842ced9bf (patch)
parent965fd9c7a9f3d40402aa0428c2e8a08d875e2933 (diff)
[PATCH] ppc32: Fix CPUs with soft loaded TLB
The recent introduction of ptep_set_access_flags() with the optimisation of not flushing the TLB unfortunately broke ppc32 CPUs with no hash table. The data access exception code path in assembly for these doesn't properly deal with the case where the TLB entry is present with the wrong PAGE_RW and will just call do_page_fault again instead of just replacing the TLB entry. Fixing the asm code for all the different CPU types affected (yah, embedded PPCs all have different MMUs =P) is painful and need testing I can't do at the moment, so here's a fix that will just flush the TLB page when changing the access flags on non-hash based machines. Please apply. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org
2 files changed, 16 insertions, 1 deletions
diff --git a/arch/ppc/mm/tlb.c b/arch/ppc/mm/tlb.c
index 3bf70f65f655..34605ba4ac2f 100644
--- a/arch/ppc/mm/tlb.c
+++ b/arch/ppc/mm/tlb.c
@@ -67,6 +67,17 @@ void flush_hash_one_pte(pte_t *ptep)
+ * Called by ptep_set_access_flags, must flush on CPUs for which the
+ * DSI handler can't just "fixup" the TLB on a write fault
+ */
+void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long addr)
+ if (Hash != 0)
+ return;
+ _tlbie(addr);
* Called at the end of a mmu_gather operation to make sure the
* TLB flush is completely done.
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index 976796d2f4c6..01256bda1d24 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -555,8 +555,12 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
pte_update(ptep, 0, bits);
#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
- __ptep_set_access_flags(__ptep, __entry, __dirty)
+ do { \
+ __ptep_set_access_flags(__ptep, __entry, __dirty); \
+ flush_tlb_page_nohash(__vma, __address); \
+ } while(0)
* Macro to mark a page protection value as "uncacheable".