mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 04:04:43 +01:00
KVM: x86: Move IRQ mask notifier infrastructure to I/O APIC emulation
Move the IRQ mask logic to ioapic.c as KVM's only user is its in-kernel I/O APIC emulation. In addition to encapsulating more I/O APIC specific code, trimming down irq_comm.c helps pave the way for removing it entirely. Acked-by: Kai Huang <kai.huang@intel.com> Link: https://lore.kernel.org/r/20250611213557.294358-18-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
parent
8fd2a6d43a
commit
37b1761fe8
7 changed files with 57 additions and 50 deletions
|
|
@ -1427,9 +1427,6 @@ struct kvm_arch {
|
|||
struct delayed_work kvmclock_update_work;
|
||||
struct delayed_work kvmclock_sync_work;
|
||||
|
||||
/* reads protected by irq_srcu, writes by irq_lock */
|
||||
struct hlist_head mask_notifier_list;
|
||||
|
||||
#ifdef CONFIG_KVM_HYPERV
|
||||
struct kvm_hv hyperv;
|
||||
#endif
|
||||
|
|
@ -2039,19 +2036,6 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
|
|||
int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||
const void *val, int bytes);
|
||||
|
||||
struct kvm_irq_mask_notifier {
|
||||
void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked);
|
||||
int irq;
|
||||
struct hlist_node link;
|
||||
};
|
||||
|
||||
void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
|
||||
struct kvm_irq_mask_notifier *kimn);
|
||||
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
|
||||
struct kvm_irq_mask_notifier *kimn);
|
||||
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
|
||||
bool mask);
|
||||
|
||||
extern bool tdp_enabled;
|
||||
|
||||
u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <uapi/asm/kvm.h>
|
||||
|
||||
#include "ioapic.h"
|
||||
|
||||
#ifdef CONFIG_KVM_IOAPIC
|
||||
struct kvm_kpit_channel_state {
|
||||
u32 count; /* can be 65536 */
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include "ioapic.h"
|
||||
#include "irq.h"
|
||||
|
||||
#include <linux/kvm_host.h>
|
||||
|
|
|
|||
|
|
@ -310,6 +310,42 @@ void kvm_arch_post_irq_ack_notifier_list_update(struct kvm *kvm)
|
|||
kvm_make_scan_ioapic_request(kvm);
|
||||
}
|
||||
|
||||
void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
|
||||
struct kvm_irq_mask_notifier *kimn)
|
||||
{
|
||||
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
|
||||
|
||||
mutex_lock(&kvm->irq_lock);
|
||||
kimn->irq = irq;
|
||||
hlist_add_head_rcu(&kimn->link, &ioapic->mask_notifier_list);
|
||||
mutex_unlock(&kvm->irq_lock);
|
||||
}
|
||||
|
||||
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
|
||||
struct kvm_irq_mask_notifier *kimn)
|
||||
{
|
||||
mutex_lock(&kvm->irq_lock);
|
||||
hlist_del_rcu(&kimn->link);
|
||||
mutex_unlock(&kvm->irq_lock);
|
||||
synchronize_srcu(&kvm->irq_srcu);
|
||||
}
|
||||
|
||||
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
|
||||
bool mask)
|
||||
{
|
||||
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
|
||||
struct kvm_irq_mask_notifier *kimn;
|
||||
int idx, gsi;
|
||||
|
||||
idx = srcu_read_lock(&kvm->irq_srcu);
|
||||
gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
|
||||
if (gsi != -1)
|
||||
hlist_for_each_entry_rcu(kimn, &ioapic->mask_notifier_list, link)
|
||||
if (kimn->irq == gsi)
|
||||
kimn->func(kimn, mask);
|
||||
srcu_read_unlock(&kvm->irq_srcu, idx);
|
||||
}
|
||||
|
||||
static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
|
||||
{
|
||||
unsigned index;
|
||||
|
|
@ -710,6 +746,7 @@ int kvm_ioapic_init(struct kvm *kvm)
|
|||
return -ENOMEM;
|
||||
spin_lock_init(&ioapic->lock);
|
||||
INIT_DELAYED_WORK(&ioapic->eoi_inject, kvm_ioapic_eoi_inject_work);
|
||||
INIT_HLIST_HEAD(&ioapic->mask_notifier_list);
|
||||
kvm->arch.vioapic = ioapic;
|
||||
kvm_ioapic_reset(ioapic);
|
||||
kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops);
|
||||
|
|
|
|||
|
|
@ -86,8 +86,24 @@ struct kvm_ioapic {
|
|||
struct delayed_work eoi_inject;
|
||||
u32 irq_eoi[IOAPIC_NUM_PINS];
|
||||
u32 irr_delivered;
|
||||
|
||||
/* reads protected by irq_srcu, writes by irq_lock */
|
||||
struct hlist_head mask_notifier_list;
|
||||
};
|
||||
|
||||
struct kvm_irq_mask_notifier {
|
||||
void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked);
|
||||
int irq;
|
||||
struct hlist_node link;
|
||||
};
|
||||
|
||||
void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
|
||||
struct kvm_irq_mask_notifier *kimn);
|
||||
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
|
||||
struct kvm_irq_mask_notifier *kimn);
|
||||
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
|
||||
bool mask);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ASSERT(x) \
|
||||
do { \
|
||||
|
|
|
|||
|
|
@ -161,39 +161,6 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
|
|||
return -EWOULDBLOCK;
|
||||
}
|
||||
|
||||
void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
|
||||
struct kvm_irq_mask_notifier *kimn)
|
||||
{
|
||||
mutex_lock(&kvm->irq_lock);
|
||||
kimn->irq = irq;
|
||||
hlist_add_head_rcu(&kimn->link, &kvm->arch.mask_notifier_list);
|
||||
mutex_unlock(&kvm->irq_lock);
|
||||
}
|
||||
|
||||
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
|
||||
struct kvm_irq_mask_notifier *kimn)
|
||||
{
|
||||
mutex_lock(&kvm->irq_lock);
|
||||
hlist_del_rcu(&kimn->link);
|
||||
mutex_unlock(&kvm->irq_lock);
|
||||
synchronize_srcu(&kvm->irq_srcu);
|
||||
}
|
||||
|
||||
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
|
||||
bool mask)
|
||||
{
|
||||
struct kvm_irq_mask_notifier *kimn;
|
||||
int idx, gsi;
|
||||
|
||||
idx = srcu_read_lock(&kvm->irq_srcu);
|
||||
gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
|
||||
if (gsi != -1)
|
||||
hlist_for_each_entry_rcu(kimn, &kvm->arch.mask_notifier_list, link)
|
||||
if (kimn->irq == gsi)
|
||||
kimn->func(kimn, mask);
|
||||
srcu_read_unlock(&kvm->irq_srcu, idx);
|
||||
}
|
||||
|
||||
bool kvm_arch_can_set_irq_routing(struct kvm *kvm)
|
||||
{
|
||||
return irqchip_in_kernel(kvm);
|
||||
|
|
|
|||
|
|
@ -12676,7 +12676,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
|
|||
if (ret)
|
||||
goto out_uninit_mmu;
|
||||
|
||||
INIT_HLIST_HEAD(&kvm->arch.mask_notifier_list);
|
||||
atomic_set(&kvm->arch.noncoherent_dma_count, 0);
|
||||
|
||||
raw_spin_lock_init(&kvm->arch.tsc_write_lock);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue