Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/block/xen-blkback/common.h
15115 views
1
/*
2
* This program is free software; you can redistribute it and/or
3
* modify it under the terms of the GNU General Public License version 2
4
* as published by the Free Software Foundation; or, when distributed
5
* separately from the Linux kernel or incorporated into other
6
* software packages, subject to the following license:
7
*
8
* Permission is hereby granted, free of charge, to any person obtaining a copy
9
* of this source file (the "Software"), to deal in the Software without
10
* restriction, including without limitation the rights to use, copy, modify,
11
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
12
* and to permit persons to whom the Software is furnished to do so, subject to
13
* the following conditions:
14
*
15
* The above copyright notice and this permission notice shall be included in
16
* all copies or substantial portions of the Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
* IN THE SOFTWARE.
25
*/
26
27
#ifndef __XEN_BLKIF__BACKEND__COMMON_H__
28
#define __XEN_BLKIF__BACKEND__COMMON_H__
29
30
#include <linux/version.h>
31
#include <linux/module.h>
32
#include <linux/interrupt.h>
33
#include <linux/slab.h>
34
#include <linux/blkdev.h>
35
#include <linux/vmalloc.h>
36
#include <linux/wait.h>
37
#include <linux/io.h>
38
#include <asm/setup.h>
39
#include <asm/pgalloc.h>
40
#include <asm/hypervisor.h>
41
#include <xen/grant_table.h>
42
#include <xen/xenbus.h>
43
#include <xen/interface/io/ring.h>
44
#include <xen/interface/io/blkif.h>
45
#include <xen/interface/io/protocols.h>
46
47
#define DRV_PFX "xen-blkback:"
48
#define DPRINTK(fmt, args...) \
49
pr_debug(DRV_PFX "(%s:%d) " fmt ".\n", \
50
__func__, __LINE__, ##args)
51
52
53
/* Not a real protocol. Used to generate ring structs which contain
54
* the elements common to all protocols only. This way we get a
55
* compiler-checkable way to use common struct elements, so we can
56
* avoid using switch(protocol) in a number of places. */
57
struct blkif_common_request {
58
char dummy;
59
};
60
struct blkif_common_response {
61
char dummy;
62
};
63
64
/* i386 protocol version */
65
#pragma pack(push, 4)
66
struct blkif_x86_32_request {
67
uint8_t operation; /* BLKIF_OP_??? */
68
uint8_t nr_segments; /* number of segments */
69
blkif_vdev_t handle; /* only for read/write requests */
70
uint64_t id; /* private guest value, echoed in resp */
71
blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
72
struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
73
};
74
struct blkif_x86_32_response {
75
uint64_t id; /* copied from request */
76
uint8_t operation; /* copied from request */
77
int16_t status; /* BLKIF_RSP_??? */
78
};
79
#pragma pack(pop)
80
81
/* x86_64 protocol version */
82
struct blkif_x86_64_request {
83
uint8_t operation; /* BLKIF_OP_??? */
84
uint8_t nr_segments; /* number of segments */
85
blkif_vdev_t handle; /* only for read/write requests */
86
uint64_t __attribute__((__aligned__(8))) id;
87
blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
88
struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
89
};
90
struct blkif_x86_64_response {
91
uint64_t __attribute__((__aligned__(8))) id;
92
uint8_t operation; /* copied from request */
93
int16_t status; /* BLKIF_RSP_??? */
94
};
95
96
DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
97
struct blkif_common_response);
98
DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
99
struct blkif_x86_32_response);
100
DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
101
struct blkif_x86_64_response);
102
103
union blkif_back_rings {
104
struct blkif_back_ring native;
105
struct blkif_common_back_ring common;
106
struct blkif_x86_32_back_ring x86_32;
107
struct blkif_x86_64_back_ring x86_64;
108
};
109
110
enum blkif_protocol {
111
BLKIF_PROTOCOL_NATIVE = 1,
112
BLKIF_PROTOCOL_X86_32 = 2,
113
BLKIF_PROTOCOL_X86_64 = 3,
114
};
115
116
struct xen_vbd {
117
/* What the domain refers to this vbd as. */
118
blkif_vdev_t handle;
119
/* Non-zero -> read-only */
120
unsigned char readonly;
121
/* VDISK_xxx */
122
unsigned char type;
123
/* phys device that this vbd maps to. */
124
u32 pdevice;
125
struct block_device *bdev;
126
/* Cached size parameter. */
127
sector_t size;
128
bool flush_support;
129
};
130
131
struct backend_info;
132
133
struct xen_blkif {
134
/* Unique identifier for this interface. */
135
domid_t domid;
136
unsigned int handle;
137
/* Physical parameters of the comms window. */
138
unsigned int irq;
139
/* Comms information. */
140
enum blkif_protocol blk_protocol;
141
union blkif_back_rings blk_rings;
142
struct vm_struct *blk_ring_area;
143
/* The VBD attached to this interface. */
144
struct xen_vbd vbd;
145
/* Back pointer to the backend_info. */
146
struct backend_info *be;
147
/* Private fields. */
148
spinlock_t blk_ring_lock;
149
atomic_t refcnt;
150
151
wait_queue_head_t wq;
152
/* One thread per one blkif. */
153
struct task_struct *xenblkd;
154
unsigned int waiting_reqs;
155
156
/* statistics */
157
unsigned long st_print;
158
int st_rd_req;
159
int st_wr_req;
160
int st_oo_req;
161
int st_f_req;
162
int st_rd_sect;
163
int st_wr_sect;
164
165
wait_queue_head_t waiting_to_free;
166
167
grant_handle_t shmem_handle;
168
grant_ref_t shmem_ref;
169
};
170
171
172
#define vbd_sz(_v) ((_v)->bdev->bd_part ? \
173
(_v)->bdev->bd_part->nr_sects : \
174
get_capacity((_v)->bdev->bd_disk))
175
176
#define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))
177
#define xen_blkif_put(_b) \
178
do { \
179
if (atomic_dec_and_test(&(_b)->refcnt)) \
180
wake_up(&(_b)->waiting_to_free);\
181
} while (0)
182
183
struct phys_req {
184
unsigned short dev;
185
unsigned short nr_sects;
186
struct block_device *bdev;
187
blkif_sector_t sector_number;
188
};
189
int xen_blkif_interface_init(void);
190
191
int xen_blkif_xenbus_init(void);
192
193
irqreturn_t xen_blkif_be_int(int irq, void *dev_id);
194
int xen_blkif_schedule(void *arg);
195
196
int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
197
struct backend_info *be, int state);
198
199
struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be);
200
201
static inline void blkif_get_x86_32_req(struct blkif_request *dst,
202
struct blkif_x86_32_request *src)
203
{
204
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
205
dst->operation = src->operation;
206
dst->nr_segments = src->nr_segments;
207
dst->handle = src->handle;
208
dst->id = src->id;
209
dst->u.rw.sector_number = src->sector_number;
210
barrier();
211
if (n > dst->nr_segments)
212
n = dst->nr_segments;
213
for (i = 0; i < n; i++)
214
dst->u.rw.seg[i] = src->seg[i];
215
}
216
217
static inline void blkif_get_x86_64_req(struct blkif_request *dst,
218
struct blkif_x86_64_request *src)
219
{
220
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
221
dst->operation = src->operation;
222
dst->nr_segments = src->nr_segments;
223
dst->handle = src->handle;
224
dst->id = src->id;
225
dst->u.rw.sector_number = src->sector_number;
226
barrier();
227
if (n > dst->nr_segments)
228
n = dst->nr_segments;
229
for (i = 0; i < n; i++)
230
dst->u.rw.seg[i] = src->seg[i];
231
}
232
233
#endif /* __XEN_BLKIF__BACKEND__COMMON_H__ */
234
235