aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-06-11 01:37:10 -0400
committerPaul Mackerras <paulus@samba.org>2008-06-30 08:30:53 -0400
commit41743a4e34f0777f51c1cf0675b91508ba143050 (patch)
tree9e63c8c8d70169e6c8be699167234db33b102a1f
parentff1f4ee94c3c4480b9cee95da2d19668262636c6 (diff)
powerpc: Free a PTE bit on ppc64 with 64K pages
This frees a PTE bit when using 64K pages on ppc64. This is done by getting rid of the separate _PAGE_HASHPTE bit. Instead, we just test if any of the 16 sub-page bits is set. For non-combo pages (ie. real 64K pages), we set SUB0 and the location encoding in that field. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/mm/hash_low_64.S17
-rw-r--r--arch/powerpc/mm/hugetlbpage.c8
-rw-r--r--include/asm-powerpc/pgtable-4k.h1
-rw-r--r--include/asm-powerpc/pgtable-64k.h17
-rw-r--r--include/asm-powerpc/pgtable-ppc64.h1
5 files changed, 31 insertions, 13 deletions
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
index 70f4c833fa32..a719f53921a5 100644
--- a/arch/powerpc/mm/hash_low_64.S
+++ b/arch/powerpc/mm/hash_low_64.S
@@ -388,7 +388,7 @@ _GLOBAL(__hash_page_4K)
388 */ 388 */
389 rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */ 389 rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
390 or r30,r30,r31 390 or r30,r30,r31
391 ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE 391 ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED
392 oris r30,r30,_PAGE_COMBO@h 392 oris r30,r30,_PAGE_COMBO@h
393 /* Write the linux PTE atomically (setting busy) */ 393 /* Write the linux PTE atomically (setting busy) */
394 stdcx. r30,0,r6 394 stdcx. r30,0,r6
@@ -468,7 +468,7 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
468 * go to out-of-line code to try to modify the HPTE. We look for 468 * go to out-of-line code to try to modify the HPTE. We look for
469 * the bit at (1 >> (index + 32)) 469 * the bit at (1 >> (index + 32))
470 */ 470 */
471 andi. r0,r31,_PAGE_HASHPTE 471 rldicl. r0,r31,64-12,48
472 li r26,0 /* Default hidx */ 472 li r26,0 /* Default hidx */
473 beq htab_insert_pte 473 beq htab_insert_pte
474 474
@@ -726,11 +726,11 @@ BEGIN_FTR_SECTION
726 bne- ht64_bail_ok 726 bne- ht64_bail_ok
727END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE) 727END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE)
728 /* Prepare new PTE value (turn access RW into DIRTY, then 728 /* Prepare new PTE value (turn access RW into DIRTY, then
729 * add BUSY,HASHPTE and ACCESSED) 729 * add BUSY and ACCESSED)
730 */ 730 */
731 rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */ 731 rlwinm r30,r4,32-9+7,31-7,31-7 /* _PAGE_RW -> _PAGE_DIRTY */
732 or r30,r30,r31 732 or r30,r30,r31
733 ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE 733 ori r30,r30,_PAGE_BUSY | _PAGE_ACCESSED
734 /* Write the linux PTE atomically (setting busy) */ 734 /* Write the linux PTE atomically (setting busy) */
735 stdcx. r30,0,r6 735 stdcx. r30,0,r6
736 bne- 1b 736 bne- 1b
@@ -798,18 +798,21 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
798 /* Check if we may already be in the hashtable, in this case, we 798 /* Check if we may already be in the hashtable, in this case, we
799 * go to out-of-line code to try to modify the HPTE 799 * go to out-of-line code to try to modify the HPTE
800 */ 800 */
801 andi. r0,r31,_PAGE_HASHPTE 801 rldicl. r0,r31,64-12,48
802 bne ht64_modify_pte 802 bne ht64_modify_pte
803 803
804ht64_insert_pte: 804ht64_insert_pte:
805 /* Clear hpte bits in new pte (we also clear BUSY btw) and 805 /* Clear hpte bits in new pte (we also clear BUSY btw) and
806 * add _PAGE_HASHPTE 806 * add _PAGE_HPTE_SUB0
807 */ 807 */
808 lis r0,_PAGE_HPTEFLAGS@h 808 lis r0,_PAGE_HPTEFLAGS@h
809 ori r0,r0,_PAGE_HPTEFLAGS@l 809 ori r0,r0,_PAGE_HPTEFLAGS@l
810 andc r30,r30,r0 810 andc r30,r30,r0
811#ifdef CONFIG_PPC_64K_PAGES
812 oris r30,r30,_PAGE_HPTE_SUB0@h
813#else
811 ori r30,r30,_PAGE_HASHPTE 814 ori r30,r30,_PAGE_HASHPTE
812 815#endif
813 /* Phyical address in r5 */ 816 /* Phyical address in r5 */
814 rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT 817 rldicl r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
815 sldi r5,r5,PAGE_SHIFT 818 sldi r5,r5,PAGE_SHIFT
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index a02266dad215..8fa07f3f6c2b 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -458,8 +458,7 @@ int hash_huge_page(struct mm_struct *mm, unsigned long access,
458 old_pte = pte_val(*ptep); 458 old_pte = pte_val(*ptep);
459 if (old_pte & _PAGE_BUSY) 459 if (old_pte & _PAGE_BUSY)
460 goto out; 460 goto out;
461 new_pte = old_pte | _PAGE_BUSY | 461 new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED;
462 _PAGE_ACCESSED | _PAGE_HASHPTE;
463 } while(old_pte != __cmpxchg_u64((unsigned long *)ptep, 462 } while(old_pte != __cmpxchg_u64((unsigned long *)ptep,
464 old_pte, new_pte)); 463 old_pte, new_pte));
465 464
@@ -499,8 +498,11 @@ repeat:
499 HPTES_PER_GROUP) & ~0x7UL; 498 HPTES_PER_GROUP) & ~0x7UL;
500 499
501 /* clear HPTE slot informations in new PTE */ 500 /* clear HPTE slot informations in new PTE */
501#ifdef CONFIG_PPC_64K_PAGES
502 new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HPTE_SUB0;
503#else
502 new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE; 504 new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | _PAGE_HASHPTE;
503 505#endif
504 /* Add in WIMG bits */ 506 /* Add in WIMG bits */
505 /* XXX We should store these in the pte */ 507 /* XXX We should store these in the pte */
506 /* --BenH: I think they are ... */ 508 /* --BenH: I think they are ... */
diff --git a/include/asm-powerpc/pgtable-4k.h b/include/asm-powerpc/pgtable-4k.h
index 818e2abc81e2..fd2090dc1dce 100644
--- a/include/asm-powerpc/pgtable-4k.h
+++ b/include/asm-powerpc/pgtable-4k.h
@@ -41,6 +41,7 @@
41#define PGDIR_MASK (~(PGDIR_SIZE-1)) 41#define PGDIR_MASK (~(PGDIR_SIZE-1))
42 42
43/* PTE bits */ 43/* PTE bits */
44#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
44#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */ 45#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */
45#define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */ 46#define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */
46#define _PAGE_F_SECOND _PAGE_SECONDARY 47#define _PAGE_F_SECOND _PAGE_SECONDARY
diff --git a/include/asm-powerpc/pgtable-64k.h b/include/asm-powerpc/pgtable-64k.h
index 1cbd6b377eea..c5007712473f 100644
--- a/include/asm-powerpc/pgtable-64k.h
+++ b/include/asm-powerpc/pgtable-64k.h
@@ -75,6 +75,20 @@ static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
75#define _PAGE_COMBO 0x10000000 /* this is a combo 4k page */ 75#define _PAGE_COMBO 0x10000000 /* this is a combo 4k page */
76#define _PAGE_4K_PFN 0x20000000 /* PFN is for a single 4k page */ 76#define _PAGE_4K_PFN 0x20000000 /* PFN is for a single 4k page */
77 77
78/* For 64K page, we don't have a separate _PAGE_HASHPTE bit. Instead,
79 * we set that to be the whole sub-bits mask. The C code will only
80 * test this, so a multi-bit mask will work. For combo pages, this
81 * is equivalent as effectively, the old _PAGE_HASHPTE was an OR of
82 * all the sub bits. For real 64k pages, we now have the assembly set
83 * _PAGE_HPTE_SUB0 in addition to setting the HIDX bits which overlap
84 * that mask. This is fine as long as the HIDX bits are never set on
85 * a PTE that isn't hashed, which is the case today.
86 *
87 * A little nit is for the huge page C code, which does the hashing
88 * in C, we need to provide which bit to use.
89 */
90#define _PAGE_HASHPTE _PAGE_HPTE_SUB
91
78/* Note the full page bits must be in the same location as for normal 92/* Note the full page bits must be in the same location as for normal
79 * 4k pages as the same asssembly will be used to insert 64K pages 93 * 4k pages as the same asssembly will be used to insert 64K pages
80 * wether the kernel has CONFIG_PPC_64K_PAGES or not 94 * wether the kernel has CONFIG_PPC_64K_PAGES or not
@@ -83,8 +97,7 @@ static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
83#define _PAGE_F_GIX 0x00007000 /* full page: hidx bits */ 97#define _PAGE_F_GIX 0x00007000 /* full page: hidx bits */
84 98
85/* PTE flags to conserve for HPTE identification */ 99/* PTE flags to conserve for HPTE identification */
86#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | _PAGE_HPTE_SUB |\ 100#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | _PAGE_COMBO)
87 _PAGE_COMBO)
88 101
89/* Shift to put page number into pte. 102/* Shift to put page number into pte.
90 * 103 *
diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h
index cc6a43ba41d0..2e48be841cc9 100644
--- a/include/asm-powerpc/pgtable-ppc64.h
+++ b/include/asm-powerpc/pgtable-ppc64.h
@@ -91,7 +91,6 @@
91#define _PAGE_DIRTY 0x0080 /* C: page changed */ 91#define _PAGE_DIRTY 0x0080 /* C: page changed */
92#define _PAGE_ACCESSED 0x0100 /* R: page referenced */ 92#define _PAGE_ACCESSED 0x0100 /* R: page referenced */
93#define _PAGE_RW 0x0200 /* software: user write access allowed */ 93#define _PAGE_RW 0x0200 /* software: user write access allowed */
94#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
95#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */ 94#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
96 95
97#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT) 96#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)