6 #include <linux/kernel.h>
8 #include <linux/slab.h>
10 #include <asm/tlbflush.h>
12 #include <asm/mmu_context.h>
13 #include <asm/pgtable.h>
15 #include <asm/oplib.h>
19 static inline unsigned long tsb_hash(
unsigned long vaddr,
unsigned long hash_shift,
unsigned long nentries)
22 return vaddr & (nentries - 1);
25 static inline int tag_compare(
unsigned long tag,
unsigned long vaddr)
27 return (tag == (vaddr >> 22));
44 if (tag_compare(ent->
tag, v))
49 static void __flush_tsb_one(
struct tlb_batch *
tb,
unsigned long hash_shift,
50 unsigned long tsb,
unsigned long nentries)
54 for (i = 0; i < tb->
tlb_nr; i++) {
60 hash = tsb_hash(v, hash_shift, nentries);
61 ent = tsb + (hash *
sizeof(
struct tsb));
79 __flush_tsb_one(tb,
PAGE_SHIFT, base, nentries);
81 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
93 #define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_8K
94 #define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_8K
96 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
97 #define HV_PGSZ_IDX_HUGE HV_PGSZ_IDX_4MB
98 #define HV_PGSZ_MASK_HUGE HV_PGSZ_MASK_4MB
101 static void setup_tsb_params(
struct mm_struct *mm,
unsigned long tsb_idx,
unsigned long tsb_bytes)
103 unsigned long tsb_reg,
base, tsb_paddr;
104 unsigned long page_sz, tte;
107 tsb_bytes /
sizeof(
struct tsb);
112 BUG_ON(tsb_paddr & (tsb_bytes - 1
UL));
120 #ifdef DCACHE_ALIASING_POSSIBLE
121 base += (tsb_paddr & 8192);
143 page_sz = 512 * 1024;
148 page_sz = 512 * 1024;
153 page_sz = 512 * 1024;
158 page_sz = 4 * 1024 * 1024;
162 printk(
KERN_ERR "TSB[%s:%d]: Impossible TSB size %lu, killing process.\n",
170 tsb_reg |= tsb_paddr;
177 tsb_reg |= (tsb_paddr & (page_sz - 1
UL));
178 tte |= (tsb_paddr & ~(page_sz - 1
UL));
193 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
208 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
225 static const char *tsb_cache_names[8] = {
245 prom_printf(
"pgtable_cache_init(): Could not create!\n");
249 for (i = 0; i < 8; i++) {
250 unsigned long size = 8192 <<
i;
251 const char *
name = tsb_cache_names[
i];
256 if (!tsb_caches[i]) {
265 static unsigned long tsb_size_to_rss_limit(
unsigned long new_size)
267 unsigned long num_ents = (new_size /
sizeof(
struct tsb));
269 if (sysctl_tsb_ratio < 0)
293 unsigned long max_tsb_size = 1 * 1024 * 1024;
295 struct tsb *old_tsb, *new_tsb;
296 unsigned long new_cache_index, old_cache_index;
297 unsigned long new_rss_limit;
304 for (new_size = 8192; new_size < max_tsb_size; new_size <<= 1
UL) {
305 new_rss_limit = tsb_size_to_rss_limit(new_size);
306 if (new_rss_limit > rss)
311 if (new_size == max_tsb_size)
312 new_rss_limit = ~0
UL;
328 new_cache_index > 0) {
331 new_rss_limit = ~0
UL;
332 goto retry_tsb_alloc;
382 (rss < mm->
context.tsb_block[tsb_index].tsb_rss_limit))) {
392 extern void copy_tsb(
unsigned long old_tsb_base,
393 unsigned long old_tsb_size,
394 unsigned long new_tsb_base,
395 unsigned long new_tsb_size);
396 unsigned long old_tsb_base = (
unsigned long) old_tsb;
397 unsigned long new_tsb_base = (
unsigned long) new_tsb;
400 old_tsb_base =
__pa(old_tsb_base);
401 new_tsb_base =
__pa(new_tsb_base);
403 copy_tsb(old_tsb_base, old_size, new_tsb_base, new_size);
407 setup_tsb_params(mm, tsb_index, new_size);
416 tsb_context_switch(mm);
430 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
431 unsigned long huge_pte_count;
439 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
462 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
464 tsb_grow(mm, MM_TSB_HUGE, huge_pte_count);
473 static void tsb_destroy_one(
struct tsb_config *tp)
475 unsigned long cache_index;
494 if (page && put_page_testzero(page)) {
495 pgtable_page_dtor(page);