aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kvm
diff options
context:
space:
mode:
authorChristoffer Dall <christoffer.dall@linaro.org>2016-03-29 08:29:28 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2016-05-20 09:39:42 -0400
commit83091db981e105d97562d3ed3ffe676e21927e3a (patch)
tree3c3b98bd138cc65fbe134f6e9b04ab27d0c4eca8 /arch/arm/kvm
parent2db4c104fa2a9af12c07433642e2e4fee37fe2fd (diff)
KVM: arm/arm64: Fix MMIO emulation data handling
When the kernel was handling a guest MMIO read access internally, we need to copy the emulation result into the run->mmio structure in order for the kvm_handle_mmio_return() function to pick it up and inject the result back into the guest. Currently the only user of kvm_io_bus for ARM is the VGIC, which did this copying itself, so this was not causing issues so far. But with the upcoming new vgic implementation we need this done properly. Update the kvm_handle_mmio_return description and cleanup the code to only perform a single copying when needed. Code and commit message inspired by Andre Przywara. Reported-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Andre Przywara <andre.przywara@arm.com> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r--arch/arm/kvm/mmio.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/arch/arm/kvm/mmio.c b/arch/arm/kvm/mmio.c
index 0f6600f05137..0158e9e3276d 100644
--- a/arch/arm/kvm/mmio.c
+++ b/arch/arm/kvm/mmio.c
@@ -87,11 +87,10 @@ static unsigned long mmio_read_buf(char *buf, unsigned int len)
87 87
88/** 88/**
89 * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation 89 * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation
90 * or in-kernel IO emulation
91 *
90 * @vcpu: The VCPU pointer 92 * @vcpu: The VCPU pointer
91 * @run: The VCPU run struct containing the mmio data 93 * @run: The VCPU run struct containing the mmio data
92 *
93 * This should only be called after returning from userspace for MMIO load
94 * emulation.
95 */ 94 */
96int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) 95int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
97{ 96{
@@ -206,18 +205,19 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
206 run->mmio.is_write = is_write; 205 run->mmio.is_write = is_write;
207 run->mmio.phys_addr = fault_ipa; 206 run->mmio.phys_addr = fault_ipa;
208 run->mmio.len = len; 207 run->mmio.len = len;
209 if (is_write)
210 memcpy(run->mmio.data, data_buf, len);
211 208
212 if (!ret) { 209 if (!ret) {
213 /* We handled the access successfully in the kernel. */ 210 /* We handled the access successfully in the kernel. */
211 if (!is_write)
212 memcpy(run->mmio.data, data_buf, len);
214 vcpu->stat.mmio_exit_kernel++; 213 vcpu->stat.mmio_exit_kernel++;
215 kvm_handle_mmio_return(vcpu, run); 214 kvm_handle_mmio_return(vcpu, run);
216 return 1; 215 return 1;
217 } else {
218 vcpu->stat.mmio_exit_user++;
219 } 216 }
220 217
218 if (is_write)
219 memcpy(run->mmio.data, data_buf, len);
220 vcpu->stat.mmio_exit_user++;
221 run->exit_reason = KVM_EXIT_MMIO; 221 run->exit_reason = KVM_EXIT_MMIO;
222 return 0; 222 return 0;
223} 223}