aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-02-19 05:00:38 -0500
committerAvi Kivity <avi@redhat.com>2010-04-25 05:35:09 -0400
commit5467a97d0f0ac99d2db0281ce1762e85afe16da2 (patch)
treef77e4a7acd17c225626a70a63c9c288854547c0c /arch
parent71db4089361b9424314c41fcf92f63ce26263fcc (diff)
KVM: PPC: Make software load/store return eaddr
The Book3S KVM implementation contains some helper functions to load and store data from and to virtual addresses. Unfortunately, this helper used to keep the physical address it so nicely found out for us to itself. So let's change that and make it return the physical address it resolved. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h4
-rw-r--r--arch/powerpc/kvm/book3s.c41
-rw-r--r--arch/powerpc/kvm/book3s_64_emulate.c11
3 files changed, 33 insertions, 23 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index d28ee839ed84..8463976ff9f1 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -115,8 +115,8 @@ extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte);
115extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); 115extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr);
116extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); 116extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu);
117extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data); 117extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data);
118extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, bool data); 118extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data);
119extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr); 119extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, bool data);
120extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); 120extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec);
121extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, 121extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
122 bool upper, u32 val); 122 bool upper, u32 val);
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 55c38e598280..a9f45197a036 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -440,55 +440,64 @@ err:
440 return kvmppc_bad_hva(); 440 return kvmppc_bad_hva();
441} 441}
442 442
443int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr) 443int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
444 bool data)
444{ 445{
445 struct kvmppc_pte pte; 446 struct kvmppc_pte pte;
446 hva_t hva = eaddr; 447 hva_t hva = *eaddr;
447 448
448 vcpu->stat.st++; 449 vcpu->stat.st++;
449 450
450 if (kvmppc_xlate(vcpu, eaddr, false, &pte)) 451 if (kvmppc_xlate(vcpu, *eaddr, data, &pte))
451 goto err; 452 goto nopte;
453
454 *eaddr = pte.raddr;
452 455
453 hva = kvmppc_pte_to_hva(vcpu, &pte, false); 456 hva = kvmppc_pte_to_hva(vcpu, &pte, false);
454 if (kvm_is_error_hva(hva)) 457 if (kvm_is_error_hva(hva))
455 goto err; 458 goto mmio;
456 459
457 if (copy_to_user((void __user *)hva, ptr, size)) { 460 if (copy_to_user((void __user *)hva, ptr, size)) {
458 printk(KERN_INFO "kvmppc_st at 0x%lx failed\n", hva); 461 printk(KERN_INFO "kvmppc_st at 0x%lx failed\n", hva);
459 goto err; 462 goto mmio;
460 } 463 }
461 464
462 return 0; 465 return EMULATE_DONE;
463 466
464err: 467nopte:
465 return -ENOENT; 468 return -ENOENT;
469mmio:
470 return EMULATE_DO_MMIO;
466} 471}
467 472
468int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, 473int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
469 bool data) 474 bool data)
470{ 475{
471 struct kvmppc_pte pte; 476 struct kvmppc_pte pte;
472 hva_t hva = eaddr; 477 hva_t hva = *eaddr;
473 478
474 vcpu->stat.ld++; 479 vcpu->stat.ld++;
475 480
476 if (kvmppc_xlate(vcpu, eaddr, data, &pte)) 481 if (kvmppc_xlate(vcpu, *eaddr, data, &pte))
477 goto err; 482 goto nopte;
483
484 *eaddr = pte.raddr;
478 485
479 hva = kvmppc_pte_to_hva(vcpu, &pte, true); 486 hva = kvmppc_pte_to_hva(vcpu, &pte, true);
480 if (kvm_is_error_hva(hva)) 487 if (kvm_is_error_hva(hva))
481 goto err; 488 goto mmio;
482 489
483 if (copy_from_user(ptr, (void __user *)hva, size)) { 490 if (copy_from_user(ptr, (void __user *)hva, size)) {
484 printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva); 491 printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva);
485 goto err; 492 goto mmio;
486 } 493 }
487 494
488 return 0; 495 return EMULATE_DONE;
489 496
490err: 497nopte:
491 return -ENOENT; 498 return -ENOENT;
499mmio:
500 return EMULATE_DO_MMIO;
492} 501}
493 502
494static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) 503static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c
index e4e7ec318eb0..a93aa4719178 100644
--- a/arch/powerpc/kvm/book3s_64_emulate.c
+++ b/arch/powerpc/kvm/book3s_64_emulate.c
@@ -169,7 +169,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
169 { 169 {
170 ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst)); 170 ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst));
171 ulong ra = 0; 171 ulong ra = 0;
172 ulong addr; 172 ulong addr, vaddr;
173 u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 173 u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
174 174
175 if (get_ra(inst)) 175 if (get_ra(inst))
@@ -178,15 +178,16 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
178 addr = (ra + rb) & ~31ULL; 178 addr = (ra + rb) & ~31ULL;
179 if (!(vcpu->arch.msr & MSR_SF)) 179 if (!(vcpu->arch.msr & MSR_SF))
180 addr &= 0xffffffff; 180 addr &= 0xffffffff;
181 vaddr = addr;
181 182
182 if (kvmppc_st(vcpu, addr, 32, zeros)) { 183 if (kvmppc_st(vcpu, &addr, 32, zeros, true)) {
183 vcpu->arch.dear = addr; 184 vcpu->arch.dear = vaddr;
184 vcpu->arch.fault_dear = addr; 185 vcpu->arch.fault_dear = vaddr;
185 to_book3s(vcpu)->dsisr = DSISR_PROTFAULT | 186 to_book3s(vcpu)->dsisr = DSISR_PROTFAULT |
186 DSISR_ISSTORE; 187 DSISR_ISSTORE;
187 kvmppc_book3s_queue_irqprio(vcpu, 188 kvmppc_book3s_queue_irqprio(vcpu,
188 BOOK3S_INTERRUPT_DATA_STORAGE); 189 BOOK3S_INTERRUPT_DATA_STORAGE);
189 kvmppc_mmu_pte_flush(vcpu, addr, ~0xFFFULL); 190 kvmppc_mmu_pte_flush(vcpu, vaddr, ~0xFFFULL);
190 } 191 }
191 192
192 break; 193 break;