aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2014-09-02 05:27:33 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-09-17 07:10:08 -0400
commitd60eacb07053142bfb9b41582074a89a790a9d46 (patch)
treede5bddd60b8cf78dbe0c7eabbe4d46ae656713a7 /virt/kvm/kvm_main.c
parent184564efae4d775225c8fe3b762a56956fb1f827 (diff)
KVM: device: add simple registration mechanism for kvm_device_ops
kvm_ioctl_create_device currently has knowledge of all the device types and their associated ops. This is fairly inflexible when adding support for new in-kernel device emulations, so move what we currently have out into a table, which can support dynamic registration of ops by new drivers for virtual hardware. Cc: Alex Williamson <Alex.Williamson@redhat.com> Cc: Alex Graf <agraf@suse.de> Cc: Gleb Natapov <gleb@kernel.org> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index c338599804e0..686d783387a0 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2272,44 +2272,55 @@ struct kvm_device *kvm_device_from_filp(struct file *filp)
2272 return filp->private_data; 2272 return filp->private_data;
2273} 2273}
2274 2274
2275static int kvm_ioctl_create_device(struct kvm *kvm, 2275static struct kvm_device_ops *kvm_device_ops_table[KVM_DEV_TYPE_MAX] = {
2276 struct kvm_create_device *cd)
2277{
2278 struct kvm_device_ops *ops = NULL;
2279 struct kvm_device *dev;
2280 bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
2281 int ret;
2282
2283 switch (cd->type) {
2284#ifdef CONFIG_KVM_MPIC 2276#ifdef CONFIG_KVM_MPIC
2285 case KVM_DEV_TYPE_FSL_MPIC_20: 2277 [KVM_DEV_TYPE_FSL_MPIC_20] = &kvm_mpic_ops,
2286 case KVM_DEV_TYPE_FSL_MPIC_42: 2278 [KVM_DEV_TYPE_FSL_MPIC_42] = &kvm_mpic_ops,
2287 ops = &kvm_mpic_ops;
2288 break;
2289#endif 2279#endif
2280
2290#ifdef CONFIG_KVM_XICS 2281#ifdef CONFIG_KVM_XICS
2291 case KVM_DEV_TYPE_XICS: 2282 [KVM_DEV_TYPE_XICS] = &kvm_xics_ops,
2292 ops = &kvm_xics_ops;
2293 break;
2294#endif 2283#endif
2284
2295#ifdef CONFIG_KVM_VFIO 2285#ifdef CONFIG_KVM_VFIO
2296 case KVM_DEV_TYPE_VFIO: 2286 [KVM_DEV_TYPE_VFIO] = &kvm_vfio_ops,
2297 ops = &kvm_vfio_ops;
2298 break;
2299#endif 2287#endif
2288
2300#ifdef CONFIG_KVM_ARM_VGIC 2289#ifdef CONFIG_KVM_ARM_VGIC
2301 case KVM_DEV_TYPE_ARM_VGIC_V2: 2290 [KVM_DEV_TYPE_ARM_VGIC_V2] = &kvm_arm_vgic_v2_ops,
2302 ops = &kvm_arm_vgic_v2_ops;
2303 break;
2304#endif 2291#endif
2292
2305#ifdef CONFIG_S390 2293#ifdef CONFIG_S390
2306 case KVM_DEV_TYPE_FLIC: 2294 [KVM_DEV_TYPE_FLIC] = &kvm_flic_ops,
2307 ops = &kvm_flic_ops;
2308 break;
2309#endif 2295#endif
2310 default: 2296};
2297
2298int kvm_register_device_ops(struct kvm_device_ops *ops, u32 type)
2299{
2300 if (type >= ARRAY_SIZE(kvm_device_ops_table))
2301 return -ENOSPC;
2302
2303 if (kvm_device_ops_table[type] != NULL)
2304 return -EEXIST;
2305
2306 kvm_device_ops_table[type] = ops;
2307 return 0;
2308}
2309
2310static int kvm_ioctl_create_device(struct kvm *kvm,
2311 struct kvm_create_device *cd)
2312{
2313 struct kvm_device_ops *ops = NULL;
2314 struct kvm_device *dev;
2315 bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
2316 int ret;
2317
2318 if (cd->type >= ARRAY_SIZE(kvm_device_ops_table))
2319 return -ENODEV;
2320
2321 ops = kvm_device_ops_table[cd->type];
2322 if (ops == NULL)
2311 return -ENODEV; 2323 return -ENODEV;
2312 }
2313 2324
2314 if (test) 2325 if (test)
2315 return 0; 2326 return 0;