--- /dev/null
+From 1d6a821277aaa0cdd666278aaff93298df313d41 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Mon, 15 Feb 2016 17:04:04 +0000
+Subject: arm/arm64: KVM: Feed initialized memory to MMIO accesses
+
+From: Marc Zyngier <marc.zyngier@arm.com>
+
+commit 1d6a821277aaa0cdd666278aaff93298df313d41 upstream.
+
+On an MMIO access, we always copy the on-stack buffer info
+the shared "run" structure, even if this is a read access.
+This ends up leaking up to 8 bytes of uninitialized memory
+into userspace, depending on the size of the access.
+
+An obvious fix for this one is to only perform the copy if
+this is an actual write.
+
+Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/kvm/mmio.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/kvm/mmio.c
++++ b/arch/arm/kvm/mmio.c
+@@ -207,7 +207,8 @@ int io_mem_abort(struct kvm_vcpu *vcpu,
+ run->mmio.is_write = is_write;
+ run->mmio.phys_addr = fault_ipa;
+ run->mmio.len = len;
+- memcpy(run->mmio.data, data_buf, len);
++ if (is_write)
++ memcpy(run->mmio.data, data_buf, len);
+
+ if (!ret) {
+ /* We handled the access successfully in the kernel. */
--- /dev/null
+From 83091db981e105d97562d3ed3ffe676e21927e3a Mon Sep 17 00:00:00 2001
+From: Christoffer Dall <christoffer.dall@linaro.org>
+Date: Tue, 29 Mar 2016 14:29:28 +0200
+Subject: KVM: arm/arm64: Fix MMIO emulation data handling
+
+From: Christoffer Dall <christoffer.dall@linaro.org>
+
+commit 83091db981e105d97562d3ed3ffe676e21927e3a upstream.
+
+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>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/kvm/mmio.c | 11 ++++++-----
+ virt/kvm/arm/vgic.c | 7 -------
+ 2 files changed, 6 insertions(+), 12 deletions(-)
+
+--- a/arch/arm/kvm/mmio.c
++++ b/arch/arm/kvm/mmio.c
+@@ -87,11 +87,10 @@ static unsigned long mmio_read_buf(char
+
+ /**
+ * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation
++ * or in-kernel IO emulation
++ *
+ * @vcpu: The VCPU pointer
+ * @run: The VCPU run struct containing the mmio data
+- *
+- * This should only be called after returning from userspace for MMIO load
+- * emulation.
+ */
+ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
+ {
+@@ -207,15 +206,17 @@ int io_mem_abort(struct kvm_vcpu *vcpu,
+ run->mmio.is_write = is_write;
+ run->mmio.phys_addr = fault_ipa;
+ run->mmio.len = len;
+- if (is_write)
+- memcpy(run->mmio.data, data_buf, len);
+
+ if (!ret) {
+ /* We handled the access successfully in the kernel. */
++ if (!is_write)
++ memcpy(run->mmio.data, data_buf, len);
+ kvm_handle_mmio_return(vcpu, run);
+ return 1;
+ }
+
++ if (is_write)
++ memcpy(run->mmio.data, data_buf, len);
+ run->exit_reason = KVM_EXIT_MMIO;
+ return 0;
+ }
+--- a/virt/kvm/arm/vgic.c
++++ b/virt/kvm/arm/vgic.c
+@@ -821,7 +821,6 @@ static int vgic_handle_mmio_access(struc
+ struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+ struct vgic_io_device *iodev = container_of(this,
+ struct vgic_io_device, dev);
+- struct kvm_run *run = vcpu->run;
+ const struct vgic_io_range *range;
+ struct kvm_exit_mmio mmio;
+ bool updated_state;
+@@ -850,12 +849,6 @@ static int vgic_handle_mmio_access(struc
+ updated_state = false;
+ }
+ spin_unlock(&dist->lock);
+- run->mmio.is_write = is_write;
+- run->mmio.len = len;
+- run->mmio.phys_addr = addr;
+- memcpy(run->mmio.data, val, len);
+-
+- kvm_handle_mmio_return(vcpu, run);
+
+ if (updated_state)
+ vgic_kick_vcpus(vcpu->kvm);