|
@@ -2448,6 +2448,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
|
|
|
case KVM_CAP_ENABLE_CAP_VM:
|
|
|
case KVM_CAP_DISABLE_QUIRKS:
|
|
|
case KVM_CAP_SET_BOOT_CPU_ID:
|
|
|
+ case KVM_CAP_SPLIT_IRQCHIP:
|
|
|
#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
|
|
|
case KVM_CAP_ASSIGN_DEV_IRQ:
|
|
|
case KVM_CAP_PCI_2_3:
|
|
@@ -3555,6 +3556,24 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
|
|
|
kvm->arch.disabled_quirks = cap->args[0];
|
|
|
r = 0;
|
|
|
break;
|
|
|
+ case KVM_CAP_SPLIT_IRQCHIP: {
|
|
|
+ mutex_lock(&kvm->lock);
|
|
|
+ r = -EEXIST;
|
|
|
+ if (irqchip_in_kernel(kvm))
|
|
|
+ goto split_irqchip_unlock;
|
|
|
+ if (atomic_read(&kvm->online_vcpus))
|
|
|
+ goto split_irqchip_unlock;
|
|
|
+ r = kvm_setup_empty_irq_routing(kvm);
|
|
|
+ if (r)
|
|
|
+ goto split_irqchip_unlock;
|
|
|
+ /* Pairs with irqchip_in_kernel. */
|
|
|
+ smp_wmb();
|
|
|
+ kvm->arch.irqchip_split = true;
|
|
|
+ r = 0;
|
|
|
+split_irqchip_unlock:
|
|
|
+ mutex_unlock(&kvm->lock);
|
|
|
+ break;
|
|
|
+ }
|
|
|
default:
|
|
|
r = -EINVAL;
|
|
|
break;
|
|
@@ -3668,7 +3687,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
|
|
|
}
|
|
|
|
|
|
r = -ENXIO;
|
|
|
- if (!irqchip_in_kernel(kvm))
|
|
|
+ if (!irqchip_in_kernel(kvm) || irqchip_split(kvm))
|
|
|
goto get_irqchip_out;
|
|
|
r = kvm_vm_ioctl_get_irqchip(kvm, chip);
|
|
|
if (r)
|
|
@@ -3692,7 +3711,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
|
|
|
}
|
|
|
|
|
|
r = -ENXIO;
|
|
|
- if (!irqchip_in_kernel(kvm))
|
|
|
+ if (!irqchip_in_kernel(kvm) || irqchip_split(kvm))
|
|
|
goto set_irqchip_out;
|
|
|
r = kvm_vm_ioctl_set_irqchip(kvm, chip);
|
|
|
if (r)
|