diff options
Diffstat (limited to 'arch/powerpc/kvm/booke.c')
-rw-r--r-- | arch/powerpc/kvm/booke.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 924c7b4b1107..eb24383c87d2 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -24,10 +24,12 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/vmalloc.h> | 25 | #include <linux/vmalloc.h> |
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | |||
27 | #include <asm/cputable.h> | 28 | #include <asm/cputable.h> |
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
29 | #include <asm/kvm_ppc.h> | 30 | #include <asm/kvm_ppc.h> |
30 | #include <asm/cacheflush.h> | 31 | #include <asm/cacheflush.h> |
32 | #include <asm/kvm_44x.h> | ||
31 | 33 | ||
32 | #include "booke.h" | 34 | #include "booke.h" |
33 | #include "44x_tlb.h" | 35 | #include "44x_tlb.h" |
@@ -207,10 +209,6 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
207 | * handled this interrupt the moment we enabled interrupts. | 209 | * handled this interrupt the moment we enabled interrupts. |
208 | * Now we just offer it a chance to reschedule the guest. */ | 210 | * Now we just offer it a chance to reschedule the guest. */ |
209 | 211 | ||
210 | /* XXX At this point the TLB still holds our shadow TLB, so if | ||
211 | * we do reschedule the host will fault over it. Perhaps we | ||
212 | * should politely restore the host's entries to minimize | ||
213 | * misses before ceding control. */ | ||
214 | vcpu->stat.dec_exits++; | 212 | vcpu->stat.dec_exits++; |
215 | if (need_resched()) | 213 | if (need_resched()) |
216 | cond_resched(); | 214 | cond_resched(); |
@@ -281,14 +279,17 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
281 | r = RESUME_GUEST; | 279 | r = RESUME_GUEST; |
282 | break; | 280 | break; |
283 | 281 | ||
282 | /* XXX move to a 440-specific file. */ | ||
284 | case BOOKE_INTERRUPT_DTLB_MISS: { | 283 | case BOOKE_INTERRUPT_DTLB_MISS: { |
284 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
285 | struct kvmppc_44x_tlbe *gtlbe; | 285 | struct kvmppc_44x_tlbe *gtlbe; |
286 | unsigned long eaddr = vcpu->arch.fault_dear; | 286 | unsigned long eaddr = vcpu->arch.fault_dear; |
287 | int gtlb_index; | ||
287 | gfn_t gfn; | 288 | gfn_t gfn; |
288 | 289 | ||
289 | /* Check the guest TLB. */ | 290 | /* Check the guest TLB. */ |
290 | gtlbe = kvmppc_44x_dtlb_search(vcpu, eaddr); | 291 | gtlb_index = kvmppc_44x_dtlb_index(vcpu, eaddr); |
291 | if (!gtlbe) { | 292 | if (gtlb_index < 0) { |
292 | /* The guest didn't have a mapping for it. */ | 293 | /* The guest didn't have a mapping for it. */ |
293 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); | 294 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); |
294 | vcpu->arch.dear = vcpu->arch.fault_dear; | 295 | vcpu->arch.dear = vcpu->arch.fault_dear; |
@@ -298,6 +299,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
298 | break; | 299 | break; |
299 | } | 300 | } |
300 | 301 | ||
302 | gtlbe = &vcpu_44x->guest_tlb[gtlb_index]; | ||
301 | vcpu->arch.paddr_accessed = tlb_xlate(gtlbe, eaddr); | 303 | vcpu->arch.paddr_accessed = tlb_xlate(gtlbe, eaddr); |
302 | gfn = vcpu->arch.paddr_accessed >> PAGE_SHIFT; | 304 | gfn = vcpu->arch.paddr_accessed >> PAGE_SHIFT; |
303 | 305 | ||
@@ -309,7 +311,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
309 | * Either way, we need to satisfy the fault without | 311 | * Either way, we need to satisfy the fault without |
310 | * invoking the guest. */ | 312 | * invoking the guest. */ |
311 | kvmppc_mmu_map(vcpu, eaddr, vcpu->arch.paddr_accessed, gtlbe->tid, | 313 | kvmppc_mmu_map(vcpu, eaddr, vcpu->arch.paddr_accessed, gtlbe->tid, |
312 | gtlbe->word2, get_tlb_bytes(gtlbe)); | 314 | gtlbe->word2, get_tlb_bytes(gtlbe), gtlb_index); |
313 | vcpu->stat.dtlb_virt_miss_exits++; | 315 | vcpu->stat.dtlb_virt_miss_exits++; |
314 | r = RESUME_GUEST; | 316 | r = RESUME_GUEST; |
315 | } else { | 317 | } else { |
@@ -322,17 +324,20 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
322 | break; | 324 | break; |
323 | } | 325 | } |
324 | 326 | ||
327 | /* XXX move to a 440-specific file. */ | ||
325 | case BOOKE_INTERRUPT_ITLB_MISS: { | 328 | case BOOKE_INTERRUPT_ITLB_MISS: { |
329 | struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); | ||
326 | struct kvmppc_44x_tlbe *gtlbe; | 330 | struct kvmppc_44x_tlbe *gtlbe; |
327 | unsigned long eaddr = vcpu->arch.pc; | 331 | unsigned long eaddr = vcpu->arch.pc; |
328 | gpa_t gpaddr; | 332 | gpa_t gpaddr; |
329 | gfn_t gfn; | 333 | gfn_t gfn; |
334 | int gtlb_index; | ||
330 | 335 | ||
331 | r = RESUME_GUEST; | 336 | r = RESUME_GUEST; |
332 | 337 | ||
333 | /* Check the guest TLB. */ | 338 | /* Check the guest TLB. */ |
334 | gtlbe = kvmppc_44x_itlb_search(vcpu, eaddr); | 339 | gtlb_index = kvmppc_44x_itlb_index(vcpu, eaddr); |
335 | if (!gtlbe) { | 340 | if (gtlb_index < 0) { |
336 | /* The guest didn't have a mapping for it. */ | 341 | /* The guest didn't have a mapping for it. */ |
337 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ITLB_MISS); | 342 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ITLB_MISS); |
338 | vcpu->stat.itlb_real_miss_exits++; | 343 | vcpu->stat.itlb_real_miss_exits++; |
@@ -341,6 +346,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
341 | 346 | ||
342 | vcpu->stat.itlb_virt_miss_exits++; | 347 | vcpu->stat.itlb_virt_miss_exits++; |
343 | 348 | ||
349 | gtlbe = &vcpu_44x->guest_tlb[gtlb_index]; | ||
344 | gpaddr = tlb_xlate(gtlbe, eaddr); | 350 | gpaddr = tlb_xlate(gtlbe, eaddr); |
345 | gfn = gpaddr >> PAGE_SHIFT; | 351 | gfn = gpaddr >> PAGE_SHIFT; |
346 | 352 | ||
@@ -352,7 +358,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
352 | * Either way, we need to satisfy the fault without | 358 | * Either way, we need to satisfy the fault without |
353 | * invoking the guest. */ | 359 | * invoking the guest. */ |
354 | kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlbe->tid, | 360 | kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlbe->tid, |
355 | gtlbe->word2, get_tlb_bytes(gtlbe)); | 361 | gtlbe->word2, get_tlb_bytes(gtlbe), gtlb_index); |
356 | } else { | 362 | } else { |
357 | /* Guest mapped and leaped at non-RAM! */ | 363 | /* Guest mapped and leaped at non-RAM! */ |
358 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_MACHINE_CHECK); | 364 | kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_MACHINE_CHECK); |