diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 20:22:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 20:22:31 -0400 |
commit | 8e44e4347735229b518cc02938c351428bcd7492 (patch) | |
tree | e2d7b5998fa8ad76948b2e11591f4534f06f7958 /arch/powerpc/mm/pgtable.c | |
parent | 06aab5a3084e1d825384fa353e6df4c7949c8683 (diff) | |
parent | 09dd3fc19c09f79115267361ecd7d5c5d2c27a3a (diff) |
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
Fix build of cpm_uart due to core changes
powerpc/8xx: Fix regression introduced by cache coherency rewrite
powerpc/4xx: Fix erroneous xmon warning on PowerPC 4xx
powerpc/mm: Fix 40x and 8xx vs. _PAGE_SPECIAL
powerpc: Cleanup linker script using new linker script macros.
powerpc: Fix ibm,client-architecture-support printout
powerpc: Increase NODES_SHIFT on 64bit from 4 to 8
powerpc/perf_counter: Fix vdso detection
powerpc: Move 64bit heap above 1TB on machines with 1TB segments
powerpc: Change archdata dma_data to a union
powerpc: Rename get_dma_direct_offset get_dma_offset
powerpc/mm: Remove duplicated #include
powerpc/book3e-64: Remove duplicated #include
powerpc: Check for unsupported relocs when using CONFIG_RELOCATABLE
powerpc/pmc: Don't access lppaca on Book3E
powerpc: kmalloc failure ignored in vio_build_iommu_table()
hvc_console: Provide (un)locked version for hvc_resize()
Diffstat (limited to 'arch/powerpc/mm/pgtable.c')
-rw-r--r-- | arch/powerpc/mm/pgtable.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index 83f1551ec2c9..53040931de32 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <asm/tlbflush.h> | 30 | #include <asm/tlbflush.h> |
31 | #include <asm/tlb.h> | 31 | #include <asm/tlb.h> |
32 | 32 | ||
33 | #include "mmu_decl.h" | ||
34 | |||
33 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 35 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
34 | 36 | ||
35 | #ifdef CONFIG_SMP | 37 | #ifdef CONFIG_SMP |
@@ -166,7 +168,7 @@ struct page * maybe_pte_to_page(pte_t pte) | |||
166 | * support falls into the same category. | 168 | * support falls into the same category. |
167 | */ | 169 | */ |
168 | 170 | ||
169 | static pte_t set_pte_filter(pte_t pte) | 171 | static pte_t set_pte_filter(pte_t pte, unsigned long addr) |
170 | { | 172 | { |
171 | pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); | 173 | pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); |
172 | if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) || | 174 | if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) || |
@@ -175,6 +177,17 @@ static pte_t set_pte_filter(pte_t pte) | |||
175 | if (!pg) | 177 | if (!pg) |
176 | return pte; | 178 | return pte; |
177 | if (!test_bit(PG_arch_1, &pg->flags)) { | 179 | if (!test_bit(PG_arch_1, &pg->flags)) { |
180 | #ifdef CONFIG_8xx | ||
181 | /* On 8xx, cache control instructions (particularly | ||
182 | * "dcbst" from flush_dcache_icache) fault as write | ||
183 | * operation if there is an unpopulated TLB entry | ||
184 | * for the address in question. To workaround that, | ||
185 | * we invalidate the TLB here, thus avoiding dcbst | ||
186 | * misbehaviour. | ||
187 | */ | ||
188 | /* 8xx doesn't care about PID, size or ind args */ | ||
189 | _tlbil_va(addr, 0, 0, 0); | ||
190 | #endif /* CONFIG_8xx */ | ||
178 | flush_dcache_icache_page(pg); | 191 | flush_dcache_icache_page(pg); |
179 | set_bit(PG_arch_1, &pg->flags); | 192 | set_bit(PG_arch_1, &pg->flags); |
180 | } | 193 | } |
@@ -194,7 +207,7 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma, | |||
194 | * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so | 207 | * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so |
195 | * instead we "filter out" the exec permission for non clean pages. | 208 | * instead we "filter out" the exec permission for non clean pages. |
196 | */ | 209 | */ |
197 | static pte_t set_pte_filter(pte_t pte) | 210 | static pte_t set_pte_filter(pte_t pte, unsigned long addr) |
198 | { | 211 | { |
199 | struct page *pg; | 212 | struct page *pg; |
200 | 213 | ||
@@ -276,7 +289,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, | |||
276 | * this context might not have been activated yet when this | 289 | * this context might not have been activated yet when this |
277 | * is called. | 290 | * is called. |
278 | */ | 291 | */ |
279 | pte = set_pte_filter(pte); | 292 | pte = set_pte_filter(pte, addr); |
280 | 293 | ||
281 | /* Perform the setting of the PTE */ | 294 | /* Perform the setting of the PTE */ |
282 | __set_pte_at(mm, addr, ptep, pte, 0); | 295 | __set_pte_at(mm, addr, ptep, pte, 0); |