aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2006-01-31 21:31:06 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:11:16 -0500
commit09f94287f7260e03bbeab497e743691fafcc22c3 (patch)
treeebdb365a7cfe25a1587a930d852f2eaa0e1e773a /arch/sparc64
parent56fb4df6da76c35dca22036174e2d1edef83ff1f (diff)
[SPARC64]: TSB refinements.
Move {init_new,destroy}_context() out of line. Do not put huge pages into the TSB, only base page size translations. There are some clever things we could do here, but for now let's be correct instead of fancy. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/tsb.S11
-rw-r--r--arch/sparc64/mm/tsb.c28
2 files changed, 39 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S
index 50752c518773..76f2c0b01f36 100644
--- a/arch/sparc64/kernel/tsb.S
+++ b/arch/sparc64/kernel/tsb.S
@@ -55,6 +55,17 @@ tsb_reload:
55 brgez,a,pn %g5, tsb_do_fault 55 brgez,a,pn %g5, tsb_do_fault
56 stx %g0, [%g1] 56 stx %g0, [%g1]
57 57
58 /* If it is larger than the base page size, don't
59 * bother putting it into the TSB.
60 */
61 srlx %g5, 32, %g2
62 sethi %hi(_PAGE_ALL_SZ_BITS >> 32), %g4
63 sethi %hi(_PAGE_SZBITS >> 32), %g7
64 and %g2, %g4, %g2
65 cmp %g2, %g7
66 bne,a,pn %xcc, tsb_tlb_reload
67 stx %g0, [%g1]
68
58 TSB_WRITE(%g1, %g5, %g6) 69 TSB_WRITE(%g1, %g5, %g6)
59 70
60 /* Finally, load TLB and return from trap. */ 71 /* Finally, load TLB and return from trap. */
diff --git a/arch/sparc64/mm/tsb.c b/arch/sparc64/mm/tsb.c
index 15e8af58b1d2..2f84cef6c1b5 100644
--- a/arch/sparc64/mm/tsb.c
+++ b/arch/sparc64/mm/tsb.c
@@ -8,6 +8,7 @@
8#include <asm/page.h> 8#include <asm/page.h>
9#include <asm/tlbflush.h> 9#include <asm/tlbflush.h>
10#include <asm/tlb.h> 10#include <asm/tlb.h>
11#include <asm/mmu_context.h>
11 12
12#define TSB_ENTRY_ALIGNMENT 16 13#define TSB_ENTRY_ALIGNMENT 16
13 14
@@ -82,3 +83,30 @@ void flush_tsb_user(struct mmu_gather *mp)
82 } 83 }
83 } 84 }
84} 85}
86
87int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
88{
89 unsigned long page = get_zeroed_page(GFP_KERNEL);
90
91 mm->context.sparc64_ctx_val = 0UL;
92 if (unlikely(!page))
93 return -ENOMEM;
94
95 mm->context.sparc64_tsb = (unsigned long *) page;
96
97 return 0;
98}
99
100void destroy_context(struct mm_struct *mm)
101{
102 free_page((unsigned long) mm->context.sparc64_tsb);
103
104 spin_lock(&ctx_alloc_lock);
105
106 if (CTX_VALID(mm->context)) {
107 unsigned long nr = CTX_NRBITS(mm->context);
108 mmu_context_bmap[nr>>6] &= ~(1UL << (nr & 63));
109 }
110
111 spin_unlock(&ctx_alloc_lock);
112}