diff options
author | Will Deacon <will.deacon@arm.com> | 2014-09-02 05:27:33 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-09-17 07:10:08 -0400 |
commit | d60eacb07053142bfb9b41582074a89a790a9d46 (patch) | |
tree | de5bddd60b8cf78dbe0c7eabbe4d46ae656713a7 /virt/kvm/kvm_main.c | |
parent | 184564efae4d775225c8fe3b762a56956fb1f827 (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.c | 65 |
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 | ||
2275 | static int kvm_ioctl_create_device(struct kvm *kvm, | 2275 | static 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 | |||
2298 | int 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 | |||
2310 | static 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; |