|
@@ -2800,6 +2800,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
|
|
case KVM_CAP_HYPERV_TIME:
|
|
|
case KVM_CAP_IOAPIC_POLARITY_IGNORED:
|
|
|
case KVM_CAP_TSC_DEADLINE_TIMER:
|
|
|
+ case KVM_CAP_ENABLE_CAP_VM:
|
|
|
+ case KVM_CAP_DISABLE_QUIRKS:
|
|
|
#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
|
|
|
case KVM_CAP_ASSIGN_DEV_IRQ:
|
|
|
case KVM_CAP_PCI_2_3:
|
|
@@ -3847,6 +3849,26 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
|
|
|
+ struct kvm_enable_cap *cap)
|
|
|
+{
|
|
|
+ int r;
|
|
|
+
|
|
|
+ if (cap->flags)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ switch (cap->cap) {
|
|
|
+ case KVM_CAP_DISABLE_QUIRKS:
|
|
|
+ kvm->arch.disabled_quirks = cap->args[0];
|
|
|
+ r = 0;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ r = -EINVAL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return r;
|
|
|
+}
|
|
|
+
|
|
|
long kvm_arch_vm_ioctl(struct file *filp,
|
|
|
unsigned int ioctl, unsigned long arg)
|
|
|
{
|
|
@@ -4099,7 +4121,15 @@ long kvm_arch_vm_ioctl(struct file *filp,
|
|
|
r = 0;
|
|
|
break;
|
|
|
}
|
|
|
+ case KVM_ENABLE_CAP: {
|
|
|
+ struct kvm_enable_cap cap;
|
|
|
|
|
|
+ r = -EFAULT;
|
|
|
+ if (copy_from_user(&cap, argp, sizeof(cap)))
|
|
|
+ goto out;
|
|
|
+ r = kvm_vm_ioctl_enable_cap(kvm, &cap);
|
|
|
+ break;
|
|
|
+ }
|
|
|
default:
|
|
|
r = kvm_vm_ioctl_assigned_device(kvm, ioctl, arg);
|
|
|
}
|