diff options
author | Paul Mackerras <paulus@samba.org> | 2013-06-22 03:14:48 -0400 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-06-29 21:33:22 -0400 |
commit | 6ed1485f65f0eb17aa7b649d5abe0b011b92f718 (patch) | |
tree | 6aef39e1fee53d943a11e6c5a20c970d13ab713e /arch/powerpc/kvm/book3s_64_mmu.c | |
parent | bc1bc4e3929d7a2e4078a9e48fe1e0bb853de1e6 (diff) |
KVM: PPC: Book3S PR: Don't keep scanning HPTEG after we find a match
The loop in kvmppc_mmu_book3s_64_xlate() that looks up a translation
in the guest hashed page table (HPT) keeps going if it finds an
HPTE that matches but doesn't allow access. This is incorrect; it
is different from what the hardware does, and there should never be
more than one matching HPTE anyway. This fixes it to stop when any
matching HPTE is found.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm/book3s_64_mmu.c')
-rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu.c | 14 |
1 files changed, 2 insertions, 12 deletions
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index b871721c0050..2e93bb50a71c 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c | |||
@@ -167,7 +167,6 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
167 | int i; | 167 | int i; |
168 | u8 key = 0; | 168 | u8 key = 0; |
169 | bool found = false; | 169 | bool found = false; |
170 | bool perm_err = false; | ||
171 | int second = 0; | 170 | int second = 0; |
172 | ulong mp_ea = vcpu->arch.magic_page_ea; | 171 | ulong mp_ea = vcpu->arch.magic_page_ea; |
173 | 172 | ||
@@ -248,11 +247,6 @@ do_second: | |||
248 | break; | 247 | break; |
249 | } | 248 | } |
250 | 249 | ||
251 | if (!gpte->may_read) { | ||
252 | perm_err = true; | ||
253 | continue; | ||
254 | } | ||
255 | |||
256 | dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx " | 250 | dprintk("KVM MMU: Translated 0x%lx [0x%llx] -> 0x%llx " |
257 | "-> 0x%lx\n", | 251 | "-> 0x%lx\n", |
258 | eaddr, avpn, gpte->vpage, gpte->raddr); | 252 | eaddr, avpn, gpte->vpage, gpte->raddr); |
@@ -281,6 +275,8 @@ do_second: | |||
281 | if (pteg[i+1] != oldr) | 275 | if (pteg[i+1] != oldr) |
282 | copy_to_user((void __user *)ptegp, pteg, sizeof(pteg)); | 276 | copy_to_user((void __user *)ptegp, pteg, sizeof(pteg)); |
283 | 277 | ||
278 | if (!gpte->may_read) | ||
279 | return -EPERM; | ||
284 | return 0; | 280 | return 0; |
285 | } else { | 281 | } else { |
286 | dprintk("KVM MMU: No PTE found (ea=0x%lx sdr1=0x%llx " | 282 | dprintk("KVM MMU: No PTE found (ea=0x%lx sdr1=0x%llx " |
@@ -296,13 +292,7 @@ do_second: | |||
296 | } | 292 | } |
297 | } | 293 | } |
298 | 294 | ||
299 | |||
300 | no_page_found: | 295 | no_page_found: |
301 | |||
302 | |||
303 | if (perm_err) | ||
304 | return -EPERM; | ||
305 | |||
306 | return -ENOENT; | 296 | return -ENOENT; |
307 | 297 | ||
308 | no_seg_found: | 298 | no_seg_found: |