Commit 0a022ecc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
 "Two KVM/arm fixes for MMIO emulation and UBSAN.

  Unusually, we're routing them via the arm64 tree as per Paolo's
  request on the list:

    https://lore.kernel.org/kvm/21ae69a2-2546-29d0-bff6-2ea825e3d968@redhat.com/

  We don't actually have any other arm64 fixes pending at the moment
  (touch wood), so I've pulled from Marc, written a merge commit, tagged
  the result and run it through my build/boot/bisect scripts"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  KVM: arm/arm64: VGIC: Properly initialise private IRQ affinity
  KVM: arm/arm64: Only skip MMIO insn once
parents 17d0fbf4 087eeea9
...@@ -86,6 +86,12 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) ...@@ -86,6 +86,12 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
unsigned int len; unsigned int len;
int mask; int mask;
/* Detect an already handled MMIO return */
if (unlikely(!vcpu->mmio_needed))
return 0;
vcpu->mmio_needed = 0;
if (!run->mmio.is_write) { if (!run->mmio.is_write) {
len = run->mmio.len; len = run->mmio.len;
if (len > sizeof(unsigned long)) if (len > sizeof(unsigned long))
...@@ -188,6 +194,7 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run, ...@@ -188,6 +194,7 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
run->mmio.is_write = is_write; run->mmio.is_write = is_write;
run->mmio.phys_addr = fault_ipa; run->mmio.phys_addr = fault_ipa;
run->mmio.len = len; run->mmio.len = len;
vcpu->mmio_needed = 1;
if (!ret) { if (!ret) {
/* We handled the access successfully in the kernel. */ /* We handled the access successfully in the kernel. */
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/kvm_host.h> #include <linux/kvm_host.h>
#include <kvm/arm_vgic.h> #include <kvm/arm_vgic.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_mmu.h> #include <asm/kvm_mmu.h>
#include "vgic.h" #include "vgic.h"
...@@ -164,12 +165,18 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis) ...@@ -164,12 +165,18 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis)
irq->vcpu = NULL; irq->vcpu = NULL;
irq->target_vcpu = vcpu0; irq->target_vcpu = vcpu0;
kref_init(&irq->refcount); kref_init(&irq->refcount);
if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2) { switch (dist->vgic_model) {
case KVM_DEV_TYPE_ARM_VGIC_V2:
irq->targets = 0; irq->targets = 0;
irq->group = 0; irq->group = 0;
} else { break;
case KVM_DEV_TYPE_ARM_VGIC_V3:
irq->mpidr = 0; irq->mpidr = 0;
irq->group = 1; irq->group = 1;
break;
default:
kfree(dist->spis);
return -EINVAL;
} }
} }
return 0; return 0;
...@@ -209,7 +216,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) ...@@ -209,7 +216,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
irq->intid = i; irq->intid = i;
irq->vcpu = NULL; irq->vcpu = NULL;
irq->target_vcpu = vcpu; irq->target_vcpu = vcpu;
irq->targets = 1U << vcpu->vcpu_id;
kref_init(&irq->refcount); kref_init(&irq->refcount);
if (vgic_irq_is_sgi(i)) { if (vgic_irq_is_sgi(i)) {
/* SGIs */ /* SGIs */
...@@ -219,11 +225,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) ...@@ -219,11 +225,6 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
/* PPIs */ /* PPIs */
irq->config = VGIC_CONFIG_LEVEL; irq->config = VGIC_CONFIG_LEVEL;
} }
if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
irq->group = 1;
else
irq->group = 0;
} }
if (!irqchip_in_kernel(vcpu->kvm)) if (!irqchip_in_kernel(vcpu->kvm))
...@@ -286,10 +287,19 @@ int vgic_init(struct kvm *kvm) ...@@ -286,10 +287,19 @@ int vgic_init(struct kvm *kvm)
for (i = 0; i < VGIC_NR_PRIVATE_IRQS; i++) { for (i = 0; i < VGIC_NR_PRIVATE_IRQS; i++) {
struct vgic_irq *irq = &vgic_cpu->private_irqs[i]; struct vgic_irq *irq = &vgic_cpu->private_irqs[i];
if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) switch (dist->vgic_model) {
case KVM_DEV_TYPE_ARM_VGIC_V3:
irq->group = 1; irq->group = 1;
else irq->mpidr = kvm_vcpu_get_mpidr_aff(vcpu);
break;
case KVM_DEV_TYPE_ARM_VGIC_V2:
irq->group = 0; irq->group = 0;
irq->targets = 1U << idx;
break;
default:
ret = -EINVAL;
goto out;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment