mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 14:41:22 -05:00
KVM: x86: Trigger I/O APIC route rescan in kvm_arch_irq_routing_update()
Trigger the I/O APIC route rescan that's performed for a split IRQ chip after userspace updates IRQ routes in kvm_arch_irq_routing_update(), i.e. before dropping kvm->irq_lock. Calling kvm_make_all_cpus_request() under a mutex is perfectly safe, and the smp_wmb()+smp_mb__after_atomic() pair in __kvm_make_request()+kvm_check_request() ensures the new routing is visible to vCPUs prior to the request being visible to vCPUs. In all likelihood, commitb053b2aef2("KVM: x86: Add EOI exit bitmap inference") somewhat arbitrarily made the request outside of irq_lock to avoid holding irq_lock any longer than is strictly necessary. And then commitabdb080f7a("kvm/irqchip: kvm_arch_irq_routing_update renaming split") took the easy route of adding another arch hook instead of risking a functional change. Note, the call to synchronize_srcu_expedited() does NOT provide ordering guarantees with respect to vCPUs scanning the new routing; as above, the request infrastructure provides the necessary ordering. I.e. there's no need to wait for kvm_scan_ioapic_routes() to complete if it's actively running, because regardless of whether it grabs the old or new table, the vCPU will have another KVM_REQ_SCAN_IOAPIC pending, i.e. will rescan again and see the new mappings. Acked-by: Kai Huang <kai.huang@intel.com> Link: https://lore.kernel.org/r/20250611213557.294358-2-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
@@ -395,13 +395,6 @@ int kvm_setup_default_irq_routing(struct kvm *kvm)
|
||||
ARRAY_SIZE(default_routing), 0);
|
||||
}
|
||||
|
||||
void kvm_arch_post_irq_routing_update(struct kvm *kvm)
|
||||
{
|
||||
if (!irqchip_split(kvm))
|
||||
return;
|
||||
kvm_make_scan_ioapic_request(kvm);
|
||||
}
|
||||
|
||||
void kvm_scan_ioapic_irq(struct kvm_vcpu *vcpu, u32 dest_id, u16 dest_mode,
|
||||
u8 vector, unsigned long *ioapic_handled_vectors)
|
||||
{
|
||||
@@ -466,4 +459,7 @@ void kvm_arch_irq_routing_update(struct kvm *kvm)
|
||||
#ifdef CONFIG_KVM_HYPERV
|
||||
kvm_hv_irq_routing_update(kvm);
|
||||
#endif
|
||||
|
||||
if (irqchip_split(kvm))
|
||||
kvm_make_scan_ioapic_request(kvm);
|
||||
}
|
||||
|
||||
@@ -1024,14 +1024,10 @@ void vcpu_put(struct kvm_vcpu *vcpu);
|
||||
|
||||
#ifdef __KVM_HAVE_IOAPIC
|
||||
void kvm_arch_post_irq_ack_notifier_list_update(struct kvm *kvm);
|
||||
void kvm_arch_post_irq_routing_update(struct kvm *kvm);
|
||||
#else
|
||||
static inline void kvm_arch_post_irq_ack_notifier_list_update(struct kvm *kvm)
|
||||
{
|
||||
}
|
||||
static inline void kvm_arch_post_irq_routing_update(struct kvm *kvm)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAVE_KVM_IRQCHIP
|
||||
|
||||
@@ -222,8 +222,6 @@ int kvm_set_irq_routing(struct kvm *kvm,
|
||||
kvm_arch_irq_routing_update(kvm);
|
||||
mutex_unlock(&kvm->irq_lock);
|
||||
|
||||
kvm_arch_post_irq_routing_update(kvm);
|
||||
|
||||
synchronize_srcu_expedited(&kvm->irq_srcu);
|
||||
|
||||
new = old;
|
||||
|
||||
Reference in New Issue
Block a user