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 | |
| 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')
| -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; |
