]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: x86: Hardcode the PIT IRQ source ID to '2'
authorSean Christopherson <seanjc@google.com>
Wed, 11 Jun 2025 21:35:49 +0000 (14:35 -0700)
committerSean Christopherson <seanjc@google.com>
Fri, 20 Jun 2025 20:52:47 +0000 (13:52 -0700)
Hardcode the PIT's source IRQ ID to '2' instead of "finding" that bit 2
is always the first available bit in irq_sources_bitmap.  Bits 0 and 1 are
set/reserved by kvm_arch_init_vm(), i.e. long before kvm_create_pit() can
be invoked, and KVM allows at most one in-kernel PIT instance, i.e. it's
impossible for the PIT to find a different free bit (there are no other
users of kvm_request_irq_source_id().

Delete the now-defunct irq_sources_bitmap and all its associated code.

Acked-by: Kai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/r/20250611213557.294358-11-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/i8254.c
arch/x86/kvm/i8254.h
arch/x86/kvm/x86.c
include/linux/kvm_host.h

index bf4459d637cc252f6f1ff7feb69323d76c026b71..4d68680f7051ba33573c0da3e6cfc7cab23eab3c 100644 (file)
@@ -1397,7 +1397,6 @@ struct kvm_arch {
        bool pause_in_guest;
        bool cstate_in_guest;
 
-       unsigned long irq_sources_bitmap;
        s64 kvmclock_offset;
 
        /*
index 2bb223bf0dac267d4578a772aa28def37c21644e..fa8187608cfc0e40b0e81c449586f0d5da8ae605 100644 (file)
@@ -248,8 +248,8 @@ static void pit_do_work(struct kthread_work *work)
        if (atomic_read(&ps->reinject) && !atomic_xchg(&ps->irq_ack, 0))
                return;
 
-       kvm_set_irq(kvm, pit->irq_source_id, 0, 1, false);
-       kvm_set_irq(kvm, pit->irq_source_id, 0, 0, false);
+       kvm_set_irq(kvm, KVM_PIT_IRQ_SOURCE_ID, 0, 1, false);
+       kvm_set_irq(kvm, KVM_PIT_IRQ_SOURCE_ID, 0, 0, false);
 
        /*
         * Provides NMI watchdog support via Virtual Wire mode.
@@ -641,47 +641,11 @@ static void kvm_pit_reset(struct kvm_pit *pit)
        kvm_pit_reset_reinject(pit);
 }
 
-static int kvm_request_irq_source_id(struct kvm *kvm)
+static void kvm_pit_clear_all(struct kvm *kvm)
 {
-       unsigned long *bitmap = &kvm->arch.irq_sources_bitmap;
-       int irq_source_id;
-
-       mutex_lock(&kvm->irq_lock);
-       irq_source_id = find_first_zero_bit(bitmap, BITS_PER_LONG);
-
-       if (irq_source_id >= BITS_PER_LONG) {
-               pr_warn("exhausted allocatable IRQ sources!\n");
-               irq_source_id = -EFAULT;
-               goto unlock;
-       }
-
-       ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
-       ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID);
-       set_bit(irq_source_id, bitmap);
-unlock:
-       mutex_unlock(&kvm->irq_lock);
-
-       return irq_source_id;
-}
-
-static void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
-{
-       ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
-       ASSERT(irq_source_id != KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID);
-
        mutex_lock(&kvm->irq_lock);
-       if (irq_source_id < 0 ||
-           irq_source_id >= BITS_PER_LONG) {
-               pr_err("IRQ source ID out of range!\n");
-               goto unlock;
-       }
-       clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap);
-       if (!irqchip_full(kvm))
-               goto unlock;
-
-       kvm_ioapic_clear_all(kvm->arch.vioapic, irq_source_id);
-       kvm_pic_clear_all(kvm->arch.vpic, irq_source_id);
-unlock:
+       kvm_ioapic_clear_all(kvm->arch.vioapic, KVM_PIT_IRQ_SOURCE_ID);
+       kvm_pic_clear_all(kvm->arch.vpic, KVM_PIT_IRQ_SOURCE_ID);
        mutex_unlock(&kvm->irq_lock);
 }
 
@@ -788,10 +752,6 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
        if (!pit)
                return NULL;
 
-       pit->irq_source_id = kvm_request_irq_source_id(kvm);
-       if (pit->irq_source_id < 0)
-               goto fail_request;
-
        mutex_init(&pit->pit_state.lock);
 
        pid = get_pid(task_tgid(current));
@@ -843,8 +803,7 @@ fail_register_pit:
        kvm_pit_set_reinject(pit, false);
        kthread_destroy_worker(pit->worker);
 fail_kthread:
-       kvm_free_irq_source_id(kvm, pit->irq_source_id);
-fail_request:
+       kvm_pit_clear_all(kvm);
        kfree(pit);
        return NULL;
 }
@@ -861,7 +820,7 @@ void kvm_free_pit(struct kvm *kvm)
                kvm_pit_set_reinject(pit, false);
                hrtimer_cancel(&pit->pit_state.timer);
                kthread_destroy_worker(pit->worker);
-               kvm_free_irq_source_id(kvm, pit->irq_source_id);
+               kvm_pit_clear_all(kvm);
                kfree(pit);
        }
 }
index 338095829ec8a22a5eeddc1a305f747b9fd0f8a5..b9c1feb379a7ab3294f4e356c95b046a8abc283d 100644 (file)
@@ -44,7 +44,6 @@ struct kvm_pit {
        struct kvm_io_device speaker_dev;
        struct kvm *kvm;
        struct kvm_kpit_state pit_state;
-       int irq_source_id;
        struct kvm_irq_mask_notifier mask_notifier;
        struct kthread_worker *worker;
        struct kthread_work expired;
index 53f2ce2d40de5b927bc4f38e7de760f67f801a28..1d744730985ef2624fdd1129d8d239de5d3daf56 100644 (file)
@@ -12669,12 +12669,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        INIT_HLIST_HEAD(&kvm->arch.mask_notifier_list);
        atomic_set(&kvm->arch.noncoherent_dma_count, 0);
 
-       /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
-       set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap);
-       /* Reserve bit 1 of irq_sources_bitmap for irqfd-resampler */
-       set_bit(KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
-               &kvm->arch.irq_sources_bitmap);
-
        raw_spin_lock_init(&kvm->arch.tsc_write_lock);
        mutex_init(&kvm->arch.apic_map_lock);
        seqcount_raw_spinlock_init(&kvm->arch.pvclock_sc, &kvm->arch.tsc_write_lock);
index cba8fc4529e8e826a02d5d134ac0ffcfa568a719..4ff5ea29e3439070d097914cd14d647300826274 100644 (file)
@@ -190,6 +190,7 @@ bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req);
 
 #define KVM_USERSPACE_IRQ_SOURCE_ID            0
 #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID       1
+#define KVM_PIT_IRQ_SOURCE_ID                  2
 
 extern struct mutex kvm_lock;
 extern struct list_head vm_list;