1 /* SPDX-License-Identifier: MIT */ 2 /****************************************************************************** 3 * event_channel.h 4 * 5 * Event channels between domains. 6 * 7 * Copyright (c) 2003-2004, K A Fraser. 8 */ 9 10 #ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__ 11 #define __XEN_PUBLIC_EVENT_CHANNEL_H__ 12 13 #include "xen.h" 14 15 /* 16 * `incontents 150 evtchn Event Channels 17 * 18 * Event channels are the basic primitive provided by Xen for event 19 * notifications. An event is the Xen equivalent of a hardware 20 * interrupt. They essentially store one bit of information, the event 21 * of interest is signalled by transitioning this bit from 0 to 1. 22 * 23 * Notifications are received by a guest via an upcall from Xen, 24 * indicating when an event arrives (setting the bit). Further 25 * notifications are masked until the bit is cleared again (therefore, 26 * guests must check the value of the bit after re-enabling event 27 * delivery to ensure no missed notifications). 28 * 29 * Event notifications can be masked by setting a flag; this is 30 * equivalent to disabling interrupts and can be used to ensure 31 * atomicity of certain operations in the guest kernel. 32 * 33 * Event channels are represented by the evtchn_* fields in 34 * struct shared_info and struct vcpu_info. 35 */ 36 37 /* 38 * ` enum neg_errnoval 39 * ` HYPERVISOR_event_channel_op(enum event_channel_op cmd, void *args) 40 * ` 41 * @cmd == EVTCHNOP_* (event-channel operation). 42 * @args == struct evtchn_* Operation-specific extra arguments (NULL if none). 43 */ 44 45 /* ` enum event_channel_op { // EVTCHNOP_* => struct evtchn_* */ 46 #define EVTCHNOP_bind_interdomain 0 47 #define EVTCHNOP_bind_virq 1 48 #define EVTCHNOP_bind_pirq 2 49 #define EVTCHNOP_close 3 50 #define EVTCHNOP_send 4 51 #define EVTCHNOP_status 5 52 #define EVTCHNOP_alloc_unbound 6 53 #define EVTCHNOP_bind_ipi 7 54 #define EVTCHNOP_bind_vcpu 8 55 #define EVTCHNOP_unmask 9 56 #define EVTCHNOP_reset 10 57 #define EVTCHNOP_init_control 11 58 #define EVTCHNOP_expand_array 12 59 #define EVTCHNOP_set_priority 13 60 #ifdef __XEN__ 61 #define EVTCHNOP_reset_cont 14 62 #endif 63 /* ` } */ 64 65 typedef uint32_t evtchn_port_t; 66 DEFINE_XEN_GUEST_HANDLE(evtchn_port_t); 67 68 /* 69 * EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as 70 * accepting interdomain bindings from domain <remote_dom>. A fresh port 71 * is allocated in <dom> and returned as <port>. 72 * NOTES: 73 * 1. If the caller is unprivileged then <dom> must be DOMID_SELF. 74 * 2. <remote_dom> may be DOMID_SELF, allowing loopback connections. 75 */ 76 struct evtchn_alloc_unbound { 77 /* IN parameters */ 78 domid_t dom, remote_dom; 79 /* OUT parameters */ 80 evtchn_port_t port; 81 }; 82 typedef struct evtchn_alloc_unbound evtchn_alloc_unbound_t; 83 84 /* 85 * EVTCHNOP_bind_interdomain: Construct an interdomain event channel between 86 * the calling domain and <remote_dom>. <remote_dom,remote_port> must identify 87 * a port that is unbound and marked as accepting bindings from the calling 88 * domain. A fresh port is allocated in the calling domain and returned as 89 * <local_port>. 90 * 91 * In case the peer domain has already tried to set our event channel 92 * pending, before it was bound, EVTCHNOP_bind_interdomain always sets 93 * the local event channel pending. 94 * 95 * The usual pattern of use, in the guest's upcall (or subsequent 96 * handler) is as follows: (Re-enable the event channel for subsequent 97 * signalling and then) check for the existence of whatever condition 98 * is being waited for by other means, and take whatever action is 99 * needed (if any). 100 * 101 * NOTES: 102 * 1. <remote_dom> may be DOMID_SELF, allowing loopback connections. 103 */ 104 struct evtchn_bind_interdomain { 105 /* IN parameters. */ 106 domid_t remote_dom; 107 evtchn_port_t remote_port; 108 /* OUT parameters. */ 109 evtchn_port_t local_port; 110 }; 111 typedef struct evtchn_bind_interdomain evtchn_bind_interdomain_t; 112 113 /* 114 * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified 115 * vcpu. 116 * NOTES: 117 * 1. Virtual IRQs are classified as per-vcpu or global. See the VIRQ list 118 * in xen.h for the classification of each VIRQ. 119 * 2. Global VIRQs must be allocated on VCPU0 but can subsequently be 120 * re-bound via EVTCHNOP_bind_vcpu. 121 * 3. Per-vcpu VIRQs may be bound to at most one event channel per vcpu. 122 * The allocated event channel is bound to the specified vcpu and the 123 * binding cannot be changed. 124 */ 125 struct evtchn_bind_virq { 126 /* IN parameters. */ 127 uint32_t virq; /* enum virq */ 128 uint32_t vcpu; 129 /* OUT parameters. */ 130 evtchn_port_t port; 131 }; 132 typedef struct evtchn_bind_virq evtchn_bind_virq_t; 133 134 /* 135 * EVTCHNOP_bind_pirq: Bind a local event channel to a real IRQ (PIRQ <irq>). 136 * NOTES: 137 * 1. A physical IRQ may be bound to at most one event channel per domain. 138 * 2. Only a sufficiently-privileged domain may bind to a physical IRQ. 139 */ 140 struct evtchn_bind_pirq { 141 /* IN parameters. */ 142 uint32_t pirq; 143 #define BIND_PIRQ__WILL_SHARE 1 144 uint32_t flags; /* BIND_PIRQ__* */ 145 /* OUT parameters. */ 146 evtchn_port_t port; 147 }; 148 typedef struct evtchn_bind_pirq evtchn_bind_pirq_t; 149 150 /* 151 * EVTCHNOP_bind_ipi: Bind a local event channel to receive events. 152 * NOTES: 153 * 1. The allocated event channel is bound to the specified vcpu. The binding 154 * may not be changed. 155 */ 156 struct evtchn_bind_ipi { 157 uint32_t vcpu; 158 /* OUT parameters. */ 159 evtchn_port_t port; 160 }; 161 typedef struct evtchn_bind_ipi evtchn_bind_ipi_t; 162 163 /* 164 * EVTCHNOP_close: Close a local event channel <port>. If the channel is 165 * interdomain then the remote end is placed in the unbound state 166 * (EVTCHNSTAT_unbound), awaiting a new connection. 167 */ 168 struct evtchn_close { 169 /* IN parameters. */ 170 evtchn_port_t port; 171 }; 172 typedef struct evtchn_close evtchn_close_t; 173 174 /* 175 * EVTCHNOP_send: Send an event to the remote end of the channel whose local 176 * endpoint is <port>. 177 */ 178 struct evtchn_send { 179 /* IN parameters. */ 180 evtchn_port_t port; 181 }; 182 typedef struct evtchn_send evtchn_send_t; 183 184 /* 185 * EVTCHNOP_status: Get the current status of the communication channel which 186 * has an endpoint at <dom, port>. 187 * NOTES: 188 * 1. <dom> may be specified as DOMID_SELF. 189 * 2. Only a sufficiently-privileged domain may obtain the status of an event 190 * channel for which <dom> is not DOMID_SELF. 191 */ 192 struct evtchn_status { 193 /* IN parameters */ 194 domid_t dom; 195 evtchn_port_t port; 196 /* OUT parameters */ 197 #define EVTCHNSTAT_closed 0 /* Channel is not in use. */ 198 #define EVTCHNSTAT_unbound 1 /* Channel is waiting interdom connection.*/ 199 #define EVTCHNSTAT_interdomain 2 /* Channel is connected to remote domain. */ 200 #define EVTCHNSTAT_pirq 3 /* Channel is bound to a phys IRQ line. */ 201 #define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */ 202 #define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */ 203 uint32_t status; 204 uint32_t vcpu; /* VCPU to which this channel is bound. */ 205 union { 206 struct { 207 domid_t dom; 208 } unbound; /* EVTCHNSTAT_unbound */ 209 struct { 210 domid_t dom; 211 evtchn_port_t port; 212 } interdomain; /* EVTCHNSTAT_interdomain */ 213 uint32_t pirq; /* EVTCHNSTAT_pirq */ 214 uint32_t virq; /* EVTCHNSTAT_virq */ 215 } u; 216 }; 217 typedef struct evtchn_status evtchn_status_t; 218 219 /* 220 * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an 221 * event is pending. 222 * NOTES: 223 * 1. IPI-bound channels always notify the vcpu specified at bind time. 224 * This binding cannot be changed. 225 * 2. Per-VCPU VIRQ channels always notify the vcpu specified at bind time. 226 * This binding cannot be changed. 227 * 3. All other channels notify vcpu0 by default. This default is set when 228 * the channel is allocated (a port that is freed and subsequently reused 229 * has its binding reset to vcpu0). 230 */ 231 struct evtchn_bind_vcpu { 232 /* IN parameters. */ 233 evtchn_port_t port; 234 uint32_t vcpu; 235 }; 236 typedef struct evtchn_bind_vcpu evtchn_bind_vcpu_t; 237 238 /* 239 * EVTCHNOP_unmask: Unmask the specified local event-channel port and deliver 240 * a notification to the appropriate VCPU if an event is pending. 241 */ 242 struct evtchn_unmask { 243 /* IN parameters. */ 244 evtchn_port_t port; 245 }; 246 typedef struct evtchn_unmask evtchn_unmask_t; 247 248 /* 249 * EVTCHNOP_reset: Close all event channels associated with specified domain. 250 * NOTES: 251 * 1. <dom> may be specified as DOMID_SELF. 252 * 2. Only a sufficiently-privileged domain may specify other than DOMID_SELF. 253 * 3. Destroys all control blocks and event array, resets event channel 254 * operations to 2-level ABI if called with <dom> == DOMID_SELF and FIFO 255 * ABI was used. Guests should not bind events during EVTCHNOP_reset call 256 * as these events are likely to be lost. 257 */ 258 struct evtchn_reset { 259 /* IN parameters. */ 260 domid_t dom; 261 }; 262 typedef struct evtchn_reset evtchn_reset_t; 263 264 /* 265 * EVTCHNOP_init_control: initialize the control block for the FIFO ABI. 266 * 267 * Note: any events that are currently pending will not be resent and 268 * will be lost. Guests should call this before binding any event to 269 * avoid losing any events. 270 */ 271 struct evtchn_init_control { 272 /* IN parameters. */ 273 uint64_t control_gfn; 274 uint32_t offset; 275 uint32_t vcpu; 276 /* OUT parameters. */ 277 uint8_t link_bits; 278 uint8_t _pad[7]; 279 }; 280 typedef struct evtchn_init_control evtchn_init_control_t; 281 282 /* 283 * EVTCHNOP_expand_array: add an additional page to the event array. 284 */ 285 struct evtchn_expand_array { 286 /* IN parameters. */ 287 uint64_t array_gfn; 288 }; 289 typedef struct evtchn_expand_array evtchn_expand_array_t; 290 291 /* 292 * EVTCHNOP_set_priority: set the priority for an event channel. 293 */ 294 struct evtchn_set_priority { 295 /* IN parameters. */ 296 evtchn_port_t port; 297 uint32_t priority; 298 }; 299 typedef struct evtchn_set_priority evtchn_set_priority_t; 300 301 /* 302 * ` enum neg_errnoval 303 * ` HYPERVISOR_event_channel_op_compat(struct evtchn_op *op) 304 * ` 305 * Superceded by new event_channel_op() hypercall since 0x00030202. 306 */ 307 struct evtchn_op { 308 uint32_t cmd; /* enum event_channel_op */ 309 union { 310 evtchn_alloc_unbound_t alloc_unbound; 311 evtchn_bind_interdomain_t bind_interdomain; 312 evtchn_bind_virq_t bind_virq; 313 evtchn_bind_pirq_t bind_pirq; 314 evtchn_bind_ipi_t bind_ipi; 315 evtchn_close_t close; 316 evtchn_send_t send; 317 evtchn_status_t status; 318 evtchn_bind_vcpu_t bind_vcpu; 319 evtchn_unmask_t unmask; 320 } u; 321 }; 322 typedef struct evtchn_op evtchn_op_t; 323 DEFINE_XEN_GUEST_HANDLE(evtchn_op_t); 324 325 /* 326 * 2-level ABI 327 */ 328 329 #define EVTCHN_2L_NR_CHANNELS (sizeof(xen_ulong_t) * sizeof(xen_ulong_t) * 64) 330 331 /* 332 * FIFO ABI 333 */ 334 335 /* Events may have priorities from 0 (highest) to 15 (lowest). */ 336 #define EVTCHN_FIFO_PRIORITY_MAX 0 337 #define EVTCHN_FIFO_PRIORITY_DEFAULT 7 338 #define EVTCHN_FIFO_PRIORITY_MIN 15 339 340 #define EVTCHN_FIFO_MAX_QUEUES (EVTCHN_FIFO_PRIORITY_MIN + 1) 341 342 typedef uint32_t event_word_t; 343 344 #define EVTCHN_FIFO_PENDING 31 345 #define EVTCHN_FIFO_MASKED 30 346 #define EVTCHN_FIFO_LINKED 29 347 #define EVTCHN_FIFO_BUSY 28 348 349 #define EVTCHN_FIFO_LINK_BITS 17 350 #define EVTCHN_FIFO_LINK_MASK ((1 << EVTCHN_FIFO_LINK_BITS) - 1) 351 352 #define EVTCHN_FIFO_NR_CHANNELS (1 << EVTCHN_FIFO_LINK_BITS) 353 354 struct evtchn_fifo_control_block { 355 uint32_t ready; 356 uint32_t _rsvd; 357 uint32_t head[EVTCHN_FIFO_MAX_QUEUES]; 358 }; 359 typedef struct evtchn_fifo_control_block evtchn_fifo_control_block_t; 360 361 #endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */ 362 363 /* 364 * Local variables: 365 * mode: C 366 * c-file-style: "BSD" 367 * c-basic-offset: 4 368 * tab-width: 4 369 * indent-tabs-mode: nil 370 * End: 371 */ 372