diff options
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/kernel/tsb.S | 11 | ||||
-rw-r--r-- | arch/sparc64/mm/tsb.c | 28 |
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 | |||
87 | int 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 | |||
100 | void 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 | } | ||