diff options
Diffstat (limited to 'arch/powerpc/mm/tlb_nohash.c')
-rw-r--r-- | arch/powerpc/mm/tlb_nohash.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index d908e75cc3b5..761e8882416f 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -67,18 +67,24 @@ void local_flush_tlb_mm(struct mm_struct *mm) | |||
67 | } | 67 | } |
68 | EXPORT_SYMBOL(local_flush_tlb_mm); | 68 | EXPORT_SYMBOL(local_flush_tlb_mm); |
69 | 69 | ||
70 | void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) | 70 | void __local_flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr, |
71 | int tsize, int ind) | ||
71 | { | 72 | { |
72 | unsigned int pid; | 73 | unsigned int pid; |
73 | 74 | ||
74 | preempt_disable(); | 75 | preempt_disable(); |
75 | pid = vma ? vma->vm_mm->context.id : 0; | 76 | pid = mm ? mm->context.id : 0; |
76 | if (pid != MMU_NO_CONTEXT) | 77 | if (pid != MMU_NO_CONTEXT) |
77 | _tlbil_va(vmaddr, pid); | 78 | _tlbil_va(vmaddr, pid, tsize, ind); |
78 | preempt_enable(); | 79 | preempt_enable(); |
79 | } | 80 | } |
80 | EXPORT_SYMBOL(local_flush_tlb_page); | ||
81 | 81 | ||
82 | void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) | ||
83 | { | ||
84 | __local_flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, | ||
85 | 0 /* tsize unused for now */, 0); | ||
86 | } | ||
87 | EXPORT_SYMBOL(local_flush_tlb_page); | ||
82 | 88 | ||
83 | /* | 89 | /* |
84 | * And here are the SMP non-local implementations | 90 | * And here are the SMP non-local implementations |
@@ -96,6 +102,8 @@ static int mm_is_core_local(struct mm_struct *mm) | |||
96 | struct tlb_flush_param { | 102 | struct tlb_flush_param { |
97 | unsigned long addr; | 103 | unsigned long addr; |
98 | unsigned int pid; | 104 | unsigned int pid; |
105 | unsigned int tsize; | ||
106 | unsigned int ind; | ||
99 | }; | 107 | }; |
100 | 108 | ||
101 | static void do_flush_tlb_mm_ipi(void *param) | 109 | static void do_flush_tlb_mm_ipi(void *param) |
@@ -109,7 +117,7 @@ static void do_flush_tlb_page_ipi(void *param) | |||
109 | { | 117 | { |
110 | struct tlb_flush_param *p = param; | 118 | struct tlb_flush_param *p = param; |
111 | 119 | ||
112 | _tlbil_va(p->addr, p->pid); | 120 | _tlbil_va(p->addr, p->pid, p->tsize, p->ind); |
113 | } | 121 | } |
114 | 122 | ||
115 | 123 | ||
@@ -149,37 +157,49 @@ void flush_tlb_mm(struct mm_struct *mm) | |||
149 | } | 157 | } |
150 | EXPORT_SYMBOL(flush_tlb_mm); | 158 | EXPORT_SYMBOL(flush_tlb_mm); |
151 | 159 | ||
152 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) | 160 | void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr, |
161 | int tsize, int ind) | ||
153 | { | 162 | { |
154 | struct cpumask *cpu_mask; | 163 | struct cpumask *cpu_mask; |
155 | unsigned int pid; | 164 | unsigned int pid; |
156 | 165 | ||
157 | preempt_disable(); | 166 | preempt_disable(); |
158 | pid = vma ? vma->vm_mm->context.id : 0; | 167 | pid = mm ? mm->context.id : 0; |
159 | if (unlikely(pid == MMU_NO_CONTEXT)) | 168 | if (unlikely(pid == MMU_NO_CONTEXT)) |
160 | goto bail; | 169 | goto bail; |
161 | cpu_mask = mm_cpumask(vma->vm_mm); | 170 | cpu_mask = mm_cpumask(mm); |
162 | if (!mm_is_core_local(mm)) { | 171 | if (!mm_is_core_local(mm)) { |
163 | /* If broadcast tlbivax is supported, use it */ | 172 | /* If broadcast tlbivax is supported, use it */ |
164 | if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) { | 173 | if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) { |
165 | int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL); | 174 | int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL); |
166 | if (lock) | 175 | if (lock) |
167 | spin_lock(&tlbivax_lock); | 176 | spin_lock(&tlbivax_lock); |
168 | _tlbivax_bcast(vmaddr, pid); | 177 | _tlbivax_bcast(vmaddr, pid, tsize, ind); |
169 | if (lock) | 178 | if (lock) |
170 | spin_unlock(&tlbivax_lock); | 179 | spin_unlock(&tlbivax_lock); |
171 | goto bail; | 180 | goto bail; |
172 | } else { | 181 | } else { |
173 | struct tlb_flush_param p = { .pid = pid, .addr = vmaddr }; | 182 | struct tlb_flush_param p = { |
183 | .pid = pid, | ||
184 | .addr = vmaddr, | ||
185 | .tsize = tsize, | ||
186 | .ind = ind, | ||
187 | }; | ||
174 | /* Ignores smp_processor_id() even if set in cpu_mask */ | 188 | /* Ignores smp_processor_id() even if set in cpu_mask */ |
175 | smp_call_function_many(cpu_mask, | 189 | smp_call_function_many(cpu_mask, |
176 | do_flush_tlb_page_ipi, &p, 1); | 190 | do_flush_tlb_page_ipi, &p, 1); |
177 | } | 191 | } |
178 | } | 192 | } |
179 | _tlbil_va(vmaddr, pid); | 193 | _tlbil_va(vmaddr, pid, tsize, ind); |
180 | bail: | 194 | bail: |
181 | preempt_enable(); | 195 | preempt_enable(); |
182 | } | 196 | } |
197 | |||
198 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) | ||
199 | { | ||
200 | __flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr, | ||
201 | 0 /* tsize unused for now */, 0); | ||
202 | } | ||
183 | EXPORT_SYMBOL(flush_tlb_page); | 203 | EXPORT_SYMBOL(flush_tlb_page); |
184 | 204 | ||
185 | #endif /* CONFIG_SMP */ | 205 | #endif /* CONFIG_SMP */ |