aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-06-14 20:45:18 -0400
committerPaul Mackerras <paulus@samba.org>2006-06-14 20:45:18 -0400
commitbf72aeba2ffef599d1d386425c9e46b82be657cd (patch)
treeead8e5111dbcfa22e156999d1bb8a96e50f06fef /include
parent31925323b1b51bb65db729e029472a8b1f635b7d (diff)
powerpc: Use 64k pages without needing cache-inhibited large pages
Some POWER5+ machines can do 64k hardware pages for normal memory but not for cache-inhibited pages. This patch lets us use 64k hardware pages for most user processes on such machines (assuming the kernel has been configured with CONFIG_PPC_64K_PAGES=y). User processes start out using 64k pages and get switched to 4k pages if they use any non-cacheable mappings. With this, we use 64k pages for the vmalloc region and 4k pages for the imalloc region. If anything creates a non-cacheable mapping in the vmalloc region, the vmalloc region will get switched to 4k pages. I don't know of any driver other than the DRM that would do this, though, and these machines don't have AGP. When a region gets switched from 64k pages to 4k pages, we do not have to clear out all the 64k HPTEs from the hash table immediately. We use the _PAGE_COMBO bit in the Linux PTE to indicate whether the page was hashed in as a 64k page or a set of 4k pages. If hash_page is trying to insert a 4k page for a Linux PTE and it sees that it has already been inserted as a 64k page, it first invalidates the 64k HPTE before inserting the 4k HPTE. The hash invalidation routines also use the _PAGE_COMBO bit, to determine whether to look for a 64k HPTE or a set of 4k HPTEs to remove. With those two changes, we can tolerate a mix of 4k and 64k HPTEs in the hash table, and they will all get removed when the address space is torn down. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include')
-rw-r--r--include/asm-powerpc/mmu.h13
-rw-r--r--include/asm-powerpc/paca.h1
-rw-r--r--include/asm-powerpc/pgtable-4k.h2
-rw-r--r--include/asm-powerpc/pgtable-64k.h2
-rw-r--r--include/asm-powerpc/pgtable.h10
5 files changed, 20 insertions, 8 deletions
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h
index 885397420104..3a5ebe229af5 100644
--- a/include/asm-powerpc/mmu.h
+++ b/include/asm-powerpc/mmu.h
@@ -165,6 +165,16 @@ struct mmu_psize_def
165extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; 165extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
166extern int mmu_linear_psize; 166extern int mmu_linear_psize;
167extern int mmu_virtual_psize; 167extern int mmu_virtual_psize;
168extern int mmu_vmalloc_psize;
169extern int mmu_io_psize;
170
171/*
172 * If the processor supports 64k normal pages but not 64k cache
173 * inhibited pages, we have to be prepared to switch processes
174 * to use 4k pages when they create cache-inhibited mappings.
175 * If this is the case, mmu_ci_restrictions will be set to 1.
176 */
177extern int mmu_ci_restrictions;
168 178
169#ifdef CONFIG_HUGETLB_PAGE 179#ifdef CONFIG_HUGETLB_PAGE
170/* 180/*
@@ -256,6 +266,7 @@ extern long iSeries_hpte_insert(unsigned long hpte_group,
256 266
257extern void stabs_alloc(void); 267extern void stabs_alloc(void);
258extern void slb_initialize(void); 268extern void slb_initialize(void);
269extern void slb_flush_and_rebolt(void);
259extern void stab_initialize(unsigned long stab); 270extern void stab_initialize(unsigned long stab);
260 271
261#endif /* __ASSEMBLY__ */ 272#endif /* __ASSEMBLY__ */
@@ -359,6 +370,8 @@ typedef unsigned long mm_context_id_t;
359 370
360typedef struct { 371typedef struct {
361 mm_context_id_t id; 372 mm_context_id_t id;
373 u16 user_psize; /* page size index */
374 u16 sllp; /* SLB entry page size encoding */
362#ifdef CONFIG_HUGETLB_PAGE 375#ifdef CONFIG_HUGETLB_PAGE
363 u16 low_htlb_areas, high_htlb_areas; 376 u16 low_htlb_areas, high_htlb_areas;
364#endif 377#endif
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index c17fd54d995b..17406353e2ce 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -81,6 +81,7 @@ struct paca_struct {
81 * on the linear mapping */ 81 * on the linear mapping */
82 82
83 mm_context_t context; 83 mm_context_t context;
84 u16 vmalloc_sllp;
84 u16 slb_cache[SLB_CACHE_ENTRIES]; 85 u16 slb_cache[SLB_CACHE_ENTRIES];
85 u16 slb_cache_ptr; 86 u16 slb_cache_ptr;
86 87
diff --git a/include/asm-powerpc/pgtable-4k.h b/include/asm-powerpc/pgtable-4k.h
index b2e18629932a..e7036155672e 100644
--- a/include/asm-powerpc/pgtable-4k.h
+++ b/include/asm-powerpc/pgtable-4k.h
@@ -78,6 +78,8 @@
78 78
79#define pte_iterate_hashed_end() } while(0) 79#define pte_iterate_hashed_end() } while(0)
80 80
81#define pte_pagesize_index(pte) MMU_PAGE_4K
82
81/* 83/*
82 * 4-level page tables related bits 84 * 4-level page tables related bits
83 */ 85 */
diff --git a/include/asm-powerpc/pgtable-64k.h b/include/asm-powerpc/pgtable-64k.h
index 653915014dcd..4b7126c53f37 100644
--- a/include/asm-powerpc/pgtable-64k.h
+++ b/include/asm-powerpc/pgtable-64k.h
@@ -90,6 +90,8 @@
90 90
91#define pte_iterate_hashed_end() } while(0); } } while(0) 91#define pte_iterate_hashed_end() } while(0); } } while(0)
92 92
93#define pte_pagesize_index(pte) \
94 (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K)
93 95
94#endif /* __ASSEMBLY__ */ 96#endif /* __ASSEMBLY__ */
95#endif /* __KERNEL__ */ 97#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/pgtable.h b/include/asm-powerpc/pgtable.h
index e9f1f4627e6b..260a0fabe97e 100644
--- a/include/asm-powerpc/pgtable.h
+++ b/include/asm-powerpc/pgtable.h
@@ -47,8 +47,8 @@ struct mm_struct;
47/* 47/*
48 * Define the address range of the vmalloc VM area. 48 * Define the address range of the vmalloc VM area.
49 */ 49 */
50#define VMALLOC_START (0xD000000000000000ul) 50#define VMALLOC_START ASM_CONST(0xD000000000000000)
51#define VMALLOC_SIZE (0x80000000000UL) 51#define VMALLOC_SIZE ASM_CONST(0x80000000000)
52#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) 52#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
53 53
54/* 54/*
@@ -413,12 +413,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
413 flush_tlb_pending(); 413 flush_tlb_pending();
414 } 414 }
415 pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); 415 pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
416
417#ifdef CONFIG_PPC_64K_PAGES
418 if (mmu_virtual_psize != MMU_PAGE_64K)
419 pte = __pte(pte_val(pte) | _PAGE_COMBO);
420#endif /* CONFIG_PPC_64K_PAGES */
421
422 *ptep = pte; 416 *ptep = pte;
423} 417}
424 418