Commit 61423c41 authored by Sean Christopherson's avatar Sean Christopherson
Browse files

KVM: x86: Hardcode the PIT IRQ source ID to '2'



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: default avatarKai Huang <kai.huang@intel.com>
Link: https://lore.kernel.org/r/20250611213557.294358-11-seanjc@google.com


Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
parent 77a74b8f
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -1397,7 +1397,6 @@ struct kvm_arch {
	bool pause_in_guest;
	bool cstate_in_guest;

	unsigned long irq_sources_bitmap;
	s64 kvmclock_offset;

	/*
+7 −48
Original line number Diff line number Diff line
@@ -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 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
	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);
	}
}
+0 −1
Original line number Diff line number Diff line
@@ -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;
+0 −6
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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;