Skip to content

Commit f536961

Browse files
committed
KVM: x86: Move IRQ routing/delivery APIs from x86.c => irq.c
Move a bunch of IRQ routing and delivery APIs from x86.c to irq.c. x86.c has grown quite fat, and irq.c is the perfect landing spot. Opportunistically rewrite kvm_arch_irq_bypass_del_producer()'s comment, as the existing comment has several typos and is rather confusing. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Link: https://lore.kernel.org/r/20250611224604.313496-28-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 0a64c44 commit f536961

File tree

2 files changed

+88
-87
lines changed

2 files changed

+88
-87
lines changed

arch/x86/kvm/irq.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <linux/export.h>
1313
#include <linux/kvm_host.h>
14+
#include <linux/kvm_irqfd.h>
1415

1516
#include "hyperv.h"
1617
#include "ioapic.h"
@@ -332,6 +333,18 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
332333
return -EWOULDBLOCK;
333334
}
334335

336+
int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event,
337+
bool line_status)
338+
{
339+
if (!irqchip_in_kernel(kvm))
340+
return -ENXIO;
341+
342+
irq_event->status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
343+
irq_event->irq, irq_event->level,
344+
line_status);
345+
return 0;
346+
}
347+
335348
bool kvm_arch_can_set_irq_routing(struct kvm *kvm)
336349
{
337350
return irqchip_in_kernel(kvm);
@@ -495,6 +508,81 @@ void kvm_arch_irq_routing_update(struct kvm *kvm)
495508
kvm_make_scan_ioapic_request(kvm);
496509
}
497510

511+
int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
512+
struct irq_bypass_producer *prod)
513+
{
514+
struct kvm_kernel_irqfd *irqfd =
515+
container_of(cons, struct kvm_kernel_irqfd, consumer);
516+
struct kvm *kvm = irqfd->kvm;
517+
int ret = 0;
518+
519+
kvm_arch_start_assignment(irqfd->kvm);
520+
521+
spin_lock_irq(&kvm->irqfds.lock);
522+
irqfd->producer = prod;
523+
524+
if (irqfd->irq_entry.type == KVM_IRQ_ROUTING_MSI) {
525+
ret = kvm_x86_call(pi_update_irte)(irqfd, irqfd->kvm, prod->irq,
526+
irqfd->gsi, &irqfd->irq_entry);
527+
if (ret)
528+
kvm_arch_end_assignment(irqfd->kvm);
529+
}
530+
spin_unlock_irq(&kvm->irqfds.lock);
531+
532+
return ret;
533+
}
534+
535+
void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
536+
struct irq_bypass_producer *prod)
537+
{
538+
struct kvm_kernel_irqfd *irqfd =
539+
container_of(cons, struct kvm_kernel_irqfd, consumer);
540+
struct kvm *kvm = irqfd->kvm;
541+
int ret;
542+
543+
WARN_ON(irqfd->producer != prod);
544+
545+
/*
546+
* If the producer of an IRQ that is currently being posted to a vCPU
547+
* is unregistered, change the associated IRTE back to remapped mode as
548+
* the IRQ has been released (or repurposed) by the device driver, i.e.
549+
* KVM must relinquish control of the IRTE.
550+
*/
551+
spin_lock_irq(&kvm->irqfds.lock);
552+
irqfd->producer = NULL;
553+
554+
if (irqfd->irq_entry.type == KVM_IRQ_ROUTING_MSI) {
555+
ret = kvm_x86_call(pi_update_irte)(irqfd, irqfd->kvm, prod->irq,
556+
irqfd->gsi, NULL);
557+
if (ret)
558+
pr_info("irq bypass consumer (eventfd %p) unregistration fails: %d\n",
559+
irqfd->consumer.eventfd, ret);
560+
}
561+
562+
spin_unlock_irq(&kvm->irqfds.lock);
563+
564+
565+
kvm_arch_end_assignment(irqfd->kvm);
566+
}
567+
568+
int kvm_arch_update_irqfd_routing(struct kvm_kernel_irqfd *irqfd,
569+
struct kvm_kernel_irq_routing_entry *old,
570+
struct kvm_kernel_irq_routing_entry *new)
571+
{
572+
return kvm_x86_call(pi_update_irte)(irqfd, irqfd->kvm, irqfd->producer->irq,
573+
irqfd->gsi, new);
574+
}
575+
576+
bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old,
577+
struct kvm_kernel_irq_routing_entry *new)
578+
{
579+
if (old->type != KVM_IRQ_ROUTING_MSI ||
580+
new->type != KVM_IRQ_ROUTING_MSI)
581+
return true;
582+
583+
return !!memcmp(&old->msi, &new->msi, sizeof(new->msi));
584+
}
585+
498586
#ifdef CONFIG_KVM_IOAPIC
499587
#define IOAPIC_ROUTING_ENTRY(irq) \
500588
{ .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \

arch/x86/kvm/x86.c

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -6420,18 +6420,6 @@ void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
64206420
kvm_vcpu_kick(vcpu);
64216421
}
64226422

