aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/mm/hash_low_32.S22
-rw-r--r--arch/powerpc/mm/mem.c3
-rw-r--r--arch/powerpc/mm/mmu_decl.h4
-rw-r--r--arch/powerpc/mm/pgtable_32.c11
4 files changed, 31 insertions, 9 deletions
diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S
index bd68df5fa78a..ddceefc06ecc 100644
--- a/arch/powerpc/mm/hash_low_32.S
+++ b/arch/powerpc/mm/hash_low_32.S
@@ -283,6 +283,7 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64)
283#define PTEG_SIZE 64 283#define PTEG_SIZE 64
284#define LG_PTEG_SIZE 6 284#define LG_PTEG_SIZE 6
285#define LDPTEu lwzu 285#define LDPTEu lwzu
286#define LDPTE lwz
286#define STPTE stw 287#define STPTE stw
287#define CMPPTE cmpw 288#define CMPPTE cmpw
288#define PTE_H 0x40 289#define PTE_H 0x40
@@ -389,13 +390,30 @@ _GLOBAL(hash_page_patch_C)
389 * and we know there is a definite (although small) speed 390 * and we know there is a definite (although small) speed
390 * advantage to putting the PTE in the primary PTEG, we always 391 * advantage to putting the PTE in the primary PTEG, we always
391 * put the PTE in the primary PTEG. 392 * put the PTE in the primary PTEG.
393 *
394 * In addition, we skip any slot that is mapping kernel text in
395 * order to avoid a deadlock when not using BAT mappings if
396 * trying to hash in the kernel hash code itself after it has
397 * already taken the hash table lock. This works in conjunction
398 * with pre-faulting of the kernel text.
399 *
400 * If the hash table bucket is full of kernel text entries, we'll
401 * lockup here but that shouldn't happen
392 */ 402 */
393 addis r4,r7,next_slot@ha 403
4041: addis r4,r7,next_slot@ha /* get next evict slot */
394 lwz r6,next_slot@l(r4) 405 lwz r6,next_slot@l(r4)
395 addi r6,r6,PTE_SIZE 406 addi r6,r6,PTE_SIZE /* search for candidate */
396 andi. r6,r6,7*PTE_SIZE 407 andi. r6,r6,7*PTE_SIZE
397 stw r6,next_slot@l(r4) 408 stw r6,next_slot@l(r4)
398 add r4,r3,r6 409 add r4,r3,r6
410 LDPTE r0,PTE_SIZE/2(r4) /* get PTE second word */
411 clrrwi r0,r0,12
412 lis r6,etext@h
413 ori r6,r6,etext@l /* get etext */
414 tophys(r6,r6)
415 cmpl cr0,r0,r6 /* compare and try again */
416 blt 1b
399 417
400#ifndef CONFIG_SMP 418#ifndef CONFIG_SMP
401 /* Store PTE in PTEG */ 419 /* Store PTE in PTEG */
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 52f397c108a7..c4bcd7546424 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -58,9 +58,6 @@ int init_bootmem_done;
58int mem_init_done; 58int mem_init_done;
59unsigned long memory_limit; 59unsigned long memory_limit;
60 60
61extern void hash_preload(struct mm_struct *mm, unsigned long ea,
62 unsigned long access, unsigned long trap);
63
64int page_is_ram(unsigned long pfn) 61int page_is_ram(unsigned long pfn)
65{ 62{
66 unsigned long paddr = (pfn << PAGE_SHIFT); 63 unsigned long paddr = (pfn << PAGE_SHIFT);
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index bea2d21ac6f7..ee55e0bb28bc 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -22,6 +22,10 @@
22#include <asm/tlbflush.h> 22#include <asm/tlbflush.h>
23#include <asm/mmu.h> 23#include <asm/mmu.h>
24 24
25extern void hash_preload(struct mm_struct *mm, unsigned long ea,
26 unsigned long access, unsigned long trap);
27
28
25#ifdef CONFIG_PPC32 29#ifdef CONFIG_PPC32
26extern void mapin_ram(void); 30extern void mapin_ram(void);
27extern int map_page(unsigned long va, phys_addr_t pa, int flags); 31extern int map_page(unsigned long va, phys_addr_t pa, int flags);
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 95d3afe36b51..f75f2fc7bc7e 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -282,16 +282,19 @@ int map_page(unsigned long va, phys_addr_t pa, int flags)
282void __init mapin_ram(void) 282void __init mapin_ram(void)
283{ 283{
284 unsigned long v, p, s, f; 284 unsigned long v, p, s, f;
285 int ktext;
285 286
286 s = mmu_mapin_ram(); 287 s = mmu_mapin_ram();
287 v = KERNELBASE + s; 288 v = KERNELBASE + s;
288 p = PPC_MEMSTART + s; 289 p = PPC_MEMSTART + s;
289 for (; s < total_lowmem; s += PAGE_SIZE) { 290 for (; s < total_lowmem; s += PAGE_SIZE) {
290 if ((char *) v >= _stext && (char *) v < etext) 291 ktext = ((char *) v >= _stext && (char *) v < etext);
291 f = _PAGE_RAM_TEXT; 292 f = ktext ?_PAGE_RAM_TEXT : _PAGE_RAM;
292 else
293 f = _PAGE_RAM;
294 map_page(v, p, f); 293 map_page(v, p, f);
294#ifdef CONFIG_PPC_STD_MMU_32
295 if (ktext)
296 hash_preload(&init_mm, v, 0, 0x300);
297#endif
295 v += PAGE_SIZE; 298 v += PAGE_SIZE;
296 p += PAGE_SIZE; 299 p += PAGE_SIZE;
297 } 300 }