On Thu, 30 Aug 2012 14:21:28 -0700, Christoffer Dall <c.dall@xxxxxxxxxxxxxxxxxxxxxx> wrote: > When the guest uses mmio operations that do not have decode information > in the HSR, we decode these instructions manually, but the instruction > may be used to access the vgic distributor interface emulated inside the > kernel so we have to go through that path for both values of HSR.ISV. > > Signed-off-by: Christoffer Dall <c.dall@xxxxxxxxxxxxxxxxxxxxxx> One nit, see below: > @@ -758,34 +757,55 @@ static int io_mem_abort(struct kvm_vcpu *vcpu, > struct kvm_run *run, > return 1; > } > > + mmio->is_write = is_write; > + mmio->phys_addr = fault_ipa; > + mmio->len = len; > + vcpu->arch.mmio.sign_extend = sign_extend; > + vcpu->arch.mmio.rd = rd; > + > + /* > + * The MMIO instruction is emulated and should not be re-executed > + * in the guest. > + */ > + kvm_skip_instr(vcpu, (vcpu->arch.hsr >> 25) & 1); > + return 0; > +} > + > +static int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, > + phys_addr_t fault_ipa, struct kvm_memory_slot *memslot) > +{ > + struct kvm_exit_mmio mmio; > + unsigned long rd; > + int ret; > + > /* > * Prepare MMIO operation. First stash it in a private > * structure that we can use for in-kernel emulation. If the > * kernel can't handle it, copy it into run->mmio and let user > * space do its magic. > */ > - mmio.is_write = is_write; > - mmio.phys_addr = fault_ipa; > - mmio.len = len; > - vcpu->arch.mmio.sign_extend = sign_extend; > - vcpu->arch.mmio.rd = rd; > > - trace_kvm_mmio((is_write) ? KVM_TRACE_MMIO_WRITE : > - KVM_TRACE_MMIO_READ_UNSATISFIED, > - len, fault_ipa, (is_write) ? *vcpu_reg(vcpu, rd) : 0); > + if (vcpu->arch.hsr & HSR_ISV) > + ret = decode_hsr(vcpu, fault_ipa, &mmio); > + else > + ret = invalid_io_mem_abort(vcpu, fault_ipa, &mmio); > > - if (is_write) > - memcpy(mmio.data, vcpu_reg(vcpu, rd), len); > + if (ret != 0) > + return ret; > > - /* > - * The MMIO instruction is emulated and should not be re-executed > - * in the guest. > - */ > - kvm_skip_instr(vcpu, (vcpu->arch.hsr >> 25) & 1); > + rd = vcpu->arch.mmio.rd; > + trace_kvm_mmio((mmio.is_write) ? KVM_TRACE_MMIO_WRITE : > + KVM_TRACE_MMIO_READ_UNSATISFIED, > + mmio.len, fault_ipa, > + (mmio.is_write) ? *vcpu_reg(vcpu, rd) : 0); > + > + if (mmio.is_write) > + memcpy(mmio.data, vcpu_reg(vcpu, rd), mmio.len); > > if (vgic_handle_mmio(vcpu, run, &mmio)) > return 1; > > + run->exit_reason = KVM_EXIT_MMIO; > kvm_prepare_mmio(run, &mmio); kvm_prepare_mmio() already set the exit_reason field. M. -- Who you jivin' with that Cosmik Debris? _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm