This will be used to destroy the KVM XICS or XIVE device when the sPAPR machine is reseted. When the VM boots, the CAS negotiation process will determine which interrupt mode to use and the appropriate KVM device will then be created. Signed-off-by: Cédric Le Goater <clg@xxxxxxxx> --- include/uapi/linux/kvm.h | 2 ++ virt/kvm/kvm_main.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index cda8b85f4849..2545e20f3cec 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1279,6 +1279,8 @@ struct kvm_s390_ucas_mapping { #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr) #define KVM_HAS_DEVICE_ATTR _IOW(KVMIO, 0xe3, struct kvm_device_attr) +#define KVM_DESTROY_DEVICE _IOWR(KVMIO, 0xf0, struct kvm_create_device) + /* * ioctls for vcpu fds */ diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 65dea3ffef68..10fc3fa522b3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2898,6 +2898,32 @@ static int kvm_ioctl_create_device(struct kvm *kvm, return 0; } +static int kvm_ioctl_destroy_device(struct kvm *kvm, + struct kvm_create_device *cd) +{ + struct fd f; + struct kvm_device *dev; + + f = fdget(cd->fd); + if (!f.file) + return -EBADF; + + dev = kvm_device_from_filp(f.file); + fdput(f); + + if (!dev) + return -EPERM; + + mutex_lock(&kvm->lock); + list_del(&dev->vm_node); + mutex_unlock(&kvm->lock); + dev->ops->destroy(dev); + + kvm_put_kvm(kvm); + + return 0; +} + static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) { switch (arg) { @@ -3093,6 +3119,20 @@ static long kvm_vm_ioctl(struct file *filp, r = 0; break; } + case KVM_DESTROY_DEVICE: { + struct kvm_create_device cd; + + r = -EFAULT; + if (copy_from_user(&cd, argp, sizeof(cd))) + goto out; + + r = kvm_ioctl_destroy_device(kvm, &cd); + if (r) + goto out; + + r = 0; + break; + } case KVM_CHECK_EXTENSION: r = kvm_vm_ioctl_check_extension_generic(kvm, arg); break; -- 2.13.6