diff options
author | David S. Miller <davem@davemloft.net> | 2013-05-04 21:34:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-04 21:34:13 -0400 |
commit | 048c9acca90ca7da42b92745445fe008a48add88 (patch) | |
tree | e2e551a565a7dcdca0fc398aa659231745e5a901 /arch/sparc/mm | |
parent | 07df841877195765d958df146f614fc7bdedd5e3 (diff) | |
parent | ad348cc5349be4ef4abe08819afbb63386585413 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Merge sparc bug fixes that didn't make it into v3.9 into
sparc-next.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r-- | arch/sparc/mm/init_32.c | 12 | ||||
-rw-r--r-- | arch/sparc/mm/init_64.c | 7 | ||||
-rw-r--r-- | arch/sparc/mm/iommu.c | 2 | ||||
-rw-r--r-- | arch/sparc/mm/srmmu.c | 4 | ||||
-rw-r--r-- | arch/sparc/mm/tlb.c | 39 | ||||
-rw-r--r-- | arch/sparc/mm/tsb.c | 57 | ||||
-rw-r--r-- | arch/sparc/mm/ultra.S | 119 |
7 files changed, 181 insertions, 59 deletions
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index 48e0c030e8f5..4490c397bb5b 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c | |||
@@ -282,14 +282,8 @@ static void map_high_region(unsigned long start_pfn, unsigned long end_pfn) | |||
282 | printk("mapping high region %08lx - %08lx\n", start_pfn, end_pfn); | 282 | printk("mapping high region %08lx - %08lx\n", start_pfn, end_pfn); |
283 | #endif | 283 | #endif |
284 | 284 | ||
285 | for (tmp = start_pfn; tmp < end_pfn; tmp++) { | 285 | for (tmp = start_pfn; tmp < end_pfn; tmp++) |
286 | struct page *page = pfn_to_page(tmp); | 286 | free_highmem_page(pfn_to_page(tmp)); |
287 | |||
288 | ClearPageReserved(page); | ||
289 | init_page_count(page); | ||
290 | __free_page(page); | ||
291 | totalhigh_pages++; | ||
292 | } | ||
293 | } | 287 | } |
294 | 288 | ||
295 | void __init mem_init(void) | 289 | void __init mem_init(void) |
@@ -347,8 +341,6 @@ void __init mem_init(void) | |||
347 | map_high_region(start_pfn, end_pfn); | 341 | map_high_region(start_pfn, end_pfn); |
348 | } | 342 | } |
349 | 343 | ||
350 | totalram_pages += totalhigh_pages; | ||
351 | |||
352 | codepages = (((unsigned long) &_etext) - ((unsigned long)&_start)); | 344 | codepages = (((unsigned long) &_etext) - ((unsigned long)&_start)); |
353 | codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT; | 345 | codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT; |
354 | datapages = (((unsigned long) &_edata) - ((unsigned long)&_etext)); | 346 | datapages = (((unsigned long) &_edata) - ((unsigned long)&_etext)); |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 4ccaa1b9961f..cf72a8a5b3aa 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -2178,10 +2178,9 @@ unsigned long vmemmap_table[VMEMMAP_SIZE]; | |||
2178 | static long __meminitdata addr_start, addr_end; | 2178 | static long __meminitdata addr_start, addr_end; |
2179 | static int __meminitdata node_start; | 2179 | static int __meminitdata node_start; |
2180 | 2180 | ||
2181 | int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) | 2181 | int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, |
2182 | int node) | ||
2182 | { | 2183 | { |
2183 | unsigned long vstart = (unsigned long) start; | ||
2184 | unsigned long vend = (unsigned long) (start + nr); | ||
2185 | unsigned long phys_start = (vstart - VMEMMAP_BASE); | 2184 | unsigned long phys_start = (vstart - VMEMMAP_BASE); |
2186 | unsigned long phys_end = (vend - VMEMMAP_BASE); | 2185 | unsigned long phys_end = (vend - VMEMMAP_BASE); |
2187 | unsigned long addr = phys_start & VMEMMAP_CHUNK_MASK; | 2186 | unsigned long addr = phys_start & VMEMMAP_CHUNK_MASK; |
@@ -2233,7 +2232,7 @@ void __meminit vmemmap_populate_print_last(void) | |||
2233 | } | 2232 | } |
2234 | } | 2233 | } |
2235 | 2234 | ||
2236 | void vmemmap_free(struct page *memmap, unsigned long nr_pages) | 2235 | void vmemmap_free(unsigned long start, unsigned long end) |
2237 | { | 2236 | { |
2238 | } | 2237 | } |
2239 | 2238 | ||
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 0f4f7191fbba..28f96f27c768 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #define IOMMU_RNGE IOMMU_RNGE_256MB | 34 | #define IOMMU_RNGE IOMMU_RNGE_256MB |
35 | #define IOMMU_START 0xF0000000 | 35 | #define IOMMU_START 0xF0000000 |
36 | #define IOMMU_WINSIZE (256*1024*1024U) | 36 | #define IOMMU_WINSIZE (256*1024*1024U) |
37 | #define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 265KB */ | 37 | #define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 256KB */ |
38 | #define IOMMU_ORDER 6 /* 4096 * (1<<6) */ | 38 | #define IOMMU_ORDER 6 /* 4096 * (1<<6) */ |
39 | 39 | ||
40 | /* srmmu.c */ | 40 | /* srmmu.c */ |
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index c38bb72e3e80..036c2797dece 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c | |||
@@ -280,7 +280,9 @@ static void __init srmmu_nocache_init(void) | |||
280 | SRMMU_NOCACHE_ALIGN_MAX, 0UL); | 280 | SRMMU_NOCACHE_ALIGN_MAX, 0UL); |
281 | memset(srmmu_nocache_pool, 0, srmmu_nocache_size); | 281 | memset(srmmu_nocache_pool, 0, srmmu_nocache_size); |
282 | 282 | ||
283 | srmmu_nocache_bitmap = __alloc_bootmem(bitmap_bits >> 3, SMP_CACHE_BYTES, 0UL); | 283 | srmmu_nocache_bitmap = |
284 | __alloc_bootmem(BITS_TO_LONGS(bitmap_bits) * sizeof(long), | ||
285 | SMP_CACHE_BYTES, 0UL); | ||
284 | bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits); | 286 | bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits); |
285 | 287 | ||
286 | srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); | 288 | srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); |
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index ba6ae7ffdc2c..83d89bcb44af 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c | |||
@@ -24,11 +24,17 @@ static DEFINE_PER_CPU(struct tlb_batch, tlb_batch); | |||
24 | void flush_tlb_pending(void) | 24 | void flush_tlb_pending(void) |
25 | { | 25 | { |
26 | struct tlb_batch *tb = &get_cpu_var(tlb_batch); | 26 | struct tlb_batch *tb = &get_cpu_var(tlb_batch); |
27 | struct mm_struct *mm = tb->mm; | ||
27 | 28 | ||
28 | if (tb->tlb_nr) { | 29 | if (!tb->tlb_nr) |
29 | flush_tsb_user(tb); | 30 | goto out; |
30 | 31 | ||
31 | if (CTX_VALID(tb->mm->context)) { | 32 | flush_tsb_user(tb); |
33 | |||
34 | if (CTX_VALID(mm->context)) { | ||
35 | if (tb->tlb_nr == 1) { | ||
36 | global_flush_tlb_page(mm, tb->vaddrs[0]); | ||
37 | } else { | ||
32 | #ifdef CONFIG_SMP | 38 | #ifdef CONFIG_SMP |
33 | smp_flush_tlb_pending(tb->mm, tb->tlb_nr, | 39 | smp_flush_tlb_pending(tb->mm, tb->tlb_nr, |
34 | &tb->vaddrs[0]); | 40 | &tb->vaddrs[0]); |
@@ -37,12 +43,30 @@ void flush_tlb_pending(void) | |||
37 | tb->tlb_nr, &tb->vaddrs[0]); | 43 | tb->tlb_nr, &tb->vaddrs[0]); |
38 | #endif | 44 | #endif |
39 | } | 45 | } |
40 | tb->tlb_nr = 0; | ||
41 | } | 46 | } |
42 | 47 | ||
48 | tb->tlb_nr = 0; | ||
49 | |||
50 | out: | ||
43 | put_cpu_var(tlb_batch); | 51 | put_cpu_var(tlb_batch); |
44 | } | 52 | } |
45 | 53 | ||
54 | void arch_enter_lazy_mmu_mode(void) | ||
55 | { | ||
56 | struct tlb_batch *tb = &__get_cpu_var(tlb_batch); | ||
57 | |||
58 | tb->active = 1; | ||
59 | } | ||
60 | |||
61 | void arch_leave_lazy_mmu_mode(void) | ||
62 | { | ||
63 | struct tlb_batch *tb = &__get_cpu_var(tlb_batch); | ||
64 | |||
65 | if (tb->tlb_nr) | ||
66 | flush_tlb_pending(); | ||
67 | tb->active = 0; | ||
68 | } | ||
69 | |||
46 | static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, | 70 | static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, |
47 | bool exec) | 71 | bool exec) |
48 | { | 72 | { |
@@ -60,6 +84,12 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, | |||
60 | nr = 0; | 84 | nr = 0; |
61 | } | 85 | } |
62 | 86 | ||
87 | if (!tb->active) { | ||
88 | global_flush_tlb_page(mm, vaddr); | ||
89 | flush_tsb_user_page(mm, vaddr); | ||
90 | goto out; | ||
91 | } | ||
92 | |||
63 | if (nr == 0) | 93 | if (nr == 0) |
64 | tb->mm = mm; | 94 | tb->mm = mm; |
65 | 95 | ||
@@ -68,6 +98,7 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, | |||
68 | if (nr >= TLB_BATCH_NR) | 98 | if (nr >= TLB_BATCH_NR) |
69 | flush_tlb_pending(); | 99 | flush_tlb_pending(); |
70 | 100 | ||
101 | out: | ||
71 | put_cpu_var(tlb_batch); | 102 | put_cpu_var(tlb_batch); |
72 | } | 103 | } |
73 | 104 | ||
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 428982b9becf..2cc3bce5ee91 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c | |||
@@ -7,11 +7,10 @@ | |||
7 | #include <linux/preempt.h> | 7 | #include <linux/preempt.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <asm/page.h> | 9 | #include <asm/page.h> |
10 | #include <asm/tlbflush.h> | ||
11 | #include <asm/tlb.h> | ||
12 | #include <asm/mmu_context.h> | ||
13 | #include <asm/pgtable.h> | 10 | #include <asm/pgtable.h> |
11 | #include <asm/mmu_context.h> | ||
14 | #include <asm/tsb.h> | 12 | #include <asm/tsb.h> |
13 | #include <asm/tlb.h> | ||
15 | #include <asm/oplib.h> | 14 | #include <asm/oplib.h> |
16 | 15 | ||
17 | extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; | 16 | extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; |
@@ -46,23 +45,27 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end) | |||
46 | } | 45 | } |
47 | } | 46 | } |
48 | 47 | ||
49 | static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift, | 48 | static void __flush_tsb_one_entry(unsigned long tsb, unsigned long v, |
50 | unsigned long tsb, unsigned long nentries) | 49 | unsigned long hash_shift, |
50 | unsigned long nentries) | ||
51 | { | 51 | { |
52 | unsigned long i; | 52 | unsigned long tag, ent, hash; |
53 | 53 | ||
54 | for (i = 0; i < tb->tlb_nr; i++) { | 54 | v &= ~0x1UL; |
55 | unsigned long v = tb->vaddrs[i]; | 55 | hash = tsb_hash(v, hash_shift, nentries); |
56 | unsigned long tag, ent, hash; | 56 | ent = tsb + (hash * sizeof(struct tsb)); |
57 | tag = (v >> 22UL); | ||
57 | 58 | ||
58 | v &= ~0x1UL; | 59 | tsb_flush(ent, tag); |
60 | } | ||
59 | 61 | ||
60 | hash = tsb_hash(v, hash_shift, nentries); | 62 | static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift, |
61 | ent = tsb + (hash * sizeof(struct tsb)); | 63 | unsigned long tsb, unsigned long nentries) |
62 | tag = (v >> 22UL); | 64 | { |
65 | unsigned long i; | ||
63 | 66 | ||
64 | tsb_flush(ent, tag); | 67 | for (i = 0; i < tb->tlb_nr; i++) |
65 | } | 68 | __flush_tsb_one_entry(tsb, tb->vaddrs[i], hash_shift, nentries); |
66 | } | 69 | } |
67 | 70 | ||
68 | void flush_tsb_user(struct tlb_batch *tb) | 71 | void flush_tsb_user(struct tlb_batch *tb) |
@@ -90,6 +93,30 @@ void flush_tsb_user(struct tlb_batch *tb) | |||
90 | spin_unlock_irqrestore(&mm->context.lock, flags); | 93 | spin_unlock_irqrestore(&mm->context.lock, flags); |
91 | } | 94 | } |
92 | 95 | ||
96 | void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) | ||
97 | { | ||
98 | unsigned long nentries, base, flags; | ||
99 | |||
100 | spin_lock_irqsave(&mm->context.lock, flags); | ||
101 | |||
102 | base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb; | ||
103 | nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries; | ||
104 | if (tlb_type == cheetah_plus || tlb_type == hypervisor) | ||
105 | base = __pa(base); | ||
106 | __flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries); | ||
107 | |||
108 | #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) | ||
109 | if (mm->context.tsb_block[MM_TSB_HUGE].tsb) { | ||
110 | base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb; | ||
111 | nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries; | ||
112 | if (tlb_type == cheetah_plus || tlb_type == hypervisor) | ||
113 | base = __pa(base); | ||
114 | __flush_tsb_one_entry(base, vaddr, HPAGE_SHIFT, nentries); | ||
115 | } | ||
116 | #endif | ||
117 | spin_unlock_irqrestore(&mm->context.lock, flags); | ||
118 | } | ||
119 | |||
93 | #define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_8K | 120 | #define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_8K |
94 | #define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_8K | 121 | #define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_8K |
95 | 122 | ||
diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index f8e13d421fcb..432aa0cb1b38 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S | |||
@@ -53,6 +53,33 @@ __flush_tlb_mm: /* 18 insns */ | |||
53 | nop | 53 | nop |
54 | 54 | ||
55 | .align 32 | 55 | .align 32 |
56 | .globl __flush_tlb_page | ||
57 | __flush_tlb_page: /* 22 insns */ | ||
58 | /* %o0 = context, %o1 = vaddr */ | ||
59 | rdpr %pstate, %g7 | ||
60 | andn %g7, PSTATE_IE, %g2 | ||
61 | wrpr %g2, %pstate | ||
62 | mov SECONDARY_CONTEXT, %o4 | ||
63 | ldxa [%o4] ASI_DMMU, %g2 | ||
64 | stxa %o0, [%o4] ASI_DMMU | ||
65 | andcc %o1, 1, %g0 | ||
66 | andn %o1, 1, %o3 | ||
67 | be,pn %icc, 1f | ||
68 | or %o3, 0x10, %o3 | ||
69 | stxa %g0, [%o3] ASI_IMMU_DEMAP | ||
70 | 1: stxa %g0, [%o3] ASI_DMMU_DEMAP | ||
71 | membar #Sync | ||
72 | stxa %g2, [%o4] ASI_DMMU | ||
73 | sethi %hi(KERNBASE), %o4 | ||
74 | flush %o4 | ||
75 | retl | ||
76 | wrpr %g7, 0x0, %pstate | ||
77 | nop | ||
78 | nop | ||
79 | nop | ||
80 | nop | ||
81 | |||
82 | .align 32 | ||
56 | .globl __flush_tlb_pending | 83 | .globl __flush_tlb_pending |
57 | __flush_tlb_pending: /* 26 insns */ | 84 | __flush_tlb_pending: /* 26 insns */ |
58 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | 85 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ |
@@ -203,6 +230,31 @@ __cheetah_flush_tlb_mm: /* 19 insns */ | |||
203 | retl | 230 | retl |
204 | wrpr %g7, 0x0, %pstate | 231 | wrpr %g7, 0x0, %pstate |
205 | 232 | ||
233 | __cheetah_flush_tlb_page: /* 22 insns */ | ||
234 | /* %o0 = context, %o1 = vaddr */ | ||
235 | rdpr %pstate, %g7 | ||
236 | andn %g7, PSTATE_IE, %g2 | ||
237 | wrpr %g2, 0x0, %pstate | ||
238 | wrpr %g0, 1, %tl | ||
239 | mov PRIMARY_CONTEXT, %o4 | ||
240 | ldxa [%o4] ASI_DMMU, %g2 | ||
241 | srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3 | ||
242 | sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3 | ||
243 | or %o0, %o3, %o0 /* Preserve nucleus page size fields */ | ||
244 | stxa %o0, [%o4] ASI_DMMU | ||
245 | andcc %o1, 1, %g0 | ||
246 | be,pn %icc, 1f | ||
247 | andn %o1, 1, %o3 | ||
248 | stxa %g0, [%o3] ASI_IMMU_DEMAP | ||
249 | 1: stxa %g0, [%o3] ASI_DMMU_DEMAP | ||
250 | membar #Sync | ||
251 | stxa %g2, [%o4] ASI_DMMU | ||
252 | sethi %hi(KERNBASE), %o4 | ||
253 | flush %o4 | ||
254 | wrpr %g0, 0, %tl | ||
255 | retl | ||
256 | wrpr %g7, 0x0, %pstate | ||
257 | |||
206 | __cheetah_flush_tlb_pending: /* 27 insns */ | 258 | __cheetah_flush_tlb_pending: /* 27 insns */ |
207 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | 259 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ |
208 | rdpr %pstate, %g7 | 260 | rdpr %pstate, %g7 |
@@ -269,6 +321,20 @@ __hypervisor_flush_tlb_mm: /* 10 insns */ | |||
269 | retl | 321 | retl |
270 | nop | 322 | nop |
271 | 323 | ||
324 | __hypervisor_flush_tlb_page: /* 11 insns */ | ||
325 | /* %o0 = context, %o1 = vaddr */ | ||
326 | mov %o0, %g2 | ||
327 | mov %o1, %o0 /* ARG0: vaddr + IMMU-bit */ | ||
328 | mov %g2, %o1 /* ARG1: mmu context */ | ||
329 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ | ||
330 | srlx %o0, PAGE_SHIFT, %o0 | ||
331 | sllx %o0, PAGE_SHIFT, %o0 | ||
332 | ta HV_MMU_UNMAP_ADDR_TRAP | ||
333 | brnz,pn %o0, __hypervisor_tlb_tl0_error | ||
334 | mov HV_MMU_UNMAP_ADDR_TRAP, %o1 | ||
335 | retl | ||
336 | nop | ||
337 | |||
272 | __hypervisor_flush_tlb_pending: /* 16 insns */ | 338 | __hypervisor_flush_tlb_pending: /* 16 insns */ |
273 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | 339 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ |
274 | sllx %o1, 3, %g1 | 340 | sllx %o1, 3, %g1 |
@@ -339,6 +405,13 @@ cheetah_patch_cachetlbops: | |||
339 | call tlb_patch_one | 405 | call tlb_patch_one |
340 | mov 19, %o2 | 406 | mov 19, %o2 |
341 | 407 | ||
408 | sethi %hi(__flush_tlb_page), %o0 | ||
409 | or %o0, %lo(__flush_tlb_page), %o0 | ||
410 | sethi %hi(__cheetah_flush_tlb_page), %o1 | ||
411 | or %o1, %lo(__cheetah_flush_tlb_page), %o1 | ||
412 | call tlb_patch_one | ||
413 | mov 22, %o2 | ||
414 | |||
342 | sethi %hi(__flush_tlb_pending), %o0 | 415 | sethi %hi(__flush_tlb_pending), %o0 |
343 | or %o0, %lo(__flush_tlb_pending), %o0 | 416 | or %o0, %lo(__flush_tlb_pending), %o0 |
344 | sethi %hi(__cheetah_flush_tlb_pending), %o1 | 417 | sethi %hi(__cheetah_flush_tlb_pending), %o1 |
@@ -397,10 +470,9 @@ xcall_flush_tlb_mm: /* 21 insns */ | |||
397 | nop | 470 | nop |
398 | nop | 471 | nop |
399 | 472 | ||
400 | .globl xcall_flush_tlb_pending | 473 | .globl xcall_flush_tlb_page |
401 | xcall_flush_tlb_pending: /* 21 insns */ | 474 | xcall_flush_tlb_page: /* 17 insns */ |
402 | /* %g5=context, %g1=nr, %g7=vaddrs[] */ | 475 | /* %g5=context, %g1=vaddr */ |
403 | sllx %g1, 3, %g1 | ||
404 | mov PRIMARY_CONTEXT, %g4 | 476 | mov PRIMARY_CONTEXT, %g4 |
405 | ldxa [%g4] ASI_DMMU, %g2 | 477 | ldxa [%g4] ASI_DMMU, %g2 |
406 | srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4 | 478 | srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4 |
@@ -408,20 +480,16 @@ xcall_flush_tlb_pending: /* 21 insns */ | |||
408 | or %g5, %g4, %g5 | 480 | or %g5, %g4, %g5 |
409 | mov PRIMARY_CONTEXT, %g4 | 481 | mov PRIMARY_CONTEXT, %g4 |
410 | stxa %g5, [%g4] ASI_DMMU | 482 | stxa %g5, [%g4] ASI_DMMU |
411 | 1: sub %g1, (1 << 3), %g1 | 483 | andcc %g1, 0x1, %g0 |
412 | ldx [%g7 + %g1], %g5 | ||
413 | andcc %g5, 0x1, %g0 | ||
414 | be,pn %icc, 2f | 484 | be,pn %icc, 2f |
415 | 485 | andn %g1, 0x1, %g5 | |
416 | andn %g5, 0x1, %g5 | ||
417 | stxa %g0, [%g5] ASI_IMMU_DEMAP | 486 | stxa %g0, [%g5] ASI_IMMU_DEMAP |
418 | 2: stxa %g0, [%g5] ASI_DMMU_DEMAP | 487 | 2: stxa %g0, [%g5] ASI_DMMU_DEMAP |
419 | membar #Sync | 488 | membar #Sync |
420 | brnz,pt %g1, 1b | ||
421 | nop | ||
422 | stxa %g2, [%g4] ASI_DMMU | 489 | stxa %g2, [%g4] ASI_DMMU |
423 | retry | 490 | retry |
424 | nop | 491 | nop |
492 | nop | ||
425 | 493 | ||
426 | .globl xcall_flush_tlb_kernel_range | 494 | .globl xcall_flush_tlb_kernel_range |
427 | xcall_flush_tlb_kernel_range: /* 25 insns */ | 495 | xcall_flush_tlb_kernel_range: /* 25 insns */ |
@@ -656,15 +724,13 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */ | |||
656 | membar #Sync | 724 | membar #Sync |
657 | retry | 725 | retry |
658 | 726 | ||
659 | .globl __hypervisor_xcall_flush_tlb_pending | 727 | .globl __hypervisor_xcall_flush_tlb_page |
660 | __hypervisor_xcall_flush_tlb_pending: /* 21 insns */ | 728 | __hypervisor_xcall_flush_tlb_page: /* 17 insns */ |
661 | /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4,g6=scratch */ | 729 | /* %g5=ctx, %g1=vaddr */ |
662 | sllx %g1, 3, %g1 | ||
663 | mov %o0, %g2 | 730 | mov %o0, %g2 |
664 | mov %o1, %g3 | 731 | mov %o1, %g3 |
665 | mov %o2, %g4 | 732 | mov %o2, %g4 |
666 | 1: sub %g1, (1 << 3), %g1 | 733 | mov %g1, %o0 /* ARG0: virtual address */ |
667 | ldx [%g7 + %g1], %o0 /* ARG0: virtual address */ | ||
668 | mov %g5, %o1 /* ARG1: mmu context */ | 734 | mov %g5, %o1 /* ARG1: mmu context */ |
669 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ | 735 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ |
670 | srlx %o0, PAGE_SHIFT, %o0 | 736 | srlx %o0, PAGE_SHIFT, %o0 |
@@ -673,8 +739,6 @@ __hypervisor_xcall_flush_tlb_pending: /* 21 insns */ | |||
673 | mov HV_MMU_UNMAP_ADDR_TRAP, %g6 | 739 | mov HV_MMU_UNMAP_ADDR_TRAP, %g6 |
674 | brnz,a,pn %o0, __hypervisor_tlb_xcall_error | 740 | brnz,a,pn %o0, __hypervisor_tlb_xcall_error |
675 | mov %o0, %g5 | 741 | mov %o0, %g5 |
676 | brnz,pt %g1, 1b | ||
677 | nop | ||
678 | mov %g2, %o0 | 742 | mov %g2, %o0 |
679 | mov %g3, %o1 | 743 | mov %g3, %o1 |
680 | mov %g4, %o2 | 744 | mov %g4, %o2 |
@@ -757,6 +821,13 @@ hypervisor_patch_cachetlbops: | |||
757 | call tlb_patch_one | 821 | call tlb_patch_one |
758 | mov 10, %o2 | 822 | mov 10, %o2 |
759 | 823 | ||
824 | sethi %hi(__flush_tlb_page), %o0 | ||
825 | or %o0, %lo(__flush_tlb_page), %o0 | ||
826 | sethi %hi(__hypervisor_flush_tlb_page), %o1 | ||
827 | or %o1, %lo(__hypervisor_flush_tlb_page), %o1 | ||
828 | call tlb_patch_one | ||
829 | mov 11, %o2 | ||
830 | |||
760 | sethi %hi(__flush_tlb_pending), %o0 | 831 | sethi %hi(__flush_tlb_pending), %o0 |
761 | or %o0, %lo(__flush_tlb_pending), %o0 | 832 | or %o0, %lo(__flush_tlb_pending), %o0 |
762 | sethi %hi(__hypervisor_flush_tlb_pending), %o1 | 833 | sethi %hi(__hypervisor_flush_tlb_pending), %o1 |
@@ -788,12 +859,12 @@ hypervisor_patch_cachetlbops: | |||
788 | call tlb_patch_one | 859 | call tlb_patch_one |
789 | mov 21, %o2 | 860 | mov 21, %o2 |
790 | 861 | ||
791 | sethi %hi(xcall_flush_tlb_pending), %o0 | 862 | sethi %hi(xcall_flush_tlb_page), %o0 |
792 | or %o0, %lo(xcall_flush_tlb_pending), %o0 | 863 | or %o0, %lo(xcall_flush_tlb_page), %o0 |
793 | sethi %hi(__hypervisor_xcall_flush_tlb_pending), %o1 | 864 | sethi %hi(__hypervisor_xcall_flush_tlb_page), %o1 |
794 | or %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1 | 865 | or %o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1 |
795 | call tlb_patch_one | 866 | call tlb_patch_one |
796 | mov 21, %o2 | 867 | mov 17, %o2 |
797 | 868 | ||
798 | sethi %hi(xcall_flush_tlb_kernel_range), %o0 | 869 | sethi %hi(xcall_flush_tlb_kernel_range), %o0 |
799 | or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 | 870 | or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 |