diff options
-rw-r--r-- | arch/powerpc/mm/hash_low_32.S | 22 | ||||
-rw-r--r-- | arch/powerpc/mm/mem.c | 3 | ||||
-rw-r--r-- | arch/powerpc/mm/mmu_decl.h | 4 | ||||
-rw-r--r-- | arch/powerpc/mm/pgtable_32.c | 11 |
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 | |
404 | 1: 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; | |||
58 | int mem_init_done; | 58 | int mem_init_done; |
59 | unsigned long memory_limit; | 59 | unsigned long memory_limit; |
60 | 60 | ||
61 | extern void hash_preload(struct mm_struct *mm, unsigned long ea, | ||
62 | unsigned long access, unsigned long trap); | ||
63 | |||
64 | int page_is_ram(unsigned long pfn) | 61 | int 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 | ||
25 | extern 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 |
26 | extern void mapin_ram(void); | 30 | extern void mapin_ram(void); |
27 | extern int map_page(unsigned long va, phys_addr_t pa, int flags); | 31 | extern 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) | |||
282 | void __init mapin_ram(void) | 282 | void __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 | } |