Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge commit 'kumar/kumar-mmu'

+216 -47
+1 -1
arch/powerpc/include/asm/highmem.h
··· 84 84 #ifdef CONFIG_DEBUG_HIGHMEM 85 85 BUG_ON(!pte_none(*(kmap_pte-idx))); 86 86 #endif 87 - set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot)); 87 + __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot)); 88 88 flush_tlb_page(NULL, vaddr); 89 89 90 90 return (void*) vaddr;
+1 -1
arch/powerpc/include/asm/io.h
··· 711 711 /* 712 712 * Change "struct page" to physical address. 713 713 */ 714 - #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 714 + #define page_to_phys(page) ((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT) 715 715 716 716 /* We do NOT want virtual merging, it would put too much pressure on 717 717 * our iommu allocator. Instead, we want drivers to be smart enough
+7 -1
arch/powerpc/include/asm/page_32.h
··· 13 13 #define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES 14 14 #endif 15 15 16 + #ifdef CONFIG_PTE_64BIT 17 + #define PTE_FLAGS_OFFSET 4 /* offset of PTE flags, in bytes */ 18 + #else 19 + #define PTE_FLAGS_OFFSET 0 20 + #endif 21 + 16 22 #ifndef __ASSEMBLY__ 17 23 /* 18 24 * The basic type of a PTE - 64 bits for those CPUs with > 32 bit 19 - * physical addressing. For now this just the IBM PPC440. 25 + * physical addressing. 20 26 */ 21 27 #ifdef CONFIG_PTE_64BIT 22 28 typedef unsigned long long pte_basic_t;
+49 -10
arch/powerpc/include/asm/pgtable-ppc32.h
··· 261 261 #define _PAGE_HWEXEC 0x00000004 /* H: Execute permission */ 262 262 #define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */ 263 263 #define _PAGE_DIRTY 0x00000010 /* S: Page dirty */ 264 + #define _PAGE_SPECIAL 0x00000020 /* S: Special page */ 264 265 #define _PAGE_USER 0x00000040 /* S: User page */ 265 266 #define _PAGE_ENDIAN 0x00000080 /* H: E bit */ 266 267 #define _PAGE_GUARDED 0x00000100 /* H: G bit */ ··· 277 276 /* ERPN in a PTE never gets cleared, ignore it */ 278 277 #define _PTE_NONE_MASK 0xffffffff00000000ULL 279 278 279 + #define __HAVE_ARCH_PTE_SPECIAL 280 280 281 281 #elif defined(CONFIG_FSL_BOOKE) 282 282 /* ··· 307 305 #define _PAGE_COHERENT 0x00100 /* H: M bit */ 308 306 #define _PAGE_NO_CACHE 0x00200 /* H: I bit */ 309 307 #define _PAGE_WRITETHRU 0x00400 /* H: W bit */ 308 + #define _PAGE_SPECIAL 0x00800 /* S: Special page */ 310 309 311 310 #ifdef CONFIG_PTE_64BIT 312 311 /* ERPN in a PTE never gets cleared, ignore it */ ··· 317 314 #define _PMD_PRESENT 0 318 315 #define _PMD_PRESENT_MASK (PAGE_MASK) 319 316 #define _PMD_BAD (~PAGE_MASK) 317 + 318 + #define __HAVE_ARCH_PTE_SPECIAL 320 319 321 320 #elif defined(CONFIG_8xx) 322 321 /* Definitions for 8xx embedded chips. */ ··· 367 362 #define _PAGE_ACCESSED 0x100 /* R: page referenced */ 368 363 #define _PAGE_EXEC 0x200 /* software: i-cache coherency required */ 369 364 #define _PAGE_RW 0x400 /* software: user write access allowed */ 365 + #define _PAGE_SPECIAL 0x800 /* software: Special page */ 370 366 367 + #ifdef CONFIG_PTE_64BIT 368 + /* We never clear the high word of the pte */ 369 + #define _PTE_NONE_MASK (0xffffffff00000000ULL | _PAGE_HASHPTE) 370 + #else 371 371 #define _PTE_NONE_MASK _PAGE_HASHPTE 372 + #endif 372 373 373 374 #define _PMD_PRESENT 0 374 375 #define _PMD_PRESENT_MASK (PAGE_MASK) ··· 382 371 383 372 /* Hash table based platforms need atomic updates of the linux PTE */ 384 373 #define PTE_ATOMIC_UPDATES 1 374 + 375 + #define __HAVE_ARCH_PTE_SPECIAL 385 376 386 377 #endif 387 378 ··· 416 403 #endif 417 404 #ifndef _PAGE_WRITETHRU 418 405 #define _PAGE_WRITETHRU 0 406 + #endif 407 + #ifndef _PAGE_SPECIAL 408 + #define _PAGE_SPECIAL 0 419 409 #endif 420 410 #ifndef _PMD_PRESENT_MASK 421 411 #define _PMD_PRESENT_MASK _PMD_PRESENT ··· 533 517 534 518 #define pte_none(pte) ((pte_val(pte) & ~_PTE_NONE_MASK) == 0) 535 519 #define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) 536 - #define pte_clear(mm,addr,ptep) do { set_pte_at((mm), (addr), (ptep), __pte(0)); } while (0) 520 + #define pte_clear(mm, addr, ptep) \ 521 + do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0) 537 522 538 523 #define pmd_none(pmd) (!pmd_val(pmd)) 539 524 #define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD) ··· 550 533 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } 551 534 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } 552 535 static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } 553 - static inline int pte_special(pte_t pte) { return 0; } 536 + static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } 554 537 555 538 static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } 556 539 static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } ··· 569 552 static inline pte_t pte_mkyoung(pte_t pte) { 570 553 pte_val(pte) |= _PAGE_ACCESSED; return pte; } 571 554 static inline pte_t pte_mkspecial(pte_t pte) { 572 - return pte; } 555 + pte_val(pte) |= _PAGE_SPECIAL; return pte; } 573 556 static inline unsigned long pte_pgprot(pte_t pte) 574 557 { 575 558 return __pgprot(pte_val(pte)) & PAGE_PROT_BITS; ··· 591 574 /* Add an HPTE to the hash table */ 592 575 extern void add_hash_page(unsigned context, unsigned long va, 593 576 unsigned long pmdval); 577 + 578 + /* Flush an entry from the TLB/hash table */ 579 + extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, 580 + unsigned long address); 594 581 595 582 /* 596 583 * Atomic PTE updates. ··· 633 612 return old; 634 613 } 635 614 #else /* CONFIG_PTE_64BIT */ 636 - /* TODO: Change that to only modify the low word and move set_pte_at() 637 - * out of line 638 - */ 639 615 static inline unsigned long long pte_update(pte_t *p, 640 616 unsigned long clr, 641 617 unsigned long set) ··· 670 652 * On machines which use an MMU hash table we avoid changing the 671 653 * _PAGE_HASHPTE bit. 672 654 */ 655 + 656 + static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, 657 + pte_t *ptep, pte_t pte) 658 + { 659 + #if (_PAGE_HASHPTE != 0) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT) 660 + pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE); 661 + #elif defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) 662 + #if _PAGE_HASHPTE != 0 663 + if (pte_val(*ptep) & _PAGE_HASHPTE) 664 + flush_hash_entry(mm, ptep, addr); 665 + #endif 666 + __asm__ __volatile__("\ 667 + stw%U0%X0 %2,%0\n\ 668 + eieio\n\ 669 + stw%U0%X0 %L2,%1" 670 + : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) 671 + : "r" (pte) : "memory"); 672 + #else 673 + *ptep = (*ptep & _PAGE_HASHPTE) | (pte & ~_PAGE_HASHPTE); 674 + #endif 675 + } 676 + 673 677 static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, 674 678 pte_t *ptep, pte_t pte) 675 679 { 676 - #if _PAGE_HASHPTE != 0 677 - pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE); 678 - #else 679 - *ptep = pte; 680 + #if defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) 681 + WARN_ON(pte_present(*ptep)); 680 682 #endif 683 + __set_pte_at(mm, addr, ptep, pte); 681 684 } 682 685 683 686 /*
+7
arch/powerpc/include/asm/reg_booke.h
··· 109 109 #define SPRN_EVPR 0x3D6 /* Exception Vector Prefix Register */ 110 110 #define SPRN_L1CSR0 0x3F2 /* L1 Cache Control and Status Register 0 */ 111 111 #define SPRN_L1CSR1 0x3F3 /* L1 Cache Control and Status Register 1 */ 112 + #define SPRN_MMUCSR0 0x3F4 /* MMU Control and Status Register 0 */ 112 113 #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ 113 114 #define SPRN_BUCSR 0x3F5 /* Branch Unit Control and Status */ 114 115 #define SPRN_L2CSR0 0x3F9 /* L2 Data Cache Control and Status Register 0 */ ··· 410 409 #define L2CSR0_L2LFC 0x00000400 /* L2 Cache Lock Flash Clear */ 411 410 #define L2CSR0_L2LOA 0x00000080 /* L2 Cache Lock Overflow Allocate */ 412 411 #define L2CSR0_L2LO 0x00000020 /* L2 Cache Lock Overflow */ 412 + 413 + /* Bit definitions for MMUCSR0 */ 414 + #define MMUCSR0_TLB1FI 0x00000002 /* TLB1 Flash invalidate */ 415 + #define MMUCSR0_TLB0FI 0x00000004 /* TLB0 Flash invalidate */ 416 + #define MMUCSR0_TLB2FI 0x00000040 /* TLB2 Flash invalidate */ 417 + #define MMUCSR0_TLB3FI 0x00000020 /* TLB3 Flash invalidate */ 413 418 414 419 /* Bit definitions for SGR. */ 415 420 #define SGR_NORMAL 0 /* Speculative fetching allowed. */
+8 -5
arch/powerpc/include/asm/tlbflush.h
··· 29 29 #include <linux/mm.h> 30 30 31 31 extern void _tlbie(unsigned long address, unsigned int pid); 32 + extern void _tlbil_all(void); 33 + extern void _tlbil_pid(unsigned int pid); 34 + extern void _tlbil_va(unsigned long address, unsigned int pid); 32 35 33 36 #if defined(CONFIG_40x) || defined(CONFIG_8xx) 34 37 #define _tlbia() asm volatile ("tlbia; sync" : : : "memory") ··· 41 38 42 39 static inline void flush_tlb_mm(struct mm_struct *mm) 43 40 { 44 - _tlbia(); 41 + _tlbil_pid(mm->context.id); 45 42 } 46 43 47 44 static inline void flush_tlb_page(struct vm_area_struct *vma, 48 45 unsigned long vmaddr) 49 46 { 50 - _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0); 47 + _tlbil_va(vmaddr, vma ? vma->vm_mm->context.id : 0); 51 48 } 52 49 53 50 static inline void flush_tlb_page_nohash(struct vm_area_struct *vma, 54 51 unsigned long vmaddr) 55 52 { 56 - _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0); 53 + flush_tlb_page(vma, vmaddr); 57 54 } 58 55 59 56 static inline void flush_tlb_range(struct vm_area_struct *vma, 60 57 unsigned long start, unsigned long end) 61 58 { 62 - _tlbia(); 59 + _tlbil_pid(vma->vm_mm->context.id); 63 60 } 64 61 65 62 static inline void flush_tlb_kernel_range(unsigned long start, 66 63 unsigned long end) 67 64 { 68 - _tlbia(); 65 + _tlbil_pid(0); 69 66 } 70 67 71 68 #elif defined(CONFIG_PPC32)
+1
arch/powerpc/kernel/asm-offsets.c
··· 352 352 #endif 353 353 354 354 DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE); 355 + DEFINE(PTE_SIZE, sizeof(pte_t)); 355 356 356 357 #ifdef CONFIG_KVM 357 358 DEFINE(TLBE_BYTES, sizeof(struct tlbe));
+2 -2
arch/powerpc/kernel/head_32.S
··· 369 369 DataAccess: 370 370 EXCEPTION_PROLOG 371 371 mfspr r10,SPRN_DSISR 372 + stw r10,_DSISR(r11) 372 373 andis. r0,r10,0xa470 /* weird error? */ 373 374 bne 1f /* if not, try to put a PTE */ 374 375 mfspr r4,SPRN_DAR /* into the hash table */ 375 376 rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */ 376 377 bl hash_page 377 - 1: stw r10,_DSISR(r11) 378 - mr r5,r10 378 + 1: lwz r5,_DSISR(r11) /* get DSISR value */ 379 379 mfspr r4,SPRN_DAR 380 380 EXC_XFER_EE_LITE(0x300, handle_page_fault) 381 381
-2
arch/powerpc/kernel/head_fsl_booke.S
··· 422 422 * r12 is pointer to the pte 423 423 */ 424 424 #ifdef CONFIG_PTE_64BIT 425 - #define PTE_FLAGS_OFFSET 4 426 425 #define FIND_PTE \ 427 426 rlwinm r12, r10, 13, 19, 29; /* Compute pgdir/pmd offset */ \ 428 427 lwzx r11, r12, r11; /* Get pgd/pmd entry */ \ ··· 430 431 rlwimi r12, r10, 23, 20, 28; /* Compute pte address */ \ 431 432 lwz r11, 4(r12); /* Get pte entry */ 432 433 #else 433 - #define PTE_FLAGS_OFFSET 0 434 434 #define FIND_PTE \ 435 435 rlwimi r11, r10, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \ 436 436 lwz r11, 0(r11); /* Get L1 entry */ \
+54
arch/powerpc/kernel/misc_32.S
··· 274 274 /* 275 275 * Flush MMU TLB 276 276 */ 277 + #ifndef CONFIG_FSL_BOOKE 278 + _GLOBAL(_tlbil_all) 279 + _GLOBAL(_tlbil_pid) 280 + #endif 277 281 _GLOBAL(_tlbia) 278 282 #if defined(CONFIG_40x) 279 283 sync /* Flush to memory before changing mapping */ ··· 348 344 /* 349 345 * Flush MMU TLB for a particular address 350 346 */ 347 + #ifndef CONFIG_FSL_BOOKE 348 + _GLOBAL(_tlbil_va) 349 + #endif 351 350 _GLOBAL(_tlbie) 352 351 #if defined(CONFIG_40x) 353 352 /* We run the search with interrupts disabled because we have to change ··· 442 435 #endif /* CONFIG_SMP */ 443 436 #endif /* ! CONFIG_40x */ 444 437 blr 438 + 439 + #if defined(CONFIG_FSL_BOOKE) 440 + /* 441 + * Flush MMU TLB, but only on the local processor (no broadcast) 442 + */ 443 + _GLOBAL(_tlbil_all) 444 + #define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \ 445 + MMUCSR0_TLB2FI | MMUCSR0_TLB3FI) 446 + li r3,(MMUCSR0_TLBFI)@l 447 + mtspr SPRN_MMUCSR0, r3 448 + 1: 449 + mfspr r3,SPRN_MMUCSR0 450 + andi. r3,r3,MMUCSR0_TLBFI@l 451 + bne 1b 452 + blr 453 + 454 + /* 455 + * Flush MMU TLB for a particular process id, but only on the local processor 456 + * (no broadcast) 457 + */ 458 + _GLOBAL(_tlbil_pid) 459 + /* we currently do an invalidate all since we don't have per pid invalidate */ 460 + li r3,(MMUCSR0_TLBFI)@l 461 + mtspr SPRN_MMUCSR0, r3 462 + 1: 463 + mfspr r3,SPRN_MMUCSR0 464 + andi. r3,r3,MMUCSR0_TLBFI@l 465 + bne 1b 466 + blr 467 + 468 + /* 469 + * Flush MMU TLB for a particular address, but only on the local processor 470 + * (no broadcast) 471 + */ 472 + _GLOBAL(_tlbil_va) 473 + slwi r4,r4,16 474 + mtspr SPRN_MAS6,r4 /* assume AS=0 for now */ 475 + tlbsx 0,r3 476 + mfspr r4,SPRN_MAS1 /* check valid */ 477 + andis. r3,r4,MAS1_VALID@h 478 + beqlr 479 + rlwinm r4,r4,0,1,31 480 + mtspr SPRN_MAS1,r4 481 + tlbwe 482 + blr 483 + #endif /* CONFIG_FSL_BOOKE */ 484 + 445 485 446 486 /* 447 487 * Flush instruction cache.
+3
arch/powerpc/kernel/ppc_ksyms.c
··· 119 119 EXPORT_SYMBOL(flush_tlb_kernel_range); 120 120 EXPORT_SYMBOL(flush_tlb_page); 121 121 EXPORT_SYMBOL(_tlbie); 122 + #if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE) 123 + EXPORT_SYMBOL(_tlbil_va); 124 + #endif 122 125 #endif 123 126 EXPORT_SYMBOL(__flush_icache_range); 124 127 EXPORT_SYMBOL(flush_dcache_range);
+70 -16
arch/powerpc/mm/hash_low_32.S
··· 75 75 * Returns to the caller if the access is illegal or there is no 76 76 * mapping for the address. Otherwise it places an appropriate PTE 77 77 * in the hash table and returns from the exception. 78 - * Uses r0, r3 - r8, ctr, lr. 78 + * Uses r0, r3 - r8, r10, ctr, lr. 79 79 */ 80 80 .text 81 81 _GLOBAL(hash_page) ··· 106 106 addi r5,r5,swapper_pg_dir@l /* kernel page table */ 107 107 rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */ 108 108 112: add r5,r5,r7 /* convert to phys addr */ 109 + #ifndef CONFIG_PTE_64BIT 109 110 rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */ 110 111 lwz r8,0(r5) /* get pmd entry */ 111 112 rlwinm. r8,r8,0,0,19 /* extract address of pte page */ 113 + #else 114 + rlwinm r8,r4,13,19,29 /* Compute pgdir/pmd offset */ 115 + lwzx r8,r8,r5 /* Get L1 entry */ 116 + rlwinm. r8,r8,0,0,20 /* extract pt base address */ 117 + #endif 112 118 #ifdef CONFIG_SMP 113 119 beq- hash_page_out /* return if no mapping */ 114 120 #else ··· 124 118 to the address following the rfi. */ 125 119 beqlr- 126 120 #endif 121 + #ifndef CONFIG_PTE_64BIT 127 122 rlwimi r8,r4,22,20,29 /* insert next 10 bits of address */ 123 + #else 124 + rlwimi r8,r4,23,20,28 /* compute pte address */ 125 + #endif 128 126 rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ 129 127 ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE 130 128 ··· 137 127 * because almost always, there won't be a permission violation 138 128 * and there won't already be an HPTE, and thus we will have 139 129 * to update the PTE to set _PAGE_HASHPTE. -- paulus. 130 + * 131 + * If PTE_64BIT is set, the low word is the flags word; use that 132 + * word for locking since it contains all the interesting bits. 140 133 */ 134 + #if (PTE_FLAGS_OFFSET != 0) 135 + addi r8,r8,PTE_FLAGS_OFFSET 136 + #endif 141 137 retry: 142 - lwarx r6,0,r8 /* get linux-style pte */ 138 + lwarx r6,0,r8 /* get linux-style pte, flag word */ 143 139 andc. r5,r3,r6 /* check access & ~permission */ 144 140 #ifdef CONFIG_SMP 145 141 bne- hash_page_out /* return if access not permitted */ ··· 153 137 bnelr- 154 138 #endif 155 139 or r5,r0,r6 /* set accessed/dirty bits */ 140 + #ifdef CONFIG_PTE_64BIT 141 + #ifdef CONFIG_SMP 142 + subf r10,r6,r8 /* create false data dependency */ 143 + subi r10,r10,PTE_FLAGS_OFFSET 144 + lwzx r10,r6,r10 /* Get upper PTE word */ 145 + #else 146 + lwz r10,-PTE_FLAGS_OFFSET(r8) 147 + #endif /* CONFIG_SMP */ 148 + #endif /* CONFIG_PTE_64BIT */ 156 149 stwcx. r5,0,r8 /* attempt to update PTE */ 157 150 bne- retry /* retry if someone got there first */ 158 151 ··· 228 203 * we can't take a hash table miss (assuming the code is 229 204 * covered by a BAT). -- paulus 230 205 */ 231 - mfmsr r10 206 + mfmsr r9 232 207 SYNC 233 - rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ 208 + rlwinm r0,r9,0,17,15 /* clear bit 16 (MSR_EE) */ 234 209 rlwinm r0,r0,0,28,26 /* clear MSR_DR */ 235 210 mtmsr r0 236 211 SYNC_601 ··· 239 214 tophys(r7,0) 240 215 241 216 #ifdef CONFIG_SMP 242 - addis r9,r7,mmu_hash_lock@ha 243 - addi r9,r9,mmu_hash_lock@l 244 - 10: lwarx r0,0,r9 /* take the mmu_hash_lock */ 217 + addis r6,r7,mmu_hash_lock@ha 218 + addi r6,r6,mmu_hash_lock@l 219 + 10: lwarx r0,0,r6 /* take the mmu_hash_lock */ 245 220 cmpi 0,r0,0 246 221 bne- 11f 247 - stwcx. r8,0,r9 222 + stwcx. r8,0,r6 248 223 beq+ 12f 249 - 11: lwz r0,0(r9) 224 + 11: lwz r0,0(r6) 250 225 cmpi 0,r0,0 251 226 beq 10b 252 227 b 11b ··· 259 234 * HPTE, so we just unlock and return. 260 235 */ 261 236 mr r8,r5 237 + #ifndef CONFIG_PTE_64BIT 262 238 rlwimi r8,r4,22,20,29 239 + #else 240 + rlwimi r8,r4,23,20,28 241 + addi r8,r8,PTE_FLAGS_OFFSET 242 + #endif 263 243 1: lwarx r6,0,r8 264 244 andi. r0,r6,_PAGE_HASHPTE 265 245 bne 9f /* if HASHPTE already set, done */ 246 + #ifdef CONFIG_PTE_64BIT 247 + #ifdef CONFIG_SMP 248 + subf r10,r6,r8 /* create false data dependency */ 249 + subi r10,r10,PTE_FLAGS_OFFSET 250 + lwzx r10,r6,r10 /* Get upper PTE word */ 251 + #else 252 + lwz r10,-PTE_FLAGS_OFFSET(r8) 253 + #endif /* CONFIG_SMP */ 254 + #endif /* CONFIG_PTE_64BIT */ 266 255 ori r5,r6,_PAGE_HASHPTE 267 256 stwcx. r5,0,r8 268 257 bne- 1b ··· 285 246 286 247 9: 287 248 #ifdef CONFIG_SMP 249 + addis r6,r7,mmu_hash_lock@ha 250 + addi r6,r6,mmu_hash_lock@l 288 251 eieio 289 252 li r0,0 290 - stw r0,0(r9) /* clear mmu_hash_lock */ 253 + stw r0,0(r6) /* clear mmu_hash_lock */ 291 254 #endif 292 255 293 256 /* reenable interrupts and DR */ 294 - mtmsr r10 257 + mtmsr r9 295 258 SYNC_601 296 259 isync 297 260 ··· 308 267 * r5 contains the linux PTE, r6 contains the old value of the 309 268 * linux PTE (before setting _PAGE_HASHPTE) and r7 contains the 310 269 * offset to be added to addresses (0 if the MMU is on, 311 - * -KERNELBASE if it is off). 270 + * -KERNELBASE if it is off). r10 contains the upper half of 271 + * the PTE if CONFIG_PTE_64BIT. 312 272 * On SMP, the caller should have the mmu_hash_lock held. 313 273 * We assume that the caller has (or will) set the _PAGE_HASHPTE 314 274 * bit in the linux PTE in memory. The value passed in r6 should ··· 355 313 BEGIN_FTR_SECTION 356 314 ori r8,r8,_PAGE_COHERENT /* set M (coherence required) */ 357 315 END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT) 316 + #ifdef CONFIG_PTE_64BIT 317 + /* Put the XPN bits into the PTE */ 318 + rlwimi r8,r10,8,20,22 319 + rlwimi r8,r10,2,29,29 320 + #endif 358 321 359 322 /* Construct the high word of the PPC-style PTE (r5) */ 360 323 rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ ··· 546 499 isync 547 500 548 501 /* First find a PTE in the range that has _PAGE_HASHPTE set */ 502 + #ifndef CONFIG_PTE_64BIT 549 503 rlwimi r5,r4,22,20,29 550 - 1: lwz r0,0(r5) 504 + #else 505 + rlwimi r5,r4,23,20,28 506 + #endif 507 + 1: lwz r0,PTE_FLAGS_OFFSET(r5) 551 508 cmpwi cr1,r6,1 552 509 andi. r0,r0,_PAGE_HASHPTE 553 510 bne 2f 554 511 ble cr1,19f 555 512 addi r4,r4,0x1000 556 - addi r5,r5,4 513 + addi r5,r5,PTE_SIZE 557 514 addi r6,r6,-1 558 515 b 1b 559 516 ··· 596 545 * already clear, we're done (for this pte). If not, 597 546 * clear it (atomically) and proceed. -- paulus. 598 547 */ 599 - 33: lwarx r8,0,r5 /* fetch the pte */ 548 + #if (PTE_FLAGS_OFFSET != 0) 549 + addi r5,r5,PTE_FLAGS_OFFSET 550 + #endif 551 + 33: lwarx r8,0,r5 /* fetch the pte flags word */ 600 552 andi. r0,r8,_PAGE_HASHPTE 601 553 beq 8f /* done if HASHPTE is already clear */ 602 554 rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */ ··· 644 590 645 591 8: ble cr1,9f /* if all ptes checked */ 646 592 81: addi r6,r6,-1 647 - addi r5,r5,4 /* advance to next pte */ 593 + addi r5,r5,PTE_SIZE 648 594 addi r4,r4,0x1000 649 595 lwz r0,0(r5) /* check next pte */ 650 596 cmpwi cr1,r6,1
+2 -2
arch/powerpc/mm/pgtable_32.c
··· 73 73 #endif /* HAVE_TLBCAM */ 74 74 75 75 #ifdef CONFIG_PTE_64BIT 76 - /* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */ 76 + /* Some processors use an 8kB pgdir because they have 8-byte Linux PTEs. */ 77 77 #define PGDIR_ORDER 1 78 78 #else 79 79 #define PGDIR_ORDER 0 ··· 288 288 } 289 289 290 290 /* 291 - * Map in all of physical memory starting at KERNELBASE. 291 + * Map in a big chunk of physical memory starting at KERNELBASE. 292 292 */ 293 293 void __init mapin_ram(void) 294 294 {
+1
arch/powerpc/mm/tlb_32.c
··· 45 45 flush_hash_pages(mm->context.id, addr, ptephys, 1); 46 46 } 47 47 } 48 + EXPORT_SYMBOL(flush_hash_entry); 48 49 49 50 /* 50 51 * Called by ptep_set_access_flags, must flush on CPUs for which the
+10 -7
arch/powerpc/platforms/Kconfig.cputype
··· 50 50 select PPC_UDBG_16550 51 51 select 4xx_SOC 52 52 select PPC_PCI_CHOICE 53 + select PHYS_64BIT 53 54 54 55 config E200 55 56 bool "Freescale e200" ··· 129 128 130 129 config PTE_64BIT 131 130 bool 132 - depends on 44x || E500 133 - default y if 44x 134 - default y if E500 && PHYS_64BIT 131 + depends on 44x || E500 || PPC_86xx 132 + default y if PHYS_64BIT 135 133 136 134 config PHYS_64BIT 137 - bool 'Large physical address support' if E500 138 - depends on 44x || E500 135 + bool 'Large physical address support' if E500 || PPC_86xx 136 + depends on (44x || E500 || PPC_86xx) && !PPC_83xx && !PPC_82xx 139 137 select RESOURCES_64BIT 140 - default y if 44x 141 138 ---help--- 142 139 This option enables kernel support for larger than 32-bit physical 143 - addresses. This features is not be available on all e500 cores. 140 + addresses. This feature may not be available on all cores. 141 + 142 + If you have more than 3.5GB of RAM or so, you also need to enable 143 + SWIOTLB under Kernel Options for this to work. The actual number 144 + is platform-dependent. 144 145 145 146 If in doubt, say N here. 146 147