diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2c3b226bc13b..b6f33547b3db 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -2274,6 +2274,36 @@ static long kvm_vm_ioctl(struct file *filp, | |||
2274 | break; | 2274 | break; |
2275 | } | 2275 | } |
2276 | #endif | 2276 | #endif |
2277 | #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING | ||
2278 | case KVM_SET_GSI_ROUTING: { | ||
2279 | struct kvm_irq_routing routing; | ||
2280 | struct kvm_irq_routing __user *urouting; | ||
2281 | struct kvm_irq_routing_entry *entries; | ||
2282 | |||
2283 | r = -EFAULT; | ||
2284 | if (copy_from_user(&routing, argp, sizeof(routing))) | ||
2285 | goto out; | ||
2286 | r = -EINVAL; | ||
2287 | if (routing.nr >= KVM_MAX_IRQ_ROUTES) | ||
2288 | goto out; | ||
2289 | if (routing.flags) | ||
2290 | goto out; | ||
2291 | r = -ENOMEM; | ||
2292 | entries = vmalloc(routing.nr * sizeof(*entries)); | ||
2293 | if (!entries) | ||
2294 | goto out; | ||
2295 | r = -EFAULT; | ||
2296 | urouting = argp; | ||
2297 | if (copy_from_user(entries, urouting->entries, | ||
2298 | routing.nr * sizeof(*entries))) | ||
2299 | goto out_free_irq_routing; | ||
2300 | r = kvm_set_irq_routing(kvm, entries, routing.nr, | ||
2301 | routing.flags); | ||
2302 | out_free_irq_routing: | ||
2303 | vfree(entries); | ||
2304 | break; | ||
2305 | } | ||
2306 | #endif /* CONFIG_HAVE_KVM_IRQ_ROUTING */ | ||
2277 | default: | 2307 | default: |
2278 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); | 2308 | r = kvm_arch_vm_ioctl(filp, ioctl, arg); |
2279 | if (r == -ENOTTY) | 2309 | if (r == -ENOTTY) |