Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

xen: Allow platform PCI interrupt to be shared

When we don't use the per-CPU vector callback, we ask Xen to deliver event
channel interrupts as INTx on the PCI platform device. As such, it can be
shared with INTx on other PCI devices.

Set IRQF_SHARED, and make it return IRQ_HANDLED or IRQ_NONE according to
whether the evtchn_upcall_pending flag was actually set. Now I can share
the interrupt:

11: 82 0 IO-APIC 11-fasteoi xen-platform-pci, ens4

Drop the IRQF_TRIGGER_RISING. It has no effect when the IRQ is shared,
and besides, the only effect it was having even beforehand was to trigger
a debug message in both I/OAPIC and legacy PIC cases:

[ 0.915441] genirq: No set_type function for IRQ 11 (IO-APIC)
[ 0.951939] genirq: No set_type function for IRQ 11 (XT-PIC)

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://lore.kernel.org/r/f9a29a68d05668a3636dd09acd94d970269eaec6.camel@infradead.org
Signed-off-by: Juergen Gross <jgross@suse.com>

authored by

David Woodhouse and committed by
Juergen Gross
3e8cd711 caea091e

+9 -7
+6 -3
drivers/xen/events/events_base.c
··· 1710 1710 generic_handle_irq(irq); 1711 1711 } 1712 1712 1713 - static void __xen_evtchn_do_upcall(void) 1713 + static int __xen_evtchn_do_upcall(void) 1714 1714 { 1715 1715 struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); 1716 + int ret = vcpu_info->evtchn_upcall_pending ? IRQ_HANDLED : IRQ_NONE; 1716 1717 int cpu = smp_processor_id(); 1717 1718 struct evtchn_loop_ctrl ctrl = { 0 }; 1718 1719 ··· 1738 1737 * above. 1739 1738 */ 1740 1739 __this_cpu_inc(irq_epoch); 1740 + 1741 + return ret; 1741 1742 } 1742 1743 1743 1744 void xen_evtchn_do_upcall(struct pt_regs *regs) ··· 1754 1751 set_irq_regs(old_regs); 1755 1752 } 1756 1753 1757 - void xen_hvm_evtchn_do_upcall(void) 1754 + int xen_hvm_evtchn_do_upcall(void) 1758 1755 { 1759 - __xen_evtchn_do_upcall(); 1756 + return __xen_evtchn_do_upcall(); 1760 1757 } 1761 1758 EXPORT_SYMBOL_GPL(xen_hvm_evtchn_do_upcall); 1762 1759
+2 -3
drivers/xen/platform-pci.c
··· 64 64 65 65 static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id) 66 66 { 67 - xen_hvm_evtchn_do_upcall(); 68 - return IRQ_HANDLED; 67 + return xen_hvm_evtchn_do_upcall(); 69 68 } 70 69 71 70 static int xen_allocate_irq(struct pci_dev *pdev) 72 71 { 73 72 return request_irq(pdev->irq, do_hvm_evtchn_intr, 74 - IRQF_NOBALANCING | IRQF_TRIGGER_RISING, 73 + IRQF_NOBALANCING | IRQF_SHARED, 75 74 "xen-platform-pci", pdev); 76 75 } 77 76
+1 -1
include/xen/events.h
··· 107 107 108 108 int xen_set_callback_via(uint64_t via); 109 109 void xen_evtchn_do_upcall(struct pt_regs *regs); 110 - void xen_hvm_evtchn_do_upcall(void); 110 + int xen_hvm_evtchn_do_upcall(void); 111 111 112 112 /* Bind a pirq for a physical interrupt to an irq. */ 113 113 int xen_bind_pirq_gsi_to_irq(unsigned gsi,