aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/44x_tlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/44x_tlb.c')
-rw-r--r--arch/powerpc/kvm/44x_tlb.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
index 06a5fcfc4d33..3594bbd1f618 100644
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -170,7 +170,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid,
170 170
171 /* XXX what about AS? */ 171 /* XXX what about AS? */
172 172
173 stlbe->tid = asid & 0xff; 173 stlbe->tid = !(asid & 0xff);
174 174
175 /* Force TS=1 for all guest mappings. */ 175 /* Force TS=1 for all guest mappings. */
176 /* For now we hardcode 4KB mappings, but it will be important to 176 /* For now we hardcode 4KB mappings, but it will be important to
@@ -190,7 +190,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid,
190void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr, 190void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
191 gva_t eend, u32 asid) 191 gva_t eend, u32 asid)
192{ 192{
193 unsigned int pid = asid & 0xff; 193 unsigned int pid = !(asid & 0xff);
194 int i; 194 int i;
195 195
196 /* XXX Replace loop with fancy data structures. */ 196 /* XXX Replace loop with fancy data structures. */
@@ -222,23 +222,30 @@ void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
222 up_write(&current->mm->mmap_sem); 222 up_write(&current->mm->mmap_sem);
223} 223}
224 224
225/* Invalidate all mappings, so that when they fault back in they will get the 225/* Invalidate all mappings on the privilege switch after PID has been changed.
226 * proper permission bits. */ 226 * The guest always runs with PID=1, so we must clear the entire TLB when
227 * switching address spaces. */
227void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode) 228void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode)
228{ 229{
229 int i; 230 int i;
230 231
231 /* XXX Replace loop with fancy data structures. */ 232 if (vcpu->arch.swap_pid) {
232 down_write(&current->mm->mmap_sem); 233 /* XXX Replace loop with fancy data structures. */
233 for (i = 0; i <= tlb_44x_hwater; i++) { 234 down_write(&current->mm->mmap_sem);
234 struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i]; 235 for (i = 0; i <= tlb_44x_hwater; i++) {
235 236 struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i];
236 kvmppc_44x_shadow_release(vcpu, i); 237
237 stlbe->word0 = 0; 238 /* Future optimization: clear only userspace mappings. */
238 kvmppc_tlbe_set_modified(vcpu, i); 239 kvmppc_44x_shadow_release(vcpu, i);
239 KVMTRACE_5D(STLB_INVAL, vcpu, i, 240 stlbe->word0 = 0;
240 stlbe->tid, stlbe->word0, stlbe->word1, 241 kvmppc_tlbe_set_modified(vcpu, i);
241 stlbe->word2, handler); 242 KVMTRACE_5D(STLB_INVAL, vcpu, i,
243 stlbe->tid, stlbe->word0, stlbe->word1,
244 stlbe->word2, handler);
245 }
246 up_write(&current->mm->mmap_sem);
247 vcpu->arch.swap_pid = 0;
242 } 248 }
243 up_write(&current->mm->mmap_sem); 249
250 vcpu->arch.shadow_pid = !usermode;
244} 251}