diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2016-08-04 13:59:56 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-08-04 13:59:56 +0200 |
commit | 6f49b2f3414622d3e41135a65dac98968956662b (patch) | |
tree | efd4c358a40b9e6adb9dd35de3407bbf17bd2935 /virt/kvm/irqchip.c | |
parent | abe9efa79be02cf2ba27f643b214b07877bb050b (diff) | |
parent | 89581f06b2bc225f0c9822fa52e714aa2e3810dd (diff) |
Merge tag 'kvm-arm-for-4.8-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/ARM Changes for v4.8 - Take 2
Includes GSI routing support to go along with the new VGIC and a small fix that
has been cooking in -next for a while.
Diffstat (limited to 'virt/kvm/irqchip.c')
-rw-r--r-- | virt/kvm/irqchip.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index df99e9c3b64d..3bcc9990adf7 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c @@ -62,12 +62,14 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi) { struct kvm_kernel_irq_routing_entry route; - if (!irqchip_in_kernel(kvm) || msi->flags != 0) + if (!irqchip_in_kernel(kvm) || (msi->flags & ~KVM_MSI_VALID_DEVID)) return -EINVAL; route.msi.address_lo = msi->address_lo; route.msi.address_hi = msi->address_hi; route.msi.data = msi->data; + route.msi.flags = msi->flags; + route.msi.devid = msi->devid; return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false); } @@ -177,6 +179,7 @@ int kvm_set_irq_routing(struct kvm *kvm, unsigned flags) { struct kvm_irq_routing_table *new, *old; + struct kvm_kernel_irq_routing_entry *e; u32 i, j, nr_rt_entries = 0; int r; @@ -200,23 +203,25 @@ int kvm_set_irq_routing(struct kvm *kvm, new->chip[i][j] = -1; for (i = 0; i < nr; ++i) { - struct kvm_kernel_irq_routing_entry *e; - r = -ENOMEM; e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) goto out; r = -EINVAL; - if (ue->flags) { - kfree(e); - goto out; + switch (ue->type) { + case KVM_IRQ_ROUTING_MSI: + if (ue->flags & ~KVM_MSI_VALID_DEVID) + goto free_entry; + break; + default: + if (ue->flags) + goto free_entry; + break; } r = setup_routing_entry(kvm, new, e, ue); - if (r) { - kfree(e); - goto out; - } + if (r) + goto free_entry; ++ue; } @@ -233,7 +238,10 @@ int kvm_set_irq_routing(struct kvm *kvm, new = old; r = 0; + goto out; +free_entry: + kfree(e); out: free_irq_routing_table(new); |