KVM: x86: decouple irqchip_in_kernel() and pic_irqchip()
authorRadim Krčmář <rkrcmar@redhat.com>
Fri, 16 Dec 2016 15:10:02 +0000 (16:10 +0100)
committerRadim Krčmář <rkrcmar@redhat.com>
Mon, 9 Jan 2017 13:42:47 +0000 (14:42 +0100)
irqchip_in_kernel() tried to save a bit by reusing pic_irqchip(), but it
just complicated the code.
Add a separate state for the irqchip mode.

Reviewed-by: David Hildenbrand <david@redhat.com>
[Used Paolo's version of condition in irqchip_in_kernel().]
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/irq.h
arch/x86/kvm/x86.c

index a7066dc1a7e9ca894784b3eeee328c214f1c6162..fc03ab1f6110fe88d5d201ba8f7e021ee64d663b 100644 (file)
@@ -716,6 +716,12 @@ struct kvm_hv {
        HV_REFERENCE_TSC_PAGE tsc_ref;
 };
 
+enum kvm_irqchip_mode {
+       KVM_IRQCHIP_NONE,
+       KVM_IRQCHIP_KERNEL,       /* created with KVM_CREATE_IRQCHIP */
+       KVM_IRQCHIP_SPLIT,        /* created with KVM_CAP_SPLIT_IRQCHIP */
+};
+
 struct kvm_arch {
        unsigned int n_used_mmu_pages;
        unsigned int n_requested_mmu_pages;
@@ -788,7 +794,7 @@ struct kvm_arch {
 
        u64 disabled_quirks;
 
-       bool irqchip_split;
+       enum kvm_irqchip_mode irqchip_mode;
        u8 nr_reserved_ioapic_pins;
 
        bool disabled_lapic_found;
index 035731eb389755b6f92a6df270b0c00dc25bd81c..f4965bc2613c45b98835b17b44d31d33d695a42d 100644 (file)
@@ -93,18 +93,19 @@ static inline int pic_in_kernel(struct kvm *kvm)
 
 static inline int irqchip_split(struct kvm *kvm)
 {
-       return kvm->arch.irqchip_split;
+       return kvm->arch.irqchip_mode == KVM_IRQCHIP_SPLIT;
 }
 
-static inline int irqchip_in_kernel(struct kvm *kvm)
+static inline int irqchip_kernel(struct kvm *kvm)
 {
-       struct kvm_pic *vpic = pic_irqchip(kvm);
-       bool ret;
+       return kvm->arch.irqchip_mode == KVM_IRQCHIP_KERNEL;
+}
 
-       ret = (vpic != NULL);
-       ret |= irqchip_split(kvm);
+static inline int irqchip_in_kernel(struct kvm *kvm)
+{
+       bool ret = kvm->arch.irqchip_mode != KVM_IRQCHIP_NONE;
 
-       /* Read vpic before kvm->irq_routing.  */
+       /* Matches with wmb after initializing kvm->irq_routing. */
        smp_rmb();
        return ret;
 }
index c72a8d00a1c00938de2a98bc652a90987147ac19..0630ab438bd5bf95c84d4efea57f509e2ad4cfe2 100644 (file)
@@ -3894,7 +3894,7 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
                        goto split_irqchip_unlock;
                /* Pairs with irqchip_in_kernel. */
                smp_wmb();
-               kvm->arch.irqchip_split = true;
+               kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT;
                kvm->arch.nr_reserved_ioapic_pins = cap->args[0];
                r = 0;
 split_irqchip_unlock:
@@ -3988,8 +3988,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
                        mutex_unlock(&kvm->slots_lock);
                        goto create_irqchip_unlock;
                }
-               /* Write kvm->irq_routing before kvm->arch.vpic.  */
+               /* Write kvm->irq_routing before enabling irqchip_in_kernel. */
                smp_wmb();
+               kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
                kvm->arch.vpic = vpic;
        create_irqchip_unlock:
                mutex_unlock(&kvm->lock);