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

xen/arm: receive Xen events on ARM

Compile events.c on ARM.
Parse, map and enable the IRQ to get event notifications from the device
tree (node "/xen").

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

+69 -4
+18
arch/arm/include/asm/xen/events.h
··· 1 + #ifndef _ASM_ARM_XEN_EVENTS_H 2 + #define _ASM_ARM_XEN_EVENTS_H 3 + 4 + #include <asm/ptrace.h> 5 + 6 + enum ipi_vector { 7 + XEN_PLACEHOLDER_VECTOR, 8 + 9 + /* Xen IPIs go here */ 10 + XEN_NR_IPIS, 11 + }; 12 + 13 + static inline int xen_irqs_disabled(struct pt_regs *regs) 14 + { 15 + return raw_irqs_disabled_flags(regs->ARM_cpsr); 16 + } 17 + 18 + #endif /* _ASM_ARM_XEN_EVENTS_H */
+33
arch/arm/xen/enlighten.c
··· 1 1 #include <xen/xen.h> 2 + #include <xen/events.h> 2 3 #include <xen/grant_table.h> 3 4 #include <xen/hvm.h> 4 5 #include <xen/interface/xen.h> ··· 10 9 #include <xen/xenbus.h> 11 10 #include <asm/xen/hypervisor.h> 12 11 #include <asm/xen/hypercall.h> 12 + #include <linux/interrupt.h> 13 + #include <linux/irqreturn.h> 13 14 #include <linux/module.h> 14 15 #include <linux/of.h> 15 16 #include <linux/of_irq.h> ··· 35 32 36 33 int xen_platform_pci_unplug = XEN_UNPLUG_ALL; 37 34 EXPORT_SYMBOL_GPL(xen_platform_pci_unplug); 35 + 36 + static __read_mostly int xen_events_irq = -1; 38 37 39 38 int xen_remap_domain_mfn_range(struct vm_area_struct *vma, 40 39 unsigned long addr, ··· 79 74 if (of_address_to_resource(node, GRANT_TABLE_PHYSADDR, &res)) 80 75 return 0; 81 76 xen_hvm_resume_frames = res.start >> PAGE_SHIFT; 77 + xen_events_irq = irq_of_parse_and_map(node, 0); 78 + pr_info("Xen %s support found, events_irq=%d gnttab_frame_pfn=%lx\n", 79 + version, xen_events_irq, xen_hvm_resume_frames); 82 80 xen_domain_type = XEN_HVM_DOMAIN; 83 81 84 82 xen_setup_features(); ··· 123 115 return 0; 124 116 } 125 117 core_initcall(xen_guest_init); 118 + 119 + static irqreturn_t xen_arm_callback(int irq, void *arg) 120 + { 121 + xen_hvm_evtchn_do_upcall(); 122 + return IRQ_HANDLED; 123 + } 124 + 125 + static int __init xen_init_events(void) 126 + { 127 + if (!xen_domain() || xen_events_irq < 0) 128 + return -ENODEV; 129 + 130 + xen_init_IRQ(); 131 + 132 + if (request_percpu_irq(xen_events_irq, xen_arm_callback, 133 + "events", xen_vcpu)) { 134 + pr_err("Error requesting IRQ %d\n", xen_events_irq); 135 + return -EINVAL; 136 + } 137 + 138 + enable_percpu_irq(xen_events_irq, 0); 139 + 140 + return 0; 141 + } 142 + postcore_initcall(xen_init_events);
+1
arch/x86/xen/enlighten.c
··· 33 33 #include <linux/memblock.h> 34 34 35 35 #include <xen/xen.h> 36 + #include <xen/events.h> 36 37 #include <xen/interface/xen.h> 37 38 #include <xen/interface/version.h> 38 39 #include <xen/interface/physdev.h>
+1
arch/x86/xen/irq.c
··· 5 5 #include <xen/interface/xen.h> 6 6 #include <xen/interface/sched.h> 7 7 #include <xen/interface/vcpu.h> 8 + #include <xen/events.h> 8 9 9 10 #include <asm/xen/hypercall.h> 10 11 #include <asm/xen/hypervisor.h>
-1
arch/x86/xen/xen-ops.h
··· 35 35 36 36 char * __init xen_memory_setup(void); 37 37 void __init xen_arch_setup(void); 38 - void __init xen_init_IRQ(void); 39 38 void xen_enable_sysenter(void); 40 39 void xen_enable_syscall(void); 41 40 void xen_vcpu_restore(void);
+14 -3
drivers/xen/events.c
··· 31 31 #include <linux/irqnr.h> 32 32 #include <linux/pci.h> 33 33 34 + #ifdef CONFIG_X86 34 35 #include <asm/desc.h> 35 36 #include <asm/ptrace.h> 36 37 #include <asm/irq.h> 37 38 #include <asm/idle.h> 38 39 #include <asm/io_apic.h> 39 - #include <asm/sync_bitops.h> 40 40 #include <asm/xen/page.h> 41 41 #include <asm/xen/pci.h> 42 + #endif 43 + #include <asm/sync_bitops.h> 42 44 #include <asm/xen/hypercall.h> 43 45 #include <asm/xen/hypervisor.h> 44 46 ··· 52 50 #include <xen/interface/event_channel.h> 53 51 #include <xen/interface/hvm/hvm_op.h> 54 52 #include <xen/interface/hvm/params.h> 53 + #include <xen/interface/physdev.h> 54 + #include <xen/interface/sched.h> 55 + #include <asm/hw_irq.h> 55 56 56 57 /* 57 58 * This lock protects updates to the following mapping and reference-count ··· 1391 1386 { 1392 1387 struct pt_regs *old_regs = set_irq_regs(regs); 1393 1388 1389 + #ifdef CONFIG_X86 1394 1390 exit_idle(); 1391 + #endif 1395 1392 irq_enter(); 1396 1393 1397 1394 __xen_evtchn_do_upcall(); ··· 1802 1795 void xen_callback_vector(void) {} 1803 1796 #endif 1804 1797 1805 - void __init xen_init_IRQ(void) 1798 + void xen_init_IRQ(void) 1806 1799 { 1807 - int i, rc; 1800 + int i; 1808 1801 1809 1802 evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), 1810 1803 GFP_KERNEL); ··· 1820 1813 1821 1814 pirq_needs_eoi = pirq_needs_eoi_flag; 1822 1815 1816 + #ifdef CONFIG_X86 1823 1817 if (xen_hvm_domain()) { 1824 1818 xen_callback_vector(); 1825 1819 native_init_IRQ(); ··· 1828 1820 * __acpi_register_gsi can point at the right function */ 1829 1821 pci_xen_hvm_init(); 1830 1822 } else { 1823 + int rc; 1831 1824 struct physdev_pirq_eoi_gmfn eoi_gmfn; 1832 1825 1833 1826 irq_ctx_init(smp_processor_id()); ··· 1844 1835 } else 1845 1836 pirq_needs_eoi = pirq_check_eoi_map; 1846 1837 } 1838 + #endif 1847 1839 } 1840 + EXPORT_SYMBOL_GPL(xen_init_IRQ);
+2
include/xen/events.h
··· 109 109 /* Determine whether to ignore this IRQ if it is passed to a guest. */ 110 110 int xen_test_irq_shared(int irq); 111 111 112 + /* initialize Xen IRQ subsystem */ 113 + void xen_init_IRQ(void); 112 114 #endif /* _XEN_EVENTS_H */