1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /****************************************************************************** 3*4882a593Smuzhiyun * event_channel.h 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Event channels between domains. 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Copyright (c) 2003-2004, K A Fraser. 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__ 11*4882a593Smuzhiyun #define __XEN_PUBLIC_EVENT_CHANNEL_H__ 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun #include <xen/interface/xen.h> 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun typedef uint32_t evtchn_port_t; 16*4882a593Smuzhiyun DEFINE_GUEST_HANDLE(evtchn_port_t); 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun /* 19*4882a593Smuzhiyun * EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as 20*4882a593Smuzhiyun * accepting interdomain bindings from domain <remote_dom>. A fresh port 21*4882a593Smuzhiyun * is allocated in <dom> and returned as <port>. 22*4882a593Smuzhiyun * NOTES: 23*4882a593Smuzhiyun * 1. If the caller is unprivileged then <dom> must be DOMID_SELF. 24*4882a593Smuzhiyun * 2. <rdom> may be DOMID_SELF, allowing loopback connections. 25*4882a593Smuzhiyun */ 26*4882a593Smuzhiyun #define EVTCHNOP_alloc_unbound 6 27*4882a593Smuzhiyun struct evtchn_alloc_unbound { 28*4882a593Smuzhiyun /* IN parameters */ 29*4882a593Smuzhiyun domid_t dom, remote_dom; 30*4882a593Smuzhiyun /* OUT parameters */ 31*4882a593Smuzhiyun evtchn_port_t port; 32*4882a593Smuzhiyun }; 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun /* 35*4882a593Smuzhiyun * EVTCHNOP_bind_interdomain: Construct an interdomain event channel between 36*4882a593Smuzhiyun * the calling domain and <remote_dom>. <remote_dom,remote_port> must identify 37*4882a593Smuzhiyun * a port that is unbound and marked as accepting bindings from the calling 38*4882a593Smuzhiyun * domain. A fresh port is allocated in the calling domain and returned as 39*4882a593Smuzhiyun * <local_port>. 40*4882a593Smuzhiyun * NOTES: 41*4882a593Smuzhiyun * 2. <remote_dom> may be DOMID_SELF, allowing loopback connections. 42*4882a593Smuzhiyun */ 43*4882a593Smuzhiyun #define EVTCHNOP_bind_interdomain 0 44*4882a593Smuzhiyun struct evtchn_bind_interdomain { 45*4882a593Smuzhiyun /* IN parameters. */ 46*4882a593Smuzhiyun domid_t remote_dom; 47*4882a593Smuzhiyun evtchn_port_t remote_port; 48*4882a593Smuzhiyun /* OUT parameters. */ 49*4882a593Smuzhiyun evtchn_port_t local_port; 50*4882a593Smuzhiyun }; 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /* 53*4882a593Smuzhiyun * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified 54*4882a593Smuzhiyun * vcpu. 55*4882a593Smuzhiyun * NOTES: 56*4882a593Smuzhiyun * 1. A virtual IRQ may be bound to at most one event channel per vcpu. 57*4882a593Smuzhiyun * 2. The allocated event channel is bound to the specified vcpu. The binding 58*4882a593Smuzhiyun * may not be changed. 59*4882a593Smuzhiyun */ 60*4882a593Smuzhiyun #define EVTCHNOP_bind_virq 1 61*4882a593Smuzhiyun struct evtchn_bind_virq { 62*4882a593Smuzhiyun /* IN parameters. */ 63*4882a593Smuzhiyun uint32_t virq; 64*4882a593Smuzhiyun uint32_t vcpu; 65*4882a593Smuzhiyun /* OUT parameters. */ 66*4882a593Smuzhiyun evtchn_port_t port; 67*4882a593Smuzhiyun }; 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun /* 70*4882a593Smuzhiyun * EVTCHNOP_bind_pirq: Bind a local event channel to PIRQ <irq>. 71*4882a593Smuzhiyun * NOTES: 72*4882a593Smuzhiyun * 1. A physical IRQ may be bound to at most one event channel per domain. 73*4882a593Smuzhiyun * 2. Only a sufficiently-privileged domain may bind to a physical IRQ. 74*4882a593Smuzhiyun */ 75*4882a593Smuzhiyun #define EVTCHNOP_bind_pirq 2 76*4882a593Smuzhiyun struct evtchn_bind_pirq { 77*4882a593Smuzhiyun /* IN parameters. */ 78*4882a593Smuzhiyun uint32_t pirq; 79*4882a593Smuzhiyun #define BIND_PIRQ__WILL_SHARE 1 80*4882a593Smuzhiyun uint32_t flags; /* BIND_PIRQ__* */ 81*4882a593Smuzhiyun /* OUT parameters. */ 82*4882a593Smuzhiyun evtchn_port_t port; 83*4882a593Smuzhiyun }; 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun /* 86*4882a593Smuzhiyun * EVTCHNOP_bind_ipi: Bind a local event channel to receive events. 87*4882a593Smuzhiyun * NOTES: 88*4882a593Smuzhiyun * 1. The allocated event channel is bound to the specified vcpu. The binding 89*4882a593Smuzhiyun * may not be changed. 90*4882a593Smuzhiyun */ 91*4882a593Smuzhiyun #define EVTCHNOP_bind_ipi 7 92*4882a593Smuzhiyun struct evtchn_bind_ipi { 93*4882a593Smuzhiyun uint32_t vcpu; 94*4882a593Smuzhiyun /* OUT parameters. */ 95*4882a593Smuzhiyun evtchn_port_t port; 96*4882a593Smuzhiyun }; 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun /* 99*4882a593Smuzhiyun * EVTCHNOP_close: Close a local event channel <port>. If the channel is 100*4882a593Smuzhiyun * interdomain then the remote end is placed in the unbound state 101*4882a593Smuzhiyun * (EVTCHNSTAT_unbound), awaiting a new connection. 102*4882a593Smuzhiyun */ 103*4882a593Smuzhiyun #define EVTCHNOP_close 3 104*4882a593Smuzhiyun struct evtchn_close { 105*4882a593Smuzhiyun /* IN parameters. */ 106*4882a593Smuzhiyun evtchn_port_t port; 107*4882a593Smuzhiyun }; 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun /* 110*4882a593Smuzhiyun * EVTCHNOP_send: Send an event to the remote end of the channel whose local 111*4882a593Smuzhiyun * endpoint is <port>. 112*4882a593Smuzhiyun */ 113*4882a593Smuzhiyun #define EVTCHNOP_send 4 114*4882a593Smuzhiyun struct evtchn_send { 115*4882a593Smuzhiyun /* IN parameters. */ 116*4882a593Smuzhiyun evtchn_port_t port; 117*4882a593Smuzhiyun }; 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* 120*4882a593Smuzhiyun * EVTCHNOP_status: Get the current status of the communication channel which 121*4882a593Smuzhiyun * has an endpoint at <dom, port>. 122*4882a593Smuzhiyun * NOTES: 123*4882a593Smuzhiyun * 1. <dom> may be specified as DOMID_SELF. 124*4882a593Smuzhiyun * 2. Only a sufficiently-privileged domain may obtain the status of an event 125*4882a593Smuzhiyun * channel for which <dom> is not DOMID_SELF. 126*4882a593Smuzhiyun */ 127*4882a593Smuzhiyun #define EVTCHNOP_status 5 128*4882a593Smuzhiyun struct evtchn_status { 129*4882a593Smuzhiyun /* IN parameters */ 130*4882a593Smuzhiyun domid_t dom; 131*4882a593Smuzhiyun evtchn_port_t port; 132*4882a593Smuzhiyun /* OUT parameters */ 133*4882a593Smuzhiyun #define EVTCHNSTAT_closed 0 /* Channel is not in use. */ 134*4882a593Smuzhiyun #define EVTCHNSTAT_unbound 1 /* Channel is waiting interdom connection.*/ 135*4882a593Smuzhiyun #define EVTCHNSTAT_interdomain 2 /* Channel is connected to remote domain. */ 136*4882a593Smuzhiyun #define EVTCHNSTAT_pirq 3 /* Channel is bound to a phys IRQ line. */ 137*4882a593Smuzhiyun #define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */ 138*4882a593Smuzhiyun #define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */ 139*4882a593Smuzhiyun uint32_t status; 140*4882a593Smuzhiyun uint32_t vcpu; /* VCPU to which this channel is bound. */ 141*4882a593Smuzhiyun union { 142*4882a593Smuzhiyun struct { 143*4882a593Smuzhiyun domid_t dom; 144*4882a593Smuzhiyun } unbound; /* EVTCHNSTAT_unbound */ 145*4882a593Smuzhiyun struct { 146*4882a593Smuzhiyun domid_t dom; 147*4882a593Smuzhiyun evtchn_port_t port; 148*4882a593Smuzhiyun } interdomain; /* EVTCHNSTAT_interdomain */ 149*4882a593Smuzhiyun uint32_t pirq; /* EVTCHNSTAT_pirq */ 150*4882a593Smuzhiyun uint32_t virq; /* EVTCHNSTAT_virq */ 151*4882a593Smuzhiyun } u; 152*4882a593Smuzhiyun }; 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun /* 155*4882a593Smuzhiyun * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an 156*4882a593Smuzhiyun * event is pending. 157*4882a593Smuzhiyun * NOTES: 158*4882a593Smuzhiyun * 1. IPI- and VIRQ-bound channels always notify the vcpu that initialised 159*4882a593Smuzhiyun * the binding. This binding cannot be changed. 160*4882a593Smuzhiyun * 2. All other channels notify vcpu0 by default. This default is set when 161*4882a593Smuzhiyun * the channel is allocated (a port that is freed and subsequently reused 162*4882a593Smuzhiyun * has its binding reset to vcpu0). 163*4882a593Smuzhiyun */ 164*4882a593Smuzhiyun #define EVTCHNOP_bind_vcpu 8 165*4882a593Smuzhiyun struct evtchn_bind_vcpu { 166*4882a593Smuzhiyun /* IN parameters. */ 167*4882a593Smuzhiyun evtchn_port_t port; 168*4882a593Smuzhiyun uint32_t vcpu; 169*4882a593Smuzhiyun }; 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun /* 172*4882a593Smuzhiyun * EVTCHNOP_unmask: Unmask the specified local event-channel port and deliver 173*4882a593Smuzhiyun * a notification to the appropriate VCPU if an event is pending. 174*4882a593Smuzhiyun */ 175*4882a593Smuzhiyun #define EVTCHNOP_unmask 9 176*4882a593Smuzhiyun struct evtchn_unmask { 177*4882a593Smuzhiyun /* IN parameters. */ 178*4882a593Smuzhiyun evtchn_port_t port; 179*4882a593Smuzhiyun }; 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun /* 182*4882a593Smuzhiyun * EVTCHNOP_reset: Close all event channels associated with specified domain. 183*4882a593Smuzhiyun * NOTES: 184*4882a593Smuzhiyun * 1. <dom> may be specified as DOMID_SELF. 185*4882a593Smuzhiyun * 2. Only a sufficiently-privileged domain may specify other than DOMID_SELF. 186*4882a593Smuzhiyun */ 187*4882a593Smuzhiyun #define EVTCHNOP_reset 10 188*4882a593Smuzhiyun struct evtchn_reset { 189*4882a593Smuzhiyun /* IN parameters. */ 190*4882a593Smuzhiyun domid_t dom; 191*4882a593Smuzhiyun }; 192*4882a593Smuzhiyun typedef struct evtchn_reset evtchn_reset_t; 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun /* 195*4882a593Smuzhiyun * EVTCHNOP_init_control: initialize the control block for the FIFO ABI. 196*4882a593Smuzhiyun */ 197*4882a593Smuzhiyun #define EVTCHNOP_init_control 11 198*4882a593Smuzhiyun struct evtchn_init_control { 199*4882a593Smuzhiyun /* IN parameters. */ 200*4882a593Smuzhiyun uint64_t control_gfn; 201*4882a593Smuzhiyun uint32_t offset; 202*4882a593Smuzhiyun uint32_t vcpu; 203*4882a593Smuzhiyun /* OUT parameters. */ 204*4882a593Smuzhiyun uint8_t link_bits; 205*4882a593Smuzhiyun uint8_t _pad[7]; 206*4882a593Smuzhiyun }; 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun /* 209*4882a593Smuzhiyun * EVTCHNOP_expand_array: add an additional page to the event array. 210*4882a593Smuzhiyun */ 211*4882a593Smuzhiyun #define EVTCHNOP_expand_array 12 212*4882a593Smuzhiyun struct evtchn_expand_array { 213*4882a593Smuzhiyun /* IN parameters. */ 214*4882a593Smuzhiyun uint64_t array_gfn; 215*4882a593Smuzhiyun }; 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun /* 218*4882a593Smuzhiyun * EVTCHNOP_set_priority: set the priority for an event channel. 219*4882a593Smuzhiyun */ 220*4882a593Smuzhiyun #define EVTCHNOP_set_priority 13 221*4882a593Smuzhiyun struct evtchn_set_priority { 222*4882a593Smuzhiyun /* IN parameters. */ 223*4882a593Smuzhiyun evtchn_port_t port; 224*4882a593Smuzhiyun uint32_t priority; 225*4882a593Smuzhiyun }; 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun struct evtchn_op { 228*4882a593Smuzhiyun uint32_t cmd; /* EVTCHNOP_* */ 229*4882a593Smuzhiyun union { 230*4882a593Smuzhiyun struct evtchn_alloc_unbound alloc_unbound; 231*4882a593Smuzhiyun struct evtchn_bind_interdomain bind_interdomain; 232*4882a593Smuzhiyun struct evtchn_bind_virq bind_virq; 233*4882a593Smuzhiyun struct evtchn_bind_pirq bind_pirq; 234*4882a593Smuzhiyun struct evtchn_bind_ipi bind_ipi; 235*4882a593Smuzhiyun struct evtchn_close close; 236*4882a593Smuzhiyun struct evtchn_send send; 237*4882a593Smuzhiyun struct evtchn_status status; 238*4882a593Smuzhiyun struct evtchn_bind_vcpu bind_vcpu; 239*4882a593Smuzhiyun struct evtchn_unmask unmask; 240*4882a593Smuzhiyun } u; 241*4882a593Smuzhiyun }; 242*4882a593Smuzhiyun DEFINE_GUEST_HANDLE_STRUCT(evtchn_op); 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun /* 245*4882a593Smuzhiyun * 2-level ABI 246*4882a593Smuzhiyun */ 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun #define EVTCHN_2L_NR_CHANNELS (sizeof(xen_ulong_t) * sizeof(xen_ulong_t) * 64) 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun /* 251*4882a593Smuzhiyun * FIFO ABI 252*4882a593Smuzhiyun */ 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun /* Events may have priorities from 0 (highest) to 15 (lowest). */ 255*4882a593Smuzhiyun #define EVTCHN_FIFO_PRIORITY_MAX 0 256*4882a593Smuzhiyun #define EVTCHN_FIFO_PRIORITY_DEFAULT 7 257*4882a593Smuzhiyun #define EVTCHN_FIFO_PRIORITY_MIN 15 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun #define EVTCHN_FIFO_MAX_QUEUES (EVTCHN_FIFO_PRIORITY_MIN + 1) 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun typedef uint32_t event_word_t; 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun #define EVTCHN_FIFO_PENDING 31 264*4882a593Smuzhiyun #define EVTCHN_FIFO_MASKED 30 265*4882a593Smuzhiyun #define EVTCHN_FIFO_LINKED 29 266*4882a593Smuzhiyun #define EVTCHN_FIFO_BUSY 28 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun #define EVTCHN_FIFO_LINK_BITS 17 269*4882a593Smuzhiyun #define EVTCHN_FIFO_LINK_MASK ((1 << EVTCHN_FIFO_LINK_BITS) - 1) 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun #define EVTCHN_FIFO_NR_CHANNELS (1 << EVTCHN_FIFO_LINK_BITS) 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun struct evtchn_fifo_control_block { 274*4882a593Smuzhiyun uint32_t ready; 275*4882a593Smuzhiyun uint32_t _rsvd; 276*4882a593Smuzhiyun event_word_t head[EVTCHN_FIFO_MAX_QUEUES]; 277*4882a593Smuzhiyun }; 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun #endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */ 280