xref: /openbmc/qemu/include/hw/xen/interface/event_channel.h (revision 3e34860a3a03f969ad0720ec9c12ea10e88738a6)
1*8ac98aedSDavid Woodhouse /* SPDX-License-Identifier: MIT */
250c88402SJoao Martins /******************************************************************************
350c88402SJoao Martins  * event_channel.h
450c88402SJoao Martins  *
550c88402SJoao Martins  * Event channels between domains.
650c88402SJoao Martins  *
750c88402SJoao Martins  * Copyright (c) 2003-2004, K A Fraser.
850c88402SJoao Martins  */
950c88402SJoao Martins 
1050c88402SJoao Martins #ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
1150c88402SJoao Martins #define __XEN_PUBLIC_EVENT_CHANNEL_H__
1250c88402SJoao Martins 
1350c88402SJoao Martins #include "xen.h"
1450c88402SJoao Martins 
1550c88402SJoao Martins /*
1650c88402SJoao Martins  * `incontents 150 evtchn Event Channels
1750c88402SJoao Martins  *
1850c88402SJoao Martins  * Event channels are the basic primitive provided by Xen for event
1950c88402SJoao Martins  * notifications. An event is the Xen equivalent of a hardware
2050c88402SJoao Martins  * interrupt. They essentially store one bit of information, the event
2150c88402SJoao Martins  * of interest is signalled by transitioning this bit from 0 to 1.
2250c88402SJoao Martins  *
2350c88402SJoao Martins  * Notifications are received by a guest via an upcall from Xen,
2450c88402SJoao Martins  * indicating when an event arrives (setting the bit). Further
2550c88402SJoao Martins  * notifications are masked until the bit is cleared again (therefore,
2650c88402SJoao Martins  * guests must check the value of the bit after re-enabling event
2750c88402SJoao Martins  * delivery to ensure no missed notifications).
2850c88402SJoao Martins  *
2950c88402SJoao Martins  * Event notifications can be masked by setting a flag; this is
3050c88402SJoao Martins  * equivalent to disabling interrupts and can be used to ensure
3150c88402SJoao Martins  * atomicity of certain operations in the guest kernel.
3250c88402SJoao Martins  *
3350c88402SJoao Martins  * Event channels are represented by the evtchn_* fields in
3450c88402SJoao Martins  * struct shared_info and struct vcpu_info.
3550c88402SJoao Martins  */
3650c88402SJoao Martins 
3750c88402SJoao Martins /*
3850c88402SJoao Martins  * ` enum neg_errnoval
3950c88402SJoao Martins  * ` HYPERVISOR_event_channel_op(enum event_channel_op cmd, void *args)
4050c88402SJoao Martins  * `
4150c88402SJoao Martins  * @cmd  == EVTCHNOP_* (event-channel operation).
4250c88402SJoao Martins  * @args == struct evtchn_* Operation-specific extra arguments (NULL if none).
4350c88402SJoao Martins  */
4450c88402SJoao Martins 
4550c88402SJoao Martins /* ` enum event_channel_op { // EVTCHNOP_* => struct evtchn_* */
4650c88402SJoao Martins #define EVTCHNOP_bind_interdomain 0
4750c88402SJoao Martins #define EVTCHNOP_bind_virq        1
4850c88402SJoao Martins #define EVTCHNOP_bind_pirq        2
4950c88402SJoao Martins #define EVTCHNOP_close            3
5050c88402SJoao Martins #define EVTCHNOP_send             4
5150c88402SJoao Martins #define EVTCHNOP_status           5
5250c88402SJoao Martins #define EVTCHNOP_alloc_unbound    6
5350c88402SJoao Martins #define EVTCHNOP_bind_ipi         7
5450c88402SJoao Martins #define EVTCHNOP_bind_vcpu        8
5550c88402SJoao Martins #define EVTCHNOP_unmask           9
5650c88402SJoao Martins #define EVTCHNOP_reset           10
5750c88402SJoao Martins #define EVTCHNOP_init_control    11
5850c88402SJoao Martins #define EVTCHNOP_expand_array    12
5950c88402SJoao Martins #define EVTCHNOP_set_priority    13
6050c88402SJoao Martins #ifdef __XEN__
6150c88402SJoao Martins #define EVTCHNOP_reset_cont      14
6250c88402SJoao Martins #endif
6350c88402SJoao Martins /* ` } */
6450c88402SJoao Martins 
6550c88402SJoao Martins typedef uint32_t evtchn_port_t;
6650c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
6750c88402SJoao Martins 
6850c88402SJoao Martins /*
6950c88402SJoao Martins  * EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
7050c88402SJoao Martins  * accepting interdomain bindings from domain <remote_dom>. A fresh port
7150c88402SJoao Martins  * is allocated in <dom> and returned as <port>.
7250c88402SJoao Martins  * NOTES:
7350c88402SJoao Martins  *  1. If the caller is unprivileged then <dom> must be DOMID_SELF.
7450c88402SJoao Martins  *  2. <remote_dom> may be DOMID_SELF, allowing loopback connections.
7550c88402SJoao Martins  */
7650c88402SJoao Martins struct evtchn_alloc_unbound {
7750c88402SJoao Martins     /* IN parameters */
7850c88402SJoao Martins     domid_t dom, remote_dom;
7950c88402SJoao Martins     /* OUT parameters */
8050c88402SJoao Martins     evtchn_port_t port;
8150c88402SJoao Martins };
8250c88402SJoao Martins typedef struct evtchn_alloc_unbound evtchn_alloc_unbound_t;
8350c88402SJoao Martins 
8450c88402SJoao Martins /*
8550c88402SJoao Martins  * EVTCHNOP_bind_interdomain: Construct an interdomain event channel between
8650c88402SJoao Martins  * the calling domain and <remote_dom>. <remote_dom,remote_port> must identify
8750c88402SJoao Martins  * a port that is unbound and marked as accepting bindings from the calling
8850c88402SJoao Martins  * domain. A fresh port is allocated in the calling domain and returned as
8950c88402SJoao Martins  * <local_port>.
9050c88402SJoao Martins  *
9150c88402SJoao Martins  * In case the peer domain has already tried to set our event channel
9250c88402SJoao Martins  * pending, before it was bound, EVTCHNOP_bind_interdomain always sets
9350c88402SJoao Martins  * the local event channel pending.
9450c88402SJoao Martins  *
9550c88402SJoao Martins  * The usual pattern of use, in the guest's upcall (or subsequent
9650c88402SJoao Martins  * handler) is as follows: (Re-enable the event channel for subsequent
9750c88402SJoao Martins  * signalling and then) check for the existence of whatever condition
9850c88402SJoao Martins  * is being waited for by other means, and take whatever action is
9950c88402SJoao Martins  * needed (if any).
10050c88402SJoao Martins  *
10150c88402SJoao Martins  * NOTES:
10250c88402SJoao Martins  *  1. <remote_dom> may be DOMID_SELF, allowing loopback connections.
10350c88402SJoao Martins  */
10450c88402SJoao Martins struct evtchn_bind_interdomain {
10550c88402SJoao Martins     /* IN parameters. */
10650c88402SJoao Martins     domid_t remote_dom;
10750c88402SJoao Martins     evtchn_port_t remote_port;
10850c88402SJoao Martins     /* OUT parameters. */
10950c88402SJoao Martins     evtchn_port_t local_port;
11050c88402SJoao Martins };
11150c88402SJoao Martins typedef struct evtchn_bind_interdomain evtchn_bind_interdomain_t;
11250c88402SJoao Martins 
11350c88402SJoao Martins /*
11450c88402SJoao Martins  * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified
11550c88402SJoao Martins  * vcpu.
11650c88402SJoao Martins  * NOTES:
11750c88402SJoao Martins  *  1. Virtual IRQs are classified as per-vcpu or global. See the VIRQ list
11850c88402SJoao Martins  *     in xen.h for the classification of each VIRQ.
11950c88402SJoao Martins  *  2. Global VIRQs must be allocated on VCPU0 but can subsequently be
12050c88402SJoao Martins  *     re-bound via EVTCHNOP_bind_vcpu.
12150c88402SJoao Martins  *  3. Per-vcpu VIRQs may be bound to at most one event channel per vcpu.
12250c88402SJoao Martins  *     The allocated event channel is bound to the specified vcpu and the
12350c88402SJoao Martins  *     binding cannot be changed.
12450c88402SJoao Martins  */
12550c88402SJoao Martins struct evtchn_bind_virq {
12650c88402SJoao Martins     /* IN parameters. */
12750c88402SJoao Martins     uint32_t virq; /* enum virq */
12850c88402SJoao Martins     uint32_t vcpu;
12950c88402SJoao Martins     /* OUT parameters. */
13050c88402SJoao Martins     evtchn_port_t port;
13150c88402SJoao Martins };
13250c88402SJoao Martins typedef struct evtchn_bind_virq evtchn_bind_virq_t;
13350c88402SJoao Martins 
13450c88402SJoao Martins /*
13550c88402SJoao Martins  * EVTCHNOP_bind_pirq: Bind a local event channel to a real IRQ (PIRQ <irq>).
13650c88402SJoao Martins  * NOTES:
13750c88402SJoao Martins  *  1. A physical IRQ may be bound to at most one event channel per domain.
13850c88402SJoao Martins  *  2. Only a sufficiently-privileged domain may bind to a physical IRQ.
13950c88402SJoao Martins  */
14050c88402SJoao Martins struct evtchn_bind_pirq {
14150c88402SJoao Martins     /* IN parameters. */
14250c88402SJoao Martins     uint32_t pirq;
14350c88402SJoao Martins #define BIND_PIRQ__WILL_SHARE 1
14450c88402SJoao Martins     uint32_t flags; /* BIND_PIRQ__* */
14550c88402SJoao Martins     /* OUT parameters. */
14650c88402SJoao Martins     evtchn_port_t port;
14750c88402SJoao Martins };
14850c88402SJoao Martins typedef struct evtchn_bind_pirq evtchn_bind_pirq_t;
14950c88402SJoao Martins 
15050c88402SJoao Martins /*
15150c88402SJoao Martins  * EVTCHNOP_bind_ipi: Bind a local event channel to receive events.
15250c88402SJoao Martins  * NOTES:
15350c88402SJoao Martins  *  1. The allocated event channel is bound to the specified vcpu. The binding
15450c88402SJoao Martins  *     may not be changed.
15550c88402SJoao Martins  */
15650c88402SJoao Martins struct evtchn_bind_ipi {
15750c88402SJoao Martins     uint32_t vcpu;
15850c88402SJoao Martins     /* OUT parameters. */
15950c88402SJoao Martins     evtchn_port_t port;
16050c88402SJoao Martins };
16150c88402SJoao Martins typedef struct evtchn_bind_ipi evtchn_bind_ipi_t;
16250c88402SJoao Martins 
16350c88402SJoao Martins /*
16450c88402SJoao Martins  * EVTCHNOP_close: Close a local event channel <port>. If the channel is
16550c88402SJoao Martins  * interdomain then the remote end is placed in the unbound state
16650c88402SJoao Martins  * (EVTCHNSTAT_unbound), awaiting a new connection.
16750c88402SJoao Martins  */
16850c88402SJoao Martins struct evtchn_close {
16950c88402SJoao Martins     /* IN parameters. */
17050c88402SJoao Martins     evtchn_port_t port;
17150c88402SJoao Martins };
17250c88402SJoao Martins typedef struct evtchn_close evtchn_close_t;
17350c88402SJoao Martins 
17450c88402SJoao Martins /*
17550c88402SJoao Martins  * EVTCHNOP_send: Send an event to the remote end of the channel whose local
17650c88402SJoao Martins  * endpoint is <port>.
17750c88402SJoao Martins  */
17850c88402SJoao Martins struct evtchn_send {
17950c88402SJoao Martins     /* IN parameters. */
18050c88402SJoao Martins     evtchn_port_t port;
18150c88402SJoao Martins };
18250c88402SJoao Martins typedef struct evtchn_send evtchn_send_t;
18350c88402SJoao Martins 
18450c88402SJoao Martins /*
18550c88402SJoao Martins  * EVTCHNOP_status: Get the current status of the communication channel which
18650c88402SJoao Martins  * has an endpoint at <dom, port>.
18750c88402SJoao Martins  * NOTES:
18850c88402SJoao Martins  *  1. <dom> may be specified as DOMID_SELF.
18950c88402SJoao Martins  *  2. Only a sufficiently-privileged domain may obtain the status of an event
19050c88402SJoao Martins  *     channel for which <dom> is not DOMID_SELF.
19150c88402SJoao Martins  */
19250c88402SJoao Martins struct evtchn_status {
19350c88402SJoao Martins     /* IN parameters */
19450c88402SJoao Martins     domid_t  dom;
19550c88402SJoao Martins     evtchn_port_t port;
19650c88402SJoao Martins     /* OUT parameters */
19750c88402SJoao Martins #define EVTCHNSTAT_closed       0  /* Channel is not in use.                 */
19850c88402SJoao Martins #define EVTCHNSTAT_unbound      1  /* Channel is waiting interdom connection.*/
19950c88402SJoao Martins #define EVTCHNSTAT_interdomain  2  /* Channel is connected to remote domain. */
20050c88402SJoao Martins #define EVTCHNSTAT_pirq         3  /* Channel is bound to a phys IRQ line.   */
20150c88402SJoao Martins #define EVTCHNSTAT_virq         4  /* Channel is bound to a virtual IRQ line */
20250c88402SJoao Martins #define EVTCHNSTAT_ipi          5  /* Channel is bound to a virtual IPI line */
20350c88402SJoao Martins     uint32_t status;
20450c88402SJoao Martins     uint32_t vcpu;                 /* VCPU to which this channel is bound.   */
20550c88402SJoao Martins     union {
20650c88402SJoao Martins         struct {
20750c88402SJoao Martins             domid_t dom;
20850c88402SJoao Martins         } unbound;                 /* EVTCHNSTAT_unbound */
20950c88402SJoao Martins         struct {
21050c88402SJoao Martins             domid_t dom;
21150c88402SJoao Martins             evtchn_port_t port;
21250c88402SJoao Martins         } interdomain;             /* EVTCHNSTAT_interdomain */
21350c88402SJoao Martins         uint32_t pirq;             /* EVTCHNSTAT_pirq        */
21450c88402SJoao Martins         uint32_t virq;             /* EVTCHNSTAT_virq        */
21550c88402SJoao Martins     } u;
21650c88402SJoao Martins };
21750c88402SJoao Martins typedef struct evtchn_status evtchn_status_t;
21850c88402SJoao Martins 
21950c88402SJoao Martins /*
22050c88402SJoao Martins  * EVTCHNOP_bind_vcpu: Specify which vcpu a channel should notify when an
22150c88402SJoao Martins  * event is pending.
22250c88402SJoao Martins  * NOTES:
22350c88402SJoao Martins  *  1. IPI-bound channels always notify the vcpu specified at bind time.
22450c88402SJoao Martins  *     This binding cannot be changed.
22550c88402SJoao Martins  *  2. Per-VCPU VIRQ channels always notify the vcpu specified at bind time.
22650c88402SJoao Martins  *     This binding cannot be changed.
22750c88402SJoao Martins  *  3. All other channels notify vcpu0 by default. This default is set when
22850c88402SJoao Martins  *     the channel is allocated (a port that is freed and subsequently reused
22950c88402SJoao Martins  *     has its binding reset to vcpu0).
23050c88402SJoao Martins  */
23150c88402SJoao Martins struct evtchn_bind_vcpu {
23250c88402SJoao Martins     /* IN parameters. */
23350c88402SJoao Martins     evtchn_port_t port;
23450c88402SJoao Martins     uint32_t vcpu;
23550c88402SJoao Martins };
23650c88402SJoao Martins typedef struct evtchn_bind_vcpu evtchn_bind_vcpu_t;
23750c88402SJoao Martins 
23850c88402SJoao Martins /*
23950c88402SJoao Martins  * EVTCHNOP_unmask: Unmask the specified local event-channel port and deliver
24050c88402SJoao Martins  * a notification to the appropriate VCPU if an event is pending.
24150c88402SJoao Martins  */
24250c88402SJoao Martins struct evtchn_unmask {
24350c88402SJoao Martins     /* IN parameters. */
24450c88402SJoao Martins     evtchn_port_t port;
24550c88402SJoao Martins };
24650c88402SJoao Martins typedef struct evtchn_unmask evtchn_unmask_t;
24750c88402SJoao Martins 
24850c88402SJoao Martins /*
24950c88402SJoao Martins  * EVTCHNOP_reset: Close all event channels associated with specified domain.
25050c88402SJoao Martins  * NOTES:
25150c88402SJoao Martins  *  1. <dom> may be specified as DOMID_SELF.
25250c88402SJoao Martins  *  2. Only a sufficiently-privileged domain may specify other than DOMID_SELF.
25350c88402SJoao Martins  *  3. Destroys all control blocks and event array, resets event channel
25450c88402SJoao Martins  *     operations to 2-level ABI if called with <dom> == DOMID_SELF and FIFO
25550c88402SJoao Martins  *     ABI was used. Guests should not bind events during EVTCHNOP_reset call
25650c88402SJoao Martins  *     as these events are likely to be lost.
25750c88402SJoao Martins  */
25850c88402SJoao Martins struct evtchn_reset {
25950c88402SJoao Martins     /* IN parameters. */
26050c88402SJoao Martins     domid_t dom;
26150c88402SJoao Martins };
26250c88402SJoao Martins typedef struct evtchn_reset evtchn_reset_t;
26350c88402SJoao Martins 
26450c88402SJoao Martins /*
26550c88402SJoao Martins  * EVTCHNOP_init_control: initialize the control block for the FIFO ABI.
26650c88402SJoao Martins  *
26750c88402SJoao Martins  * Note: any events that are currently pending will not be resent and
26850c88402SJoao Martins  * will be lost.  Guests should call this before binding any event to
26950c88402SJoao Martins  * avoid losing any events.
27050c88402SJoao Martins  */
27150c88402SJoao Martins struct evtchn_init_control {
27250c88402SJoao Martins     /* IN parameters. */
27350c88402SJoao Martins     uint64_t control_gfn;
27450c88402SJoao Martins     uint32_t offset;
27550c88402SJoao Martins     uint32_t vcpu;
27650c88402SJoao Martins     /* OUT parameters. */
27750c88402SJoao Martins     uint8_t link_bits;
27850c88402SJoao Martins     uint8_t _pad[7];
27950c88402SJoao Martins };
28050c88402SJoao Martins typedef struct evtchn_init_control evtchn_init_control_t;
28150c88402SJoao Martins 
28250c88402SJoao Martins /*
28350c88402SJoao Martins  * EVTCHNOP_expand_array: add an additional page to the event array.
28450c88402SJoao Martins  */
28550c88402SJoao Martins struct evtchn_expand_array {
28650c88402SJoao Martins     /* IN parameters. */
28750c88402SJoao Martins     uint64_t array_gfn;
28850c88402SJoao Martins };
28950c88402SJoao Martins typedef struct evtchn_expand_array evtchn_expand_array_t;
29050c88402SJoao Martins 
29150c88402SJoao Martins /*
29250c88402SJoao Martins  * EVTCHNOP_set_priority: set the priority for an event channel.
29350c88402SJoao Martins  */
29450c88402SJoao Martins struct evtchn_set_priority {
29550c88402SJoao Martins     /* IN parameters. */
29650c88402SJoao Martins     evtchn_port_t port;
29750c88402SJoao Martins     uint32_t priority;
29850c88402SJoao Martins };
29950c88402SJoao Martins typedef struct evtchn_set_priority evtchn_set_priority_t;
30050c88402SJoao Martins 
30150c88402SJoao Martins /*
30250c88402SJoao Martins  * ` enum neg_errnoval
30350c88402SJoao Martins  * ` HYPERVISOR_event_channel_op_compat(struct evtchn_op *op)
30450c88402SJoao Martins  * `
30550c88402SJoao Martins  * Superceded by new event_channel_op() hypercall since 0x00030202.
30650c88402SJoao Martins  */
30750c88402SJoao Martins struct evtchn_op {
30850c88402SJoao Martins     uint32_t cmd; /* enum event_channel_op */
30950c88402SJoao Martins     union {
31050c88402SJoao Martins         evtchn_alloc_unbound_t    alloc_unbound;
31150c88402SJoao Martins         evtchn_bind_interdomain_t bind_interdomain;
31250c88402SJoao Martins         evtchn_bind_virq_t        bind_virq;
31350c88402SJoao Martins         evtchn_bind_pirq_t        bind_pirq;
31450c88402SJoao Martins         evtchn_bind_ipi_t         bind_ipi;
31550c88402SJoao Martins         evtchn_close_t            close;
31650c88402SJoao Martins         evtchn_send_t             send;
31750c88402SJoao Martins         evtchn_status_t           status;
31850c88402SJoao Martins         evtchn_bind_vcpu_t        bind_vcpu;
31950c88402SJoao Martins         evtchn_unmask_t           unmask;
32050c88402SJoao Martins     } u;
32150c88402SJoao Martins };
32250c88402SJoao Martins typedef struct evtchn_op evtchn_op_t;
32350c88402SJoao Martins DEFINE_XEN_GUEST_HANDLE(evtchn_op_t);
32450c88402SJoao Martins 
32550c88402SJoao Martins /*
32650c88402SJoao Martins  * 2-level ABI
32750c88402SJoao Martins  */
32850c88402SJoao Martins 
32950c88402SJoao Martins #define EVTCHN_2L_NR_CHANNELS (sizeof(xen_ulong_t) * sizeof(xen_ulong_t) * 64)
33050c88402SJoao Martins 
33150c88402SJoao Martins /*
33250c88402SJoao Martins  * FIFO ABI
33350c88402SJoao Martins  */
33450c88402SJoao Martins 
33550c88402SJoao Martins /* Events may have priorities from 0 (highest) to 15 (lowest). */
33650c88402SJoao Martins #define EVTCHN_FIFO_PRIORITY_MAX     0
33750c88402SJoao Martins #define EVTCHN_FIFO_PRIORITY_DEFAULT 7
33850c88402SJoao Martins #define EVTCHN_FIFO_PRIORITY_MIN     15
33950c88402SJoao Martins 
34050c88402SJoao Martins #define EVTCHN_FIFO_MAX_QUEUES (EVTCHN_FIFO_PRIORITY_MIN + 1)
34150c88402SJoao Martins 
34250c88402SJoao Martins typedef uint32_t event_word_t;
34350c88402SJoao Martins 
34450c88402SJoao Martins #define EVTCHN_FIFO_PENDING 31
34550c88402SJoao Martins #define EVTCHN_FIFO_MASKED  30
34650c88402SJoao Martins #define EVTCHN_FIFO_LINKED  29
34750c88402SJoao Martins #define EVTCHN_FIFO_BUSY    28
34850c88402SJoao Martins 
34950c88402SJoao Martins #define EVTCHN_FIFO_LINK_BITS 17
35050c88402SJoao Martins #define EVTCHN_FIFO_LINK_MASK ((1 << EVTCHN_FIFO_LINK_BITS) - 1)
35150c88402SJoao Martins 
35250c88402SJoao Martins #define EVTCHN_FIFO_NR_CHANNELS (1 << EVTCHN_FIFO_LINK_BITS)
35350c88402SJoao Martins 
35450c88402SJoao Martins struct evtchn_fifo_control_block {
35550c88402SJoao Martins     uint32_t ready;
35650c88402SJoao Martins     uint32_t _rsvd;
35750c88402SJoao Martins     uint32_t head[EVTCHN_FIFO_MAX_QUEUES];
35850c88402SJoao Martins };
35950c88402SJoao Martins typedef struct evtchn_fifo_control_block evtchn_fifo_control_block_t;
36050c88402SJoao Martins 
36150c88402SJoao Martins #endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */
36250c88402SJoao Martins 
36350c88402SJoao Martins /*
36450c88402SJoao Martins  * Local variables:
36550c88402SJoao Martins  * mode: C
36650c88402SJoao Martins  * c-file-style: "BSD"
36750c88402SJoao Martins  * c-basic-offset: 4
36850c88402SJoao Martins  * tab-width: 4
36950c88402SJoao Martins  * indent-tabs-mode: nil
37050c88402SJoao Martins  * End:
37150c88402SJoao Martins  */
372