1 #if defined(CONFIG_PARAVIRT_XEN) || !defined(__KERNEL__)
2 #include "public/evtchn.h"
4 /******************************************************************************
7 * Communication via Xen event channels.
8 * Also definitions for the device that demuxes notifications to userspace.
10 * Copyright (c) 2003-2005, K A Fraser
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License version 2
14 * as published by the Free Software Foundation; or, when distributed
15 * separately from the Linux kernel or incorporated into other
16 * software packages, subject to the following license:
18 * Permission is hereby granted, free of charge, to any person obtaining a copy
19 * of this source file (the "Software"), to deal in the Software without
20 * restriction, including without limitation the rights to use, copy, modify,
21 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
22 * and to permit persons to whom the Software is furnished to do so, subject to
23 * the following conditions:
25 * The above copyright notice and this permission notice shall be included in
26 * all copies or substantial portions of the Software.
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
37 #ifndef __ASM_EVTCHN_H__
38 #define __ASM_EVTCHN_H__
40 #include <linux/interrupt.h>
41 #include <asm/hypervisor.h>
42 #include <asm/ptrace.h>
43 #include <asm/sync_bitops.h>
44 #include <xen/interface/event_channel.h>
45 #include <linux/smp.h>
48 * LOW-LEVEL DEFINITIONS
55 int bindcount; /* for dynamic IRQs */
56 #ifdef CONFIG_X86_IO_APIC
57 u8 vector; /* for physical IRQs */
61 struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node);
62 static inline int evtchn_make_refcounted(unsigned int evtchn) { return 0; }
66 * Dynamically bind an event source to an IRQ-like callback handler.
67 * On some platforms this may not be implemented via the Linux IRQ subsystem.
68 * The IRQ argument passed to the callback handler is the same as returned
69 * from the bind call. It may not correspond to a Linux IRQ number.
70 * Returns IRQ or negative errno.
72 int bind_caller_port_to_irqhandler(
73 unsigned int caller_port,
74 irq_handler_t handler,
75 unsigned long irqflags,
78 int bind_listening_port_to_irqhandler(
79 unsigned int remote_domain,
80 irq_handler_t handler,
81 unsigned long irqflags,
84 int bind_interdomain_evtchn_to_irqhandler(
85 unsigned int remote_domain,
86 unsigned int remote_port,
87 irq_handler_t handler,
88 unsigned long irqflags,
91 int bind_virq_to_irqhandler(
94 irq_handler_t handler,
95 unsigned long irqflags,
98 #if defined(CONFIG_SMP) && defined(CONFIG_XEN) && defined(CONFIG_X86)
99 int bind_virq_to_irqaction(
102 struct irqaction *action);
104 #define bind_virq_to_irqaction(virq, cpu, action) \
105 bind_virq_to_irqhandler(virq, cpu, (action)->handler, \
106 (action)->flags | IRQF_NOBALANCING, \
107 (action)->name, action)
109 #if defined(CONFIG_SMP) && !defined(MODULE)
111 int bind_ipi_to_irqhandler(
114 irq_handler_t handler,
115 unsigned long irqflags,
119 int bind_ipi_to_irqaction(
121 struct irqaction *action);
122 DECLARE_PER_CPU(DECLARE_BITMAP(, NR_IPIS), ipi_pending);
127 * Common unbind function for all event sources. Takes IRQ to unbind from.
128 * Automatically closes the underlying event channel (except for bindings
129 * made with bind_caller_port_to_irqhandler()).
131 void unbind_from_irqhandler(unsigned int irq, void *dev_id);
133 #if defined(CONFIG_SMP) && defined(CONFIG_XEN) && defined(CONFIG_X86)
134 /* Specialized unbind function for per-CPU IRQs. */
135 void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu,
138 #define unbind_from_per_cpu_irq(irq, cpu, action) \
139 unbind_from_irqhandler(irq, action)
143 void irq_resume(void);
146 /* Entry point for notifications into Linux subsystems. */
147 asmlinkage void evtchn_do_upcall(struct pt_regs *regs);
149 /* Mark a PIRQ as unavailable for dynamic allocation. */
150 void evtchn_register_pirq(int irq);
151 /* Map a Xen-supplied PIRQ to a dynamically allocated one. */
152 int evtchn_map_pirq(int irq, int xen_pirq);
153 /* Look up a Xen-supplied PIRQ for a dynamically allocated one. */
154 int evtchn_get_xen_pirq(int irq);
156 void mask_evtchn(int port);
157 void disable_all_local_evtchn(void);
158 void unmask_evtchn(int port);
159 unsigned int irq_from_evtchn(unsigned int port);
161 static inline int test_and_set_evtchn_mask(int port)
163 shared_info_t *s = HYPERVISOR_shared_info;
164 return sync_test_and_set_bit(port, s->evtchn_mask);
167 static inline void clear_evtchn(int port)
169 shared_info_t *s = HYPERVISOR_shared_info;
170 sync_clear_bit(port, s->evtchn_pending);
173 static inline void set_evtchn(int port)
175 shared_info_t *s = HYPERVISOR_shared_info;
176 sync_set_bit(port, s->evtchn_pending);
179 static inline int test_evtchn(int port)
181 shared_info_t *s = HYPERVISOR_shared_info;
182 return sync_test_bit(port, s->evtchn_pending);
185 static inline void notify_remote_via_evtchn(int port)
187 struct evtchn_send send = { .port = port };
188 VOID(HYPERVISOR_event_channel_op(EVTCHNOP_send, &send));
192 multi_notify_remote_via_evtchn(multicall_entry_t *mcl, int port)
194 struct evtchn_send *send = (void *)(mcl->args + 2);
196 BUILD_BUG_ON(sizeof(*send) > sizeof(mcl->args) - 2 * sizeof(*mcl->args));
198 mcl->op = __HYPERVISOR_event_channel_op;
199 mcl->args[0] = EVTCHNOP_send;
200 mcl->args[1] = (unsigned long)send;
203 static inline int close_evtchn(int port)
205 struct evtchn_close close = { .port = port };
206 return HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
209 /* Test an irq's pending state. */
210 int xen_test_irq_pending(int irq);
213 * Use these to access the event channel underlying the IRQ handle returned
214 * by bind_*_to_irqhandler().
216 void notify_remote_via_irq(int irq);
217 int multi_notify_remote_via_irq(multicall_entry_t *, int irq);
218 int irq_to_evtchn_port(int irq);
220 #if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)
221 void notify_remote_via_ipi(unsigned int ipi, unsigned int cpu);
222 void clear_ipi_evtchn(void);
225 #if defined(CONFIG_XEN_SPINLOCK_ACQUIRE_NESTING) \
226 && CONFIG_XEN_SPINLOCK_ACQUIRE_NESTING
227 void xen_spin_irq_enter(void);
228 void xen_spin_irq_exit(void);
230 static inline void xen_spin_irq_enter(void) {}
231 static inline void xen_spin_irq_exit(void) {}
234 #endif /* __ASM_EVTCHN_H__ */
235 #endif /* CONFIG_PARAVIRT_XEN */