From mboxrd@z Thu Jan 1 00:00:00 1970 From: Avi Kivity Subject: Re: [PATCH v5 09/13] ARM: KVM: Handle I/O aborts Date: Mon, 12 Dec 2011 15:54:05 +0200 Message-ID: <4EE6077D.2000306@redhat.com> References: <20111211102403.21693.6887.stgit@localhost> <20111211102516.21693.13260.stgit@localhost> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Cc: android-virt@lists.cs.columbia.edu, kvm@vger.kernel.org, Marc.Zyngier@arm.com, catalin.marinas@arm.com, tech@virtualopensystems.com, peter.maydell@linaro.org To: Christoffer Dall Return-path: Received: from mx1.redhat.com ([209.132.183.28]:42446 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752606Ab1LLNyV (ORCPT ); Mon, 12 Dec 2011 08:54:21 -0500 In-Reply-To: <20111211102516.21693.13260.stgit@localhost> Sender: kvm-owner@vger.kernel.org List-ID: On 12/11/2011 12:25 PM, Christoffer Dall wrote: > From: Christoffer Dall > > When the guest accesses I/O memory this will create data abort > exceptions and they are handled by decoding the HSR information > (physical address, read/write, length, register) and forwarding reads > and writes to QEMU which performs the device emulation. > > Certain classes of load/store operations do not support the syndrome > information provided in the HSR and we therefore must be able to fetch > the offending instruction from guest memory and decode it manually. > > This requires changing the general flow somewhat since new calls to run > the VCPU must check if there's a pending MMIO load and perform the write > after userspace has made the data available. > > } > > +/** > + * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation > + * @vcpu: The VCPU pointer > + * @run: The VCPU run struct containing the mmio data > + * > + * This should only be called after returning to QEMU for MMIO load emulation. s/to QEMU/from userspace/ > + */ > +int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) > +{ > + int *dest; > + unsigned int len; > + int mask; > + > + if (!run->mmio.is_write) { > + dest = vcpu_reg(vcpu, vcpu->arch.mmio_rd); > + memset(dest, 0, sizeof(int)); > + > + if (run->mmio.len > 4) { > + kvm_err(-EINVAL, "Incorrect mmio length"); > + return -EINVAL; > + } Time of check... > + > + len = run->mmio.len; > + memcpy(dest, run->mmio.data, len); ... time of use. Anything in run-> is untrusted. Best to use the kernel's copy of len. > + > + trace_kvm_mmio(KVM_TRACE_MMIO_READ, len, run->mmio.phys_addr, > + *((u64 *)run->mmio.data)); > + > + if (vcpu->arch.mmio_sign_extend && len < 4) { > + mask = 1U << ((len * 8) - 1); > + *dest = (*dest ^ mask) - mask; > + } > + } > + > + return 0; > +} > + > -- error compiling committee.c: too many arguments to function