@@ -882,6 +882,8 @@ On s390, a dummy irq routing table is created.
Note that on s390 the KVM_CAP_S390_IRQCHIP vm capability needs to be enabled
before KVM_CREATE_IRQCHIP can be used.
+The interrupt controller must be created before any extra VM planes.
+
4.25 KVM_IRQ_LINE
-----------------
@@ -7792,8 +7794,8 @@ used in the IRQ routing table. The first args[0] MSI routes are reserved
for the IOAPIC pins. Whenever the LAPIC receives an EOI for these routes,
a KVM_EXIT_IOAPIC_EOI vmexit will be reported to userspace.
-Fails if VCPU has already been created, or if the irqchip is already in the
-kernel (i.e. KVM_CREATE_IRQCHIP has already been called).
+Fails if VCPUs or planes have already been created, or if the irqchip is
+already in the kernel (i.e. KVM_CREATE_IRQCHIP has already been called).
7.6 KVM_CAP_S390_RI
-------------------
@@ -6561,7 +6561,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
r = -EEXIST;
if (irqchip_in_kernel(kvm))
goto split_irqchip_unlock;
- if (kvm->created_vcpus)
+ if (kvm->created_vcpus || kvm->has_planes)
goto split_irqchip_unlock;
/* Pairs with irqchip_in_kernel. */
smp_wmb();
@@ -7087,7 +7087,7 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
goto create_irqchip_unlock;
r = -EINVAL;
- if (kvm->created_vcpus)
+ if (kvm->created_vcpus || kvm->has_planes)
goto create_irqchip_unlock;
r = kvm_pic_init(kvm);
@@ -883,6 +883,7 @@ struct kvm {
bool dirty_ring_with_bitmap;
bool vm_bugged;
bool vm_dead;
+ bool has_planes;
#ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
struct notifier_block pm_notifier;
@@ -5316,6 +5316,7 @@ static int kvm_vm_ioctl_create_plane(struct kvm *kvm, unsigned id)
return fd;
plane = kvm_create_vm_plane(kvm, id);
+ kvm->has_planes = true;
if (IS_ERR(plane)) {
r = PTR_ERR(plane);
goto put_fd;
Force creating the irqchip before planes, so that APICV_INHIBIT_REASON_ABSENT only needs to be removed from plane 0. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- Documentation/virt/kvm/api.rst | 6 ++++-- arch/x86/kvm/x86.c | 4 ++-- include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 1 + 4 files changed, 8 insertions(+), 4 deletions(-)