summaryrefslogtreecommitdiff
path: root/virt/kvm/irqchip.c
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-10-20 00:10:27 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-10-20 00:10:27 -0300
commitd0b2f91bede3bd5e3d24dd6803e56eee959c1797 (patch)
tree7fee4ab0509879c373c4f2cbd5b8a5be5b4041ee /virt/kvm/irqchip.c
parente914f8eb445e8f74b00303c19c2ffceaedd16a05 (diff)
Linux-libre 4.8.2-gnupck-4.8.2-gnu
Diffstat (limited to 'virt/kvm/irqchip.c')
-rw-r--r--virt/kvm/irqchip.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index 8db197bb6..3bcc9990a 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);
}
@@ -135,7 +137,8 @@ void kvm_free_irq_routing(struct kvm *kvm)
free_irq_routing_table(rt);
}
-static int setup_routing_entry(struct kvm_irq_routing_table *rt,
+static int setup_routing_entry(struct kvm *kvm,
+ struct kvm_irq_routing_table *rt,
struct kvm_kernel_irq_routing_entry *e,
const struct kvm_irq_routing_entry *ue)
{
@@ -154,7 +157,7 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt,
e->gsi = ue->gsi;
e->type = ue->type;
- r = kvm_set_routing_entry(e, ue);
+ r = kvm_set_routing_entry(kvm, e, ue);
if (r)
goto out;
if (e->type == KVM_IRQ_ROUTING_IRQCHIP)
@@ -176,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;
@@ -199,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;
- }
- r = setup_routing_entry(new, e, ue);
- if (r) {
- 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)
+ goto free_entry;
++ue;
}
@@ -232,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);