xref: /illumos-gate/usr/src/uts/common/xen/io/xpvtap.h (revision 7eea693d)
1*7eea693dSMark Johnson /*
2*7eea693dSMark Johnson  * CDDL HEADER START
3*7eea693dSMark Johnson  *
4*7eea693dSMark Johnson  * The contents of this file are subject to the terms of the
5*7eea693dSMark Johnson  * Common Development and Distribution License (the "License").
6*7eea693dSMark Johnson  * You may not use this file except in compliance with the License.
7*7eea693dSMark Johnson  *
8*7eea693dSMark Johnson  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7eea693dSMark Johnson  * or http://www.opensolaris.org/os/licensing.
10*7eea693dSMark Johnson  * See the License for the specific language governing permissions
11*7eea693dSMark Johnson  * and limitations under the License.
12*7eea693dSMark Johnson  *
13*7eea693dSMark Johnson  * When distributing Covered Code, include this CDDL HEADER in each
14*7eea693dSMark Johnson  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7eea693dSMark Johnson  * If applicable, add the following below this CDDL HEADER, with the
16*7eea693dSMark Johnson  * fields enclosed by brackets "[]" replaced with your own identifying
17*7eea693dSMark Johnson  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7eea693dSMark Johnson  *
19*7eea693dSMark Johnson  * CDDL HEADER END
20*7eea693dSMark Johnson  */
21*7eea693dSMark Johnson 
22*7eea693dSMark Johnson /*
23*7eea693dSMark Johnson  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*7eea693dSMark Johnson  * Use is subject to license terms.
25*7eea693dSMark Johnson  */
26*7eea693dSMark Johnson 
27*7eea693dSMark Johnson #ifndef _SYS_XPVTAP_H
28*7eea693dSMark Johnson #define	_SYS_XPVTAP_H
29*7eea693dSMark Johnson 
30*7eea693dSMark Johnson 
31*7eea693dSMark Johnson #ifdef __cplusplus
32*7eea693dSMark Johnson extern "C" {
33*7eea693dSMark Johnson #endif
34*7eea693dSMark Johnson 
35*7eea693dSMark Johnson #include <sys/types.h>
36*7eea693dSMark Johnson 
37*7eea693dSMark Johnson /* Notification from user app that it has pushed responses */
38*7eea693dSMark Johnson #define	XPVTAP_IOCTL_RESP_PUSH		1
39*7eea693dSMark Johnson 
40*7eea693dSMark Johnson /* Number of bytes the user app should mmap for the gref pages */
41*7eea693dSMark Johnson #define	XPVTAP_GREF_BUFSIZE	\
42*7eea693dSMark Johnson 	(BLKIF_RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGESIZE)
43*7eea693dSMark Johnson 
44*7eea693dSMark Johnson 
45*7eea693dSMark Johnson #ifdef	_KERNEL
46*7eea693dSMark Johnson 
47*7eea693dSMark Johnson #include <xen/io/blk_common.h>
48*7eea693dSMark Johnson 
49*7eea693dSMark Johnson 
50*7eea693dSMark Johnson #define	XPVTAP_GREF_REQADDR(base, id) (caddr_t) \
51*7eea693dSMark Johnson 	((uintptr_t)base + (id * BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGESIZE))
52*7eea693dSMark Johnson 
53*7eea693dSMark Johnson /* structure used to keep track of resources */
54*7eea693dSMark Johnson typedef struct xpvtap_rs_s {
55*7eea693dSMark Johnson 	/*
56*7eea693dSMark Johnson 	 * Bounds of resource allocation. We will start allocating at rs_min
57*7eea693dSMark Johnson 	 * and rollover at rs_max+1 (rs_max is included). e.g. for rs_min=0
58*7eea693dSMark Johnson 	 * and rs_max=7, we will have 8 total resources which can be alloced.
59*7eea693dSMark Johnson 	 */
60*7eea693dSMark Johnson 	uint_t rs_min;
61*7eea693dSMark Johnson 	uint_t rs_max;
62*7eea693dSMark Johnson 
63*7eea693dSMark Johnson 	/*
64*7eea693dSMark Johnson 	 * rs_free points to an array of 64-bit values used to track resource
65*7eea693dSMark Johnson 	 * allocation. rs_free_size is the free buffer size in bytes.
66*7eea693dSMark Johnson 	 */
67*7eea693dSMark Johnson 	uint64_t *rs_free;
68*7eea693dSMark Johnson 	uint_t rs_free_size;
69*7eea693dSMark Johnson 
70*7eea693dSMark Johnson 	/*
71*7eea693dSMark Johnson 	 * last tracks the last alloc'd resource. This allows us to do a round
72*7eea693dSMark Johnson 	 * robin allocation.
73*7eea693dSMark Johnson 	 */
74*7eea693dSMark Johnson 	uint_t rs_last;
75*7eea693dSMark Johnson 
76*7eea693dSMark Johnson 	/*
77*7eea693dSMark Johnson 	 * set when flushing all allocated resources. We'll know the lock
78*7eea693dSMark Johnson 	 * is held.
79*7eea693dSMark Johnson 	 */
80*7eea693dSMark Johnson 	boolean_t rs_flushing;
81*7eea693dSMark Johnson 
82*7eea693dSMark Johnson 	kmutex_t rs_mutex;
83*7eea693dSMark Johnson } xpvtap_rs_t;
84*7eea693dSMark Johnson typedef struct xpvtap_rs_s *xpvtap_rs_hdl_t;
85*7eea693dSMark Johnson 
86*7eea693dSMark Johnson /* track if user app has the device open, and sleep waiting for close */
87*7eea693dSMark Johnson typedef struct xpvtap_open_s {
88*7eea693dSMark Johnson 	kmutex_t	bo_mutex;
89*7eea693dSMark Johnson 	boolean_t	bo_opened;
90*7eea693dSMark Johnson 	kcondvar_t	bo_exit_cv;
91*7eea693dSMark Johnson } xpvtap_open_t;
92*7eea693dSMark Johnson 
93*7eea693dSMark Johnson /*
94*7eea693dSMark Johnson  * ring between driver and user app. requests are forwared from the
95*7eea693dSMark Johnson  * guest to the user app on this ring. reponses from the user app come in
96*7eea693dSMark Johnson  * on this ring are then are forwarded to the guest.
97*7eea693dSMark Johnson  */
98*7eea693dSMark Johnson typedef struct xpvtap_user_ring_s {
99*7eea693dSMark Johnson 	/* ring state */
100*7eea693dSMark Johnson 	blkif_front_ring_t	ur_ring;
101*7eea693dSMark Johnson 
102*7eea693dSMark Johnson 	/*
103*7eea693dSMark Johnson 	 * pointer to allocated memory for the ring which is shared between
104*7eea693dSMark Johnson 	 * the driver and the app.
105*7eea693dSMark Johnson 	 */
106*7eea693dSMark Johnson 	blkif_sring_t		*ur_sring;
107*7eea693dSMark Johnson 
108*7eea693dSMark Johnson 	/* umem cookie for free'ing up the umem */
109*7eea693dSMark Johnson 	ddi_umem_cookie_t	ur_cookie;
110*7eea693dSMark Johnson 
111*7eea693dSMark Johnson 	RING_IDX		ur_prod_polled;
112*7eea693dSMark Johnson } xpvtap_user_ring_t;
113*7eea693dSMark Johnson 
114*7eea693dSMark Johnson /*
115*7eea693dSMark Johnson  * track the requests that come in from the guest. we need to track the
116*7eea693dSMark Johnson  * requests for two reasons. first, we need to know how many grefs we need
117*7eea693dSMark Johnson  * to unmap when the app sends the response. second, since we use the ID in
118*7eea693dSMark Johnson  * the request to index into um_guest_pages (tells the app where the segments
119*7eea693dSMark Johnson  * are mapped), we need to have a mapping between the the ID we sent in the
120*7eea693dSMark Johnson  * request to the app and the ID we got from the guest request. The response
121*7eea693dSMark Johnson  * to the guest needs to have the later.
122*7eea693dSMark Johnson  */
123*7eea693dSMark Johnson typedef struct xpvtap_user_map_s {
124*7eea693dSMark Johnson 	/* address space of the user app. grab this in open */
125*7eea693dSMark Johnson 	struct as		*um_as;
126*7eea693dSMark Johnson 
127*7eea693dSMark Johnson 	/* state to track request IDs we can send to the user app */
128*7eea693dSMark Johnson 	xpvtap_rs_hdl_t		um_rs;
129*7eea693dSMark Johnson 
130*7eea693dSMark Johnson 	/*
131*7eea693dSMark Johnson 	 * base user app VA of the mapped grefs. this VA space is large enough
132*7eea693dSMark Johnson 	 * to map the max pages per request * max outstanding requests.
133*7eea693dSMark Johnson 	 */
134*7eea693dSMark Johnson 	caddr_t			um_guest_pages;
135*7eea693dSMark Johnson 	size_t			um_guest_size;
136*7eea693dSMark Johnson 
137*7eea693dSMark Johnson 	/*
138*7eea693dSMark Johnson 	 * have we locked down the gref buffer's ptes and registered
139*7eea693dSMark Johnson 	 * them with segmf. This needs to happen after the user app
140*7eea693dSMark Johnson 	 * has mmaped the gref buf.
141*7eea693dSMark Johnson 	 */
142*7eea693dSMark Johnson 	boolean_t		um_registered;
143*7eea693dSMark Johnson 
144*7eea693dSMark Johnson 	/*
145*7eea693dSMark Johnson 	 * array of outstanding requests to the user app. Index into this
146*7eea693dSMark Johnson 	 * array using the ID in the user app request.
147*7eea693dSMark Johnson 	 */
148*7eea693dSMark Johnson 	blkif_request_t		*um_outstanding_reqs;
149*7eea693dSMark Johnson } xpvtap_user_map_t;
150*7eea693dSMark Johnson 
151*7eea693dSMark Johnson /* thread start, wake, exit state */
152*7eea693dSMark Johnson typedef struct xpvtap_user_thread_s {
153*7eea693dSMark Johnson 	kmutex_t		ut_mutex;
154*7eea693dSMark Johnson 	kcondvar_t		ut_wake_cv;
155*7eea693dSMark Johnson 	volatile boolean_t	ut_wake;
156*7eea693dSMark Johnson 	volatile boolean_t	ut_exit;
157*7eea693dSMark Johnson 	kcondvar_t		ut_exit_done_cv;
158*7eea693dSMark Johnson 	volatile boolean_t	ut_exit_done;
159*7eea693dSMark Johnson 	ddi_taskq_t		*ut_taskq;
160*7eea693dSMark Johnson } xpvtap_user_thread_t;
161*7eea693dSMark Johnson 
162*7eea693dSMark Johnson /* driver state */
163*7eea693dSMark Johnson typedef struct xpvtap_state_s {
164*7eea693dSMark Johnson 	dev_info_t		*bt_dip;
165*7eea693dSMark Johnson 	int			bt_instance;
166*7eea693dSMark Johnson 
167*7eea693dSMark Johnson 	/* ring between the guest and xpvtap */
168*7eea693dSMark Johnson 	blk_ring_t		bt_guest_ring;
169*7eea693dSMark Johnson 
170*7eea693dSMark Johnson 	/* ring between xpvtap and the user app */
171*7eea693dSMark Johnson 	xpvtap_user_ring_t	bt_user_ring;
172*7eea693dSMark Johnson 
173*7eea693dSMark Johnson 	xpvtap_user_map_t	bt_map;
174*7eea693dSMark Johnson 	xpvtap_user_thread_t	bt_thread;
175*7eea693dSMark Johnson 	struct pollhead		bt_pollhead;
176*7eea693dSMark Johnson 	xpvtap_open_t		bt_open;
177*7eea693dSMark Johnson } xpvtap_state_t;
178*7eea693dSMark Johnson 
179*7eea693dSMark Johnson #endif /* _KERNEL */
180*7eea693dSMark Johnson 
181*7eea693dSMark Johnson #ifdef __cplusplus
182*7eea693dSMark Johnson }
183*7eea693dSMark Johnson #endif
184*7eea693dSMark Johnson 
185*7eea693dSMark Johnson #endif /* _SYS_XPVTAP_H */
186