From db78027aa1cf72c13be5b8d106bf4e42a62c0b62 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Fri, 19 Feb 2010 11:00:38 +0100 Subject: [PATCH] --- yaml --- r: 197604 b: refs/heads/master c: 5467a97d0f0ac99d2db0281ce1762e85afe16da2 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/powerpc/include/asm/kvm_book3s.h | 4 +- trunk/arch/powerpc/kvm/book3s.c | 41 +++++++++++++-------- trunk/arch/powerpc/kvm/book3s_64_emulate.c | 11 +++--- 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/[refs] b/[refs] index 40f9e2e3b8e6..ce70ffe80331 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 71db4089361b9424314c41fcf92f63ce26263fcc +refs/heads/master: 5467a97d0f0ac99d2db0281ce1762e85afe16da2 diff --git a/trunk/arch/powerpc/include/asm/kvm_book3s.h b/trunk/arch/powerpc/include/asm/kvm_book3s.h index d28ee839ed84..8463976ff9f1 100644 --- a/trunk/arch/powerpc/include/asm/kvm_book3s.h +++ b/trunk/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/trunk/arch/powerpc/kvm/book3s.c b/trunk/arch/powerpc/kvm/book3s.c index 55c38e598280..a9f45197a036 100644 --- a/trunk/arch/powerpc/kvm/book3s.c +++ b/trunk/arch/powerpc/kvm/book3s.c @@ -440,55 +440,64 @@ static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte, 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/trunk/arch/powerpc/kvm/book3s_64_emulate.c b/trunk/arch/powerpc/kvm/book3s_64_emulate.c index e4e7ec318eb0..a93aa4719178 100644 --- a/trunk/arch/powerpc/kvm/book3s_64_emulate.c +++ b/trunk/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;