aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-10-31 01:42:19 -0400
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>2007-11-01 08:15:30 -0400
commitb98ac05d5e460301fbea24cceed0f2a601c82e22 (patch)
tree2e556ad28a007d13339300fbbd4942d0ec9f023c /include/asm-powerpc
parente701d269aa28996f3502780951fe1b12d5d66b49 (diff)
[POWERPC] 4xx: Deal with 44x virtually tagged icache
The 44x family has an interesting "feature" which is a virtually tagged instruction cache (yuck !). So far, we haven't dealt with it properly, which means we've been mostly lucky or people didn't report the problems, unless people have been running custom patches in their distro... This is an attempt at fixing it properly. I chose to do it by setting a global flag whenever we change a PTE that was previously marked executable, and flush the entire instruction cache upon return to user space when that happens. This is a bit heavy handed, but it's hard to do more fine grained flushes as the icbi instruction, on those processor, for some very strange reasons (since the cache is virtually mapped) still requires a valid TLB entry for reading in the target address space, which isn't something I want to deal with. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r--include/asm-powerpc/pgtable-ppc32.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h
index 86a54a4a8a2a..fea2d8ff1e73 100644
--- a/include/asm-powerpc/pgtable-ppc32.h
+++ b/include/asm-powerpc/pgtable-ppc32.h
@@ -11,6 +11,11 @@
11extern unsigned long va_to_phys(unsigned long address); 11extern unsigned long va_to_phys(unsigned long address);
12extern pte_t *va_to_pte(unsigned long address); 12extern pte_t *va_to_pte(unsigned long address);
13extern unsigned long ioremap_bot, ioremap_base; 13extern unsigned long ioremap_bot, ioremap_base;
14
15#ifdef CONFIG_44x
16extern int icache_44x_need_flush;
17#endif
18
14#endif /* __ASSEMBLY__ */ 19#endif /* __ASSEMBLY__ */
15 20
16/* 21/*
@@ -562,6 +567,10 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr,
562 : "=&r" (old), "=&r" (tmp), "=m" (*p) 567 : "=&r" (old), "=&r" (tmp), "=m" (*p)
563 : "r" (p), "r" (clr), "r" (set), "m" (*p) 568 : "r" (p), "r" (clr), "r" (set), "m" (*p)
564 : "cc" ); 569 : "cc" );
570#ifdef CONFIG_44x
571 if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
572 icache_44x_need_flush = 1;
573#endif
565 return old; 574 return old;
566} 575}
567#else 576#else
@@ -582,6 +591,10 @@ static inline unsigned long long pte_update(pte_t *p, unsigned long clr,
582 : "=&r" (old), "=&r" (tmp), "=m" (*p) 591 : "=&r" (old), "=&r" (tmp), "=m" (*p)
583 : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p) 592 : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
584 : "cc" ); 593 : "cc" );
594#ifdef CONFIG_44x
595 if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
596 icache_44x_need_flush = 1;
597#endif
585 return old; 598 return old;
586} 599}
587#endif 600#endif