6423-
int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event,
6424-
bool line_status)
6425-
{
6426-
if (!irqchip_in_kernel(kvm))
6427-
return -ENXIO;
6428-
6429-
irq_event->status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
6430-
irq_event->irq, irq_event->level,
6431-
line_status);
6432-
return 0;
6433-
}
6434-
64356423
int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
64366424
struct kvm_enable_cap *cap)
64376425
{
@@ -13504,81 +13492,6 @@ bool kvm_arch_has_noncoherent_dma(struct kvm *kvm)
1350413492
}
1350513493
EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma);
1350613494

13507-
int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
13508-
struct irq_bypass_producer *prod)
13509-
{
13510-
struct kvm_kernel_irqfd *irqfd =
13511-
container_of(cons, struct kvm_kernel_irqfd, consumer);
13512-
struct kvm *kvm = irqfd->kvm;
13513-
int ret = 0;
13514-
13515-
kvm_arch_start_assignment(irqfd->kvm);
13516-
13517-
spin_lock_irq(&kvm->irqfds.lock);
13518-
irqfd->producer = prod;
13519-
13520-
if (irqfd->irq_entry.type == KVM_IRQ_ROUTING_MSI) {
13521-
ret = kvm_x86_call(pi_update_irte)(irqfd, irqfd->kvm, prod->irq,
13522-
irqfd->gsi, &irqfd->irq_entry);
13523-
if (ret)
13524-
kvm_arch_end_assignment(irqfd->kvm);
13525-
}
13526-
spin_unlock_irq(&kvm->irqfds.lock);
13527-
13528-
return ret;
13529-
}
13530-
13531-
void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
13532-
struct irq_bypass_producer *prod)
13533-
{
13534-
struct kvm_kernel_irqfd *irqfd =
13535-
container_of(cons, struct kvm_kernel_irqfd, consumer);
13536-
struct kvm *kvm = irqfd->kvm;
13537-
int ret;
13538-
13539-
WARN_ON(irqfd->producer != prod);
13540-
13541-
/*
13542-
* When producer of consumer is unregistered, we change back to
13543-
* remapped mode, so we can re-use the current implementation
13544-
* when the irq is masked/disabled or the consumer side (KVM
13545-
* int this case doesn't want to receive the interrupts.
13546-
*/
13547-
spin_lock_irq(&kvm->irqfds.lock);
13548-
irqfd->producer = NULL;
13549-
13550-
if (irqfd->irq_entry.type == KVM_IRQ_ROUTING_MSI) {
13551-
ret = kvm_x86_call(pi_update_irte)(irqfd, irqfd->kvm, prod->irq,
13552-
irqfd->gsi, NULL);
13553-
if (ret)
13554-
pr_info("irq bypass consumer (eventfd %p) unregistration fails: %d\n",
13555-
irqfd->consumer.eventfd, ret);
13556-
}
13557-
13558-
spin_unlock_irq(&kvm->irqfds.lock);
13559-
13560-
13561-
kvm_arch_end_assignment(irqfd->kvm);
13562-
}
13563-
13564-
int kvm_arch_update_irqfd_routing(struct kvm_kernel_irqfd *irqfd,
13565-
struct kvm_kernel_irq_routing_entry *old,
13566-
struct kvm_kernel_irq_routing_entry *new)
13567-
{
13568-
return kvm_x86_call(pi_update_irte)(irqfd, irqfd->kvm, irqfd->producer->irq,
13569-
irqfd->gsi, new);
13570-
}
13571-
13572-
bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old,
13573-
struct kvm_kernel_irq_routing_entry *new)
13574-
{
13575-
if (old->type != KVM_IRQ_ROUTING_MSI ||
13576-
new->type != KVM_IRQ_ROUTING_MSI)
13577-
return true;
13578-
13579-
return !!memcmp(&old->msi, &new->msi, sizeof(new->msi));
13580-
}
13581-
1358213495
bool kvm_vector_hashing_enabled(void)
1358313496
{
1358413497
return vector_hashing;

0 commit comments

Comments
 (0)