Merge tag 'kvm-arm-for-4.8-take2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / virt / kvm / irqchip.c
index df99e9c..3bcc999 100644 (file)
@@ -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);