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 <ag...@suse.de>
---
 arch/powerpc/include/asm/kvm_book3s.h |    4 +-
 arch/powerpc/kvm/book3s.c             |   41 ++++++++++++++++++++-------------
 arch/powerpc/kvm/book3s_64_emulate.c  |   11 +++++----
 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 d28ee83..8463976 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);
 extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr);
 extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu);
 extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, 
bool data);
-extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, 
bool data);
-extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr);
+extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, 
bool data);
+extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, 
bool data);
 extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int 
vec);
 extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
                           bool upper, u32 val);
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 07f8b42..e8dccc6 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -439,55 +439,64 @@ err:
        return kvmppc_bad_hva();
 }
 
-int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr)
+int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
+             bool data)
 {
        struct kvmppc_pte pte;
-       hva_t hva = eaddr;
+       hva_t hva = *eaddr;
 
        vcpu->stat.st++;
 
-       if (kvmppc_xlate(vcpu, eaddr, false, &pte))
-               goto err;
+       if (kvmppc_xlate(vcpu, *eaddr, data, &pte))
+               goto nopte;
+
+       *eaddr = pte.raddr;
 
        hva = kvmppc_pte_to_hva(vcpu, &pte, false);
        if (kvm_is_error_hva(hva))
-               goto err;
+               goto mmio;
 
        if (copy_to_user((void __user *)hva, ptr, size)) {
                printk(KERN_INFO "kvmppc_st at 0x%lx failed\n", hva);
-               goto err;
+               goto mmio;
        }
 
-       return 0;
+       return EMULATE_DONE;
 
-err:
+nopte:
        return -ENOENT;
+mmio:
+       return EMULATE_DO_MMIO;
 }
 
-int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr,
+int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
                      bool data)
 {
        struct kvmppc_pte pte;
-       hva_t hva = eaddr;
+       hva_t hva = *eaddr;
 
        vcpu->stat.ld++;
 
-       if (kvmppc_xlate(vcpu, eaddr, data, &pte))
-               goto err;
+       if (kvmppc_xlate(vcpu, *eaddr, data, &pte))
+               goto nopte;
+
+       *eaddr = pte.raddr;
 
        hva = kvmppc_pte_to_hva(vcpu, &pte, true);
        if (kvm_is_error_hva(hva))
-               goto err;
+               goto mmio;
 
        if (copy_from_user(ptr, (void __user *)hva, size)) {
                printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva);
-               goto err;
+               goto mmio;
        }
 
-       return 0;
+       return EMULATE_DONE;
 
-err:
+nopte:
        return -ENOENT;
+mmio:
+       return EMULATE_DO_MMIO;
 }
 
 static 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 e4e7ec3..a93aa47 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,
                {
                        ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst));
                        ulong ra = 0;
-                       ulong addr;
+                       ulong addr, vaddr;
                        u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
                        if (get_ra(inst))
@@ -178,15 +178,16 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct 
kvm_vcpu *vcpu,
                        addr = (ra + rb) & ~31ULL;
                        if (!(vcpu->arch.msr & MSR_SF))
                                addr &= 0xffffffff;
+                       vaddr = addr;
 
-                       if (kvmppc_st(vcpu, addr, 32, zeros)) {
-                               vcpu->arch.dear = addr;
-                               vcpu->arch.fault_dear = addr;
+                       if (kvmppc_st(vcpu, &addr, 32, zeros, true)) {
+                               vcpu->arch.dear = vaddr;
+                               vcpu->arch.fault_dear = vaddr;
                                to_book3s(vcpu)->dsisr = DSISR_PROTFAULT |
                                                      DSISR_ISSTORE;
                                kvmppc_book3s_queue_irqprio(vcpu,
                                        BOOK3S_INTERRUPT_DATA_STORAGE);
-                               kvmppc_mmu_pte_flush(vcpu, addr, ~0xFFFULL);
+                               kvmppc_mmu_pte_flush(vcpu, vaddr, ~0xFFFULL);
                        }
 
                        break;
-- 
1.6.0.2

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to