xref: /qemu/contrib/ivshmem-client/ivshmem-client.h (revision 5105b1d8c2d1ad4a25b8806e86c0f012936b2eed)
1a75eb03bSDavid Marchand /*
2a75eb03bSDavid Marchand  * Copyright 6WIND S.A., 2014
3a75eb03bSDavid Marchand  *
4a75eb03bSDavid Marchand  * This work is licensed under the terms of the GNU GPL, version 2 or
5a75eb03bSDavid Marchand  * (at your option) any later version.  See the COPYING file in the
6a75eb03bSDavid Marchand  * top-level directory.
7a75eb03bSDavid Marchand  */
8a75eb03bSDavid Marchand 
9a75eb03bSDavid Marchand #ifndef _IVSHMEM_CLIENT_H_
10a75eb03bSDavid Marchand #define _IVSHMEM_CLIENT_H_
11a75eb03bSDavid Marchand 
12a75eb03bSDavid Marchand /**
13a75eb03bSDavid Marchand  * This file provides helper to implement an ivshmem client. It is used
14a75eb03bSDavid Marchand  * on the host to ask QEMU to send an interrupt to an ivshmem PCI device in a
15a75eb03bSDavid Marchand  * guest. QEMU also implements an ivshmem client similar to this one, they both
16a75eb03bSDavid Marchand  * connect to an ivshmem server.
17a75eb03bSDavid Marchand  *
18a75eb03bSDavid Marchand  * A standalone ivshmem client based on this file is provided for debug/test
19a75eb03bSDavid Marchand  * purposes.
20a75eb03bSDavid Marchand  */
21a75eb03bSDavid Marchand 
22a75eb03bSDavid Marchand #include <limits.h>
23a75eb03bSDavid Marchand #include <sys/select.h>
24a75eb03bSDavid Marchand 
25a75eb03bSDavid Marchand #include "qemu/queue.h"
26*5105b1d8SDavid Marchand #include "hw/misc/ivshmem.h"
27a75eb03bSDavid Marchand 
28a75eb03bSDavid Marchand /**
29a75eb03bSDavid Marchand  * Maximum number of notification vectors supported by the client
30a75eb03bSDavid Marchand  */
31a75eb03bSDavid Marchand #define IVSHMEM_CLIENT_MAX_VECTORS 64
32a75eb03bSDavid Marchand 
33a75eb03bSDavid Marchand /**
34a75eb03bSDavid Marchand  * Structure storing a peer
35a75eb03bSDavid Marchand  *
36a75eb03bSDavid Marchand  * Each time a client connects to an ivshmem server, it is advertised to
37a75eb03bSDavid Marchand  * all connected clients through the unix socket. When our ivshmem
38a75eb03bSDavid Marchand  * client receives a notification, it creates a IvshmemClientPeer
39a75eb03bSDavid Marchand  * structure to store the infos of this peer.
40a75eb03bSDavid Marchand  *
41a75eb03bSDavid Marchand  * This structure is also used to store the information of our own
42a75eb03bSDavid Marchand  * client in (IvshmemClient)->local.
43a75eb03bSDavid Marchand  */
44a75eb03bSDavid Marchand typedef struct IvshmemClientPeer {
45a75eb03bSDavid Marchand     QTAILQ_ENTRY(IvshmemClientPeer) next;    /**< next in list*/
46a75eb03bSDavid Marchand     long id;                                 /**< the id of the peer */
47a75eb03bSDavid Marchand     int vectors[IVSHMEM_CLIENT_MAX_VECTORS]; /**< one fd per vector */
48a75eb03bSDavid Marchand     unsigned vectors_count;                  /**< number of vectors */
49a75eb03bSDavid Marchand } IvshmemClientPeer;
50a75eb03bSDavid Marchand QTAILQ_HEAD(IvshmemClientPeerList, IvshmemClientPeer);
51a75eb03bSDavid Marchand 
52a75eb03bSDavid Marchand typedef struct IvshmemClientPeerList IvshmemClientPeerList;
53a75eb03bSDavid Marchand typedef struct IvshmemClient IvshmemClient;
54a75eb03bSDavid Marchand 
55a75eb03bSDavid Marchand /**
56a75eb03bSDavid Marchand  * Typedef of callback function used when our IvshmemClient receives a
57a75eb03bSDavid Marchand  * notification from a peer.
58a75eb03bSDavid Marchand  */
59a75eb03bSDavid Marchand typedef void (*IvshmemClientNotifCb)(
60a75eb03bSDavid Marchand     const IvshmemClient *client,
61a75eb03bSDavid Marchand     const IvshmemClientPeer *peer,
62a75eb03bSDavid Marchand     unsigned vect, void *arg);
63a75eb03bSDavid Marchand 
64a75eb03bSDavid Marchand /**
65a75eb03bSDavid Marchand  * Structure describing an ivshmem client
66a75eb03bSDavid Marchand  *
67a75eb03bSDavid Marchand  * This structure stores all information related to our client: the name
68a75eb03bSDavid Marchand  * of the server unix socket, the list of peers advertised by the
69a75eb03bSDavid Marchand  * server, our own client information, and a pointer the notification
70a75eb03bSDavid Marchand  * callback function used when we receive a notification from a peer.
71a75eb03bSDavid Marchand  */
72a75eb03bSDavid Marchand struct IvshmemClient {
73a75eb03bSDavid Marchand     char unix_sock_path[PATH_MAX];      /**< path to unix sock */
74a75eb03bSDavid Marchand     int sock_fd;                        /**< unix sock filedesc */
75a75eb03bSDavid Marchand     int shm_fd;                         /**< shm file descriptor */
76a75eb03bSDavid Marchand 
77a75eb03bSDavid Marchand     IvshmemClientPeerList peer_list;    /**< list of peers */
78a75eb03bSDavid Marchand     IvshmemClientPeer local;            /**< our own infos */
79a75eb03bSDavid Marchand 
80a75eb03bSDavid Marchand     IvshmemClientNotifCb notif_cb;      /**< notification callback */
81a75eb03bSDavid Marchand     void *notif_arg;                    /**< notification argument */
82a75eb03bSDavid Marchand 
83a75eb03bSDavid Marchand     bool verbose;                       /**< true to enable debug */
84a75eb03bSDavid Marchand };
85a75eb03bSDavid Marchand 
86a75eb03bSDavid Marchand /**
87a75eb03bSDavid Marchand  * Initialize an ivshmem client
88a75eb03bSDavid Marchand  *
89a75eb03bSDavid Marchand  * @client:         A pointer to an uninitialized IvshmemClient structure
90a75eb03bSDavid Marchand  * @unix_sock_path: The pointer to the unix socket file name
91a75eb03bSDavid Marchand  * @notif_cb:       If not NULL, the pointer to the function to be called when
92a75eb03bSDavid Marchand  *                  our IvshmemClient receives a notification from a peer
93a75eb03bSDavid Marchand  * @notif_arg:      Opaque pointer given as-is to the notification callback
94a75eb03bSDavid Marchand  *                  function
95a75eb03bSDavid Marchand  * @verbose:        True to enable debug
96a75eb03bSDavid Marchand  *
97a75eb03bSDavid Marchand  * Returns:         0 on success, or a negative value on error
98a75eb03bSDavid Marchand  */
99a75eb03bSDavid Marchand int ivshmem_client_init(IvshmemClient *client, const char *unix_sock_path,
100a75eb03bSDavid Marchand                         IvshmemClientNotifCb notif_cb, void *notif_arg,
101a75eb03bSDavid Marchand                         bool verbose);
102a75eb03bSDavid Marchand 
103a75eb03bSDavid Marchand /**
104a75eb03bSDavid Marchand  * Connect to the server
105a75eb03bSDavid Marchand  *
106a75eb03bSDavid Marchand  * Connect to the server unix socket, and read the first initial
107a75eb03bSDavid Marchand  * messages sent by the server, giving the ID of the client and the file
108a75eb03bSDavid Marchand  * descriptor of the shared memory.
109a75eb03bSDavid Marchand  *
110a75eb03bSDavid Marchand  * @client: The ivshmem client
111a75eb03bSDavid Marchand  *
112a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error
113a75eb03bSDavid Marchand  */
114a75eb03bSDavid Marchand int ivshmem_client_connect(IvshmemClient *client);
115a75eb03bSDavid Marchand 
116a75eb03bSDavid Marchand /**
117a75eb03bSDavid Marchand  * Close connection to the server and free all peer structures
118a75eb03bSDavid Marchand  *
119a75eb03bSDavid Marchand  * @client: The ivshmem client
120a75eb03bSDavid Marchand  */
121a75eb03bSDavid Marchand void ivshmem_client_close(IvshmemClient *client);
122a75eb03bSDavid Marchand 
123a75eb03bSDavid Marchand /**
124a75eb03bSDavid Marchand  * Fill a fd_set with file descriptors to be monitored
125a75eb03bSDavid Marchand  *
126a75eb03bSDavid Marchand  * This function will fill a fd_set with all file descriptors
127a75eb03bSDavid Marchand  * that must be polled (unix server socket and peers eventfd). The
128a75eb03bSDavid Marchand  * function will not initialize the fd_set, it is up to the caller
129a75eb03bSDavid Marchand  * to do this.
130a75eb03bSDavid Marchand  *
131a75eb03bSDavid Marchand  * @client: The ivshmem client
132a75eb03bSDavid Marchand  * @fds:    The fd_set to be updated
133a75eb03bSDavid Marchand  * @maxfd:  Must be set to the max file descriptor + 1 in fd_set. This value is
134a75eb03bSDavid Marchand  *          updated if this function adds a greater fd in fd_set.
135a75eb03bSDavid Marchand  */
136a75eb03bSDavid Marchand void ivshmem_client_get_fds(const IvshmemClient *client, fd_set *fds,
137a75eb03bSDavid Marchand                             int *maxfd);
138a75eb03bSDavid Marchand 
139a75eb03bSDavid Marchand /**
140a75eb03bSDavid Marchand  * Read and handle new messages
141a75eb03bSDavid Marchand  *
142a75eb03bSDavid Marchand  * Given a fd_set filled by select(), handle incoming messages from
143a75eb03bSDavid Marchand  * server or peers.
144a75eb03bSDavid Marchand  *
145a75eb03bSDavid Marchand  * @client: The ivshmem client
146a75eb03bSDavid Marchand  * @fds:    The fd_set containing the file descriptors to be checked. Note
147a75eb03bSDavid Marchand  *          that file descriptors that are not related to our client are
148a75eb03bSDavid Marchand  *          ignored.
149a75eb03bSDavid Marchand  * @maxfd:  The maximum fd in fd_set, plus one.
150a75eb03bSDavid Marchand  *
151a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error
152a75eb03bSDavid Marchand  */
153a75eb03bSDavid Marchand int ivshmem_client_handle_fds(IvshmemClient *client, fd_set *fds, int maxfd);
154a75eb03bSDavid Marchand 
155a75eb03bSDavid Marchand /**
156a75eb03bSDavid Marchand  * Send a notification to a vector of a peer
157a75eb03bSDavid Marchand  *
158a75eb03bSDavid Marchand  * @client: The ivshmem client
159a75eb03bSDavid Marchand  * @peer:   The peer to be notified
160a75eb03bSDavid Marchand  * @vector: The number of the vector
161a75eb03bSDavid Marchand  *
162a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error
163a75eb03bSDavid Marchand  */
164a75eb03bSDavid Marchand int ivshmem_client_notify(const IvshmemClient *client,
165a75eb03bSDavid Marchand                           const IvshmemClientPeer *peer, unsigned vector);
166a75eb03bSDavid Marchand 
167a75eb03bSDavid Marchand /**
168a75eb03bSDavid Marchand  * Send a notification to all vectors of a peer
169a75eb03bSDavid Marchand  *
170a75eb03bSDavid Marchand  * @client: The ivshmem client
171a75eb03bSDavid Marchand  * @peer:   The peer to be notified
172a75eb03bSDavid Marchand  *
173a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error (at least one
174a75eb03bSDavid Marchand  *          notification failed)
175a75eb03bSDavid Marchand  */
176a75eb03bSDavid Marchand int ivshmem_client_notify_all_vects(const IvshmemClient *client,
177a75eb03bSDavid Marchand                                     const IvshmemClientPeer *peer);
178a75eb03bSDavid Marchand 
179a75eb03bSDavid Marchand /**
180a75eb03bSDavid Marchand  * Broadcat a notification to all vectors of all peers
181a75eb03bSDavid Marchand  *
182a75eb03bSDavid Marchand  * @client: The ivshmem client
183a75eb03bSDavid Marchand  *
184a75eb03bSDavid Marchand  * Returns: 0 on success, or a negative value on error (at least one
185a75eb03bSDavid Marchand  *          notification failed)
186a75eb03bSDavid Marchand  */
187a75eb03bSDavid Marchand int ivshmem_client_notify_broadcast(const IvshmemClient *client);
188a75eb03bSDavid Marchand 
189a75eb03bSDavid Marchand /**
190a75eb03bSDavid Marchand  * Search a peer from its identifier
191a75eb03bSDavid Marchand  *
192a75eb03bSDavid Marchand  * Return the peer structure from its peer_id. If the given peer_id is
193a75eb03bSDavid Marchand  * the local id, the function returns the local peer structure.
194a75eb03bSDavid Marchand  *
195a75eb03bSDavid Marchand  * @client:  The ivshmem client
196a75eb03bSDavid Marchand  * @peer_id: The identifier of the peer structure
197a75eb03bSDavid Marchand  *
198a75eb03bSDavid Marchand  * Returns:  The peer structure, or NULL if not found
199a75eb03bSDavid Marchand  */
200a75eb03bSDavid Marchand IvshmemClientPeer *
201a75eb03bSDavid Marchand ivshmem_client_search_peer(IvshmemClient *client, long peer_id);
202a75eb03bSDavid Marchand 
203a75eb03bSDavid Marchand /**
204a75eb03bSDavid Marchand  * Dump information of this ivshmem client on stdout
205a75eb03bSDavid Marchand  *
206a75eb03bSDavid Marchand  * Dump the id and the vectors of the given ivshmem client and the list
207a75eb03bSDavid Marchand  * of its peers and their vectors on stdout.
208a75eb03bSDavid Marchand  *
209a75eb03bSDavid Marchand  * @client: The ivshmem client
210a75eb03bSDavid Marchand  */
211a75eb03bSDavid Marchand void ivshmem_client_dump(const IvshmemClient *client);
212a75eb03bSDavid Marchand 
213a75eb03bSDavid Marchand #endif /* _IVSHMEM_CLIENT_H_ */
214