Skip to content

Commit 37b1761

Browse files
committed
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>
1 parent 8fd2a6d commit 37b1761

File tree

7 files changed

+57
-50
lines changed

7 files changed

+57
-50
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,9 +1427,6 @@ struct kvm_arch {
14271427
struct delayed_work kvmclock_update_work;
14281428
struct delayed_work kvmclock_sync_work;
14291429

1430-
/* reads protected by irq_srcu, writes by irq_lock */
1431-
struct hlist_head mask_notifier_list;
1432-
14331430
#ifdef CONFIG_KVM_HYPERV
14341431
struct kvm_hv hyperv;
14351432
#endif
@@ -2039,19 +2036,6 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
20392036
int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
20402037
const void *val, int bytes);
20412038

2042-
struct kvm_irq_mask_notifier {
2043-
void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked);
2044-
int irq;
2045-
struct hlist_node link;
2046-
};
2047-
2048-
void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
2049-
struct kvm_irq_mask_notifier *kimn);
2050-
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
2051-
struct kvm_irq_mask_notifier *kimn);
2052-
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
2053-
bool mask);
2054-
20552039
extern bool tdp_enabled;
20562040

20572041
u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu);

arch/x86/kvm/i8254.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include <uapi/asm/kvm.h>
1010

11+
#include "ioapic.h"
12+
1113
#ifdef CONFIG_KVM_IOAPIC
1214
struct kvm_kpit_channel_state {
1315
u32 count; /* can be 65536 */

arch/x86/kvm/i8259.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <linux/mm.h>
3232
#include <linux/slab.h>
3333
#include <linux/bitops.h>
34+
35+
#include "ioapic.h"
3436
#include "irq.h"
3537

3638
#include <linux/kvm_host.h>

arch/x86/kvm/ioapic.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,42 @@ void kvm_arch_post_irq_ack_notifier_list_update(struct kvm *kvm)
310310
kvm_make_scan_ioapic_request(kvm);
311311
}
312312

313+
void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
314+
struct kvm_irq_mask_notifier *kimn)
315+
{
316+
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
317+
318+
mutex_lock(&kvm->irq_lock);
319+
kimn->irq = irq;
320+
hlist_add_head_rcu(&kimn->link, &ioapic->mask_notifier_list);
321+
mutex_unlock(&kvm->irq_lock);
322+
}
323+
324+
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
325+
struct kvm_irq_mask_notifier *kimn)
326+
{
327+
mutex_lock(&kvm->irq_lock);
328+
hlist_del_rcu(&kimn->link);
329+
mutex_unlock(&kvm->irq_lock);
330+
synchronize_srcu(&kvm->irq_srcu);
331+
}
332+
333+
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
334+
bool mask)
335+
{
336+
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
337+
struct kvm_irq_mask_notifier *kimn;
338+
int idx, gsi;
339+
340+
idx = srcu_read_lock(&kvm->irq_srcu);
341+
gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
342+
if (gsi != -1)
343+
hlist_for_each_entry_rcu(kimn, &ioapic->mask_notifier_list, link)
344+
if (kimn->irq == gsi)
345+
kimn->func(kimn, mask);
346+
srcu_read_unlock(&kvm->irq_srcu, idx);
347+
}
348+
313349
static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
314350
{
315351
unsigned index;
@@ -710,6 +746,7 @@ int kvm_ioapic_init(struct kvm *kvm)
710746
return -ENOMEM;
711747
spin_lock_init(&ioapic->lock);
712748
INIT_DELAYED_WORK(&ioapic->eoi_inject, kvm_ioapic_eoi_inject_work);
749+
INIT_HLIST_HEAD(&ioapic->mask_notifier_list);
713750
kvm->arch.vioapic = ioapic;
714751
kvm_ioapic_reset(ioapic);
715752
kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops);

arch/x86/kvm/ioapic.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,24 @@ struct kvm_ioapic {
8686
struct delayed_work eoi_inject;
8787
u32 irq_eoi[IOAPIC_NUM_PINS];
8888
u32 irr_delivered;
89+
90+
/* reads protected by irq_srcu, writes by irq_lock */
91+
struct hlist_head mask_notifier_list;
92+
};
93+
94+
struct kvm_irq_mask_notifier {
95+
void (*func)(struct kvm_irq_mask_notifier *kimn, bool masked);
96+
int irq;
97+
struct hlist_node link;
8998
};
9099

100+
void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
101+
struct kvm_irq_mask_notifier *kimn);
102+
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
103+
struct kvm_irq_mask_notifier *kimn);
104+
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
105+
bool mask);
106+
91107
#ifdef DEBUG
92108
#define ASSERT(x) \
93109
do { \

arch/x86/kvm/irq_comm.c

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -161,39 +161,6 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
161161
return -EWOULDBLOCK;
162162
}
163163

164-
void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
165-
struct kvm_irq_mask_notifier *kimn)
166-
{
167-
mutex_lock(&kvm->irq_lock);
168-
kimn->irq = irq;
169-
hlist_add_head_rcu(&kimn->link, &kvm->arch.mask_notifier_list);
170-
mutex_unlock(&kvm->irq_lock);
171-
}
172-
173-
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
174-
struct kvm_irq_mask_notifier *kimn)
175-
{
176-
mutex_lock(&kvm->irq_lock);
177-
hlist_del_rcu(&kimn->link);
178-
mutex_unlock(&kvm->irq_lock);
179-
synchronize_srcu(&kvm->irq_srcu);
180-
}
181-
182-
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
183-
bool mask)
184-
{
185-
struct kvm_irq_mask_notifier *kimn;
186-
int idx, gsi;
187-
188-
idx = srcu_read_lock(&kvm->irq_srcu);
189-
gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin);
190-
if (gsi != -1)
191-
hlist_for_each_entry_rcu(kimn, &kvm->arch.mask_notifier_list, link)
192-
if (kimn->irq == gsi)
193-
kimn->func(kimn, mask);
194-
srcu_read_unlock(&kvm->irq_srcu, idx);
195-
}
196-
197164
bool kvm_arch_can_set_irq_routing(struct kvm *kvm)
198165
{
199166
return irqchip_in_kernel(kvm);

arch/x86/kvm/x86.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12676,7 +12676,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
1267612676
if (ret)
1267712677
goto out_uninit_mmu;
1267812678

12679-
INIT_HLIST_HEAD(&kvm->arch.mask_notifier_list);
1268012679
atomic_set(&kvm->arch.noncoherent_dma_count, 0);
1268112680

1268212681
raw_spin_lock_init(&kvm->arch.tsc_write_lock);

0 commit comments

Comments
 (0)