Blame view

drivers/virtio/virtio_ring.c 13.8 KB
0a8a69dd7   Rusty Russell   Virtio helper rou...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  /* Virtio ring implementation.
   *
   *  Copyright 2007 Rusty Russell IBM Corporation
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation; either version 2 of the License, or
   *  (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to the Free Software
   *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   */
  #include <linux/virtio.h>
  #include <linux/virtio_ring.h>
e34f87256   Rusty Russell   virtio: Add trans...
21
  #include <linux/virtio_config.h>
0a8a69dd7   Rusty Russell   Virtio helper rou...
22
  #include <linux/device.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
23
  #include <linux/slab.h>
b5a2c4f19   Paul Gortmaker   virtio: Add modul...
24
  #include <linux/module.h>
0a8a69dd7   Rusty Russell   Virtio helper rou...
25

d57ed95da   Michael S. Tsirkin   virtio: use smp_X...
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  /* virtio guest is communicating with a virtual "device" that actually runs on
   * a host processor.  Memory barriers are used to control SMP effects. */
  #ifdef CONFIG_SMP
  /* Where possible, use SMP barriers which are more lightweight than mandatory
   * barriers, because mandatory barriers control MMIO effects on accesses
   * through relaxed memory I/O windows (which virtio does not use). */
  #define virtio_mb() smp_mb()
  #define virtio_rmb() smp_rmb()
  #define virtio_wmb() smp_wmb()
  #else
  /* We must force memory ordering even if guest is UP since host could be
   * running on another CPU, but SMP barriers are defined to barrier() in that
   * configuration. So fall back to mandatory barriers instead. */
  #define virtio_mb() mb()
  #define virtio_rmb() rmb()
  #define virtio_wmb() wmb()
  #endif
0a8a69dd7   Rusty Russell   Virtio helper rou...
43
44
  #ifdef DEBUG
  /* For development, we want to crash whenever the ring is screwed. */
9499f5e7e   Rusty Russell   virtio: add names...
45
46
47
48
49
50
  #define BAD_RING(_vq, fmt, args...)				\
  	do {							\
  		dev_err(&(_vq)->vq.vdev->dev,			\
  			"%s:"fmt, (_vq)->vq.name, ##args);	\
  		BUG();						\
  	} while (0)
c5f841f17   Rusty Russell   virtio: more neat...
51
52
53
54
  /* Caller is supposed to guarantee no reentry. */
  #define START_USE(_vq)						\
  	do {							\
  		if ((_vq)->in_use)				\
9499f5e7e   Rusty Russell   virtio: add names...
55
56
57
  			panic("%s:in_use = %i
  ",		\
  			      (_vq)->vq.name, (_vq)->in_use);	\
c5f841f17   Rusty Russell   virtio: more neat...
58
  		(_vq)->in_use = __LINE__;			\
9499f5e7e   Rusty Russell   virtio: add names...
59
  	} while (0)
3a35ce7dc   Roel Kluin   virtio: fix BAD_R...
60
  #define END_USE(_vq) \
97a545ab6   Rusty Russell   virtio: remove bo...
61
  	do { BUG_ON(!(_vq)->in_use); (_vq)->in_use = 0; } while(0)
0a8a69dd7   Rusty Russell   Virtio helper rou...
62
  #else
9499f5e7e   Rusty Russell   virtio: add names...
63
64
65
66
67
68
  #define BAD_RING(_vq, fmt, args...)				\
  	do {							\
  		dev_err(&_vq->vq.vdev->dev,			\
  			"%s:"fmt, (_vq)->vq.name, ##args);	\
  		(_vq)->broken = true;				\
  	} while (0)
0a8a69dd7   Rusty Russell   Virtio helper rou...
69
70
71
72
73
74
75
76
77
78
79
80
81
  #define START_USE(vq)
  #define END_USE(vq)
  #endif
  
  struct vring_virtqueue
  {
  	struct virtqueue vq;
  
  	/* Actual memory layout for this queue */
  	struct vring vring;
  
  	/* Other side has made a mess, don't try any more. */
  	bool broken;
9fa29b9df   Mark McLoughlin   virtio: indirect ...
82
83
  	/* Host supports indirect buffers */
  	bool indirect;
a5c262c5f   Michael S. Tsirkin   virtio_ring: supp...
84
85
  	/* Host publishes avail event idx */
  	bool event;
0a8a69dd7   Rusty Russell   Virtio helper rou...
86
87
88
89
90
91
92
93
  	/* Number of free buffers */
  	unsigned int num_free;
  	/* Head of free buffer list. */
  	unsigned int free_head;
  	/* Number we've added since last sync. */
  	unsigned int num_added;
  
  	/* Last used index we've seen. */
1bc4953ed   Anthony Liguori   virtio: Fix used_...
94
  	u16 last_used_idx;
0a8a69dd7   Rusty Russell   Virtio helper rou...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  
  	/* How to notify other side. FIXME: commonalize hcalls! */
  	void (*notify)(struct virtqueue *vq);
  
  #ifdef DEBUG
  	/* They're supposed to lock for us. */
  	unsigned int in_use;
  #endif
  
  	/* Tokens for callbacks. */
  	void *data[];
  };
  
  #define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
9fa29b9df   Mark McLoughlin   virtio: indirect ...
109
110
111
112
  /* Set up an indirect table of descriptors and add it to the queue. */
  static int vring_add_indirect(struct vring_virtqueue *vq,
  			      struct scatterlist sg[],
  			      unsigned int out,
bbd603efb   Michael S. Tsirkin   virtio: add_buf_gfp
113
114
  			      unsigned int in,
  			      gfp_t gfp)
9fa29b9df   Mark McLoughlin   virtio: indirect ...
115
116
117
118
  {
  	struct vring_desc *desc;
  	unsigned head;
  	int i;
bbd603efb   Michael S. Tsirkin   virtio: add_buf_gfp
119
  	desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp);
9fa29b9df   Mark McLoughlin   virtio: indirect ...
120
  	if (!desc)
686d36378   Michael S. Tsirkin   virtio: return EN...
121
  		return -ENOMEM;
9fa29b9df   Mark McLoughlin   virtio: indirect ...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  
  	/* Transfer entries from the sg list into the indirect page */
  	for (i = 0; i < out; i++) {
  		desc[i].flags = VRING_DESC_F_NEXT;
  		desc[i].addr = sg_phys(sg);
  		desc[i].len = sg->length;
  		desc[i].next = i+1;
  		sg++;
  	}
  	for (; i < (out + in); i++) {
  		desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
  		desc[i].addr = sg_phys(sg);
  		desc[i].len = sg->length;
  		desc[i].next = i+1;
  		sg++;
  	}
  
  	/* Last one doesn't continue. */
  	desc[i-1].flags &= ~VRING_DESC_F_NEXT;
  	desc[i-1].next = 0;
  
  	/* We're about to use a buffer */
  	vq->num_free--;
  
  	/* Use a single buffer which doesn't continue */
  	head = vq->free_head;
  	vq->vring.desc[head].flags = VRING_DESC_F_INDIRECT;
  	vq->vring.desc[head].addr = virt_to_phys(desc);
  	vq->vring.desc[head].len = i * sizeof(struct vring_desc);
  
  	/* Update free pointer */
  	vq->free_head = vq->vring.desc[head].next;
  
  	return head;
  }
bbd603efb   Michael S. Tsirkin   virtio: add_buf_gfp
157
158
159
160
161
162
  int virtqueue_add_buf_gfp(struct virtqueue *_vq,
  			  struct scatterlist sg[],
  			  unsigned int out,
  			  unsigned int in,
  			  void *data,
  			  gfp_t gfp)
0a8a69dd7   Rusty Russell   Virtio helper rou...
163
164
  {
  	struct vring_virtqueue *vq = to_vvq(_vq);
1fe9b6fef   Michael S. Tsirkin   virtio: fix oops ...
165
166
  	unsigned int i, avail, uninitialized_var(prev);
  	int head;
0a8a69dd7   Rusty Russell   Virtio helper rou...
167

9fa29b9df   Mark McLoughlin   virtio: indirect ...
168
  	START_USE(vq);
0a8a69dd7   Rusty Russell   Virtio helper rou...
169
  	BUG_ON(data == NULL);
9fa29b9df   Mark McLoughlin   virtio: indirect ...
170
171
172
173
  
  	/* If the host supports indirect descriptor tables, and we have multiple
  	 * buffers, then go indirect. FIXME: tune this threshold */
  	if (vq->indirect && (out + in) > 1 && vq->num_free) {
bbd603efb   Michael S. Tsirkin   virtio: add_buf_gfp
174
  		head = vring_add_indirect(vq, sg, out, in, gfp);
1fe9b6fef   Michael S. Tsirkin   virtio: fix oops ...
175
  		if (likely(head >= 0))
9fa29b9df   Mark McLoughlin   virtio: indirect ...
176
177
  			goto add_head;
  	}
0a8a69dd7   Rusty Russell   Virtio helper rou...
178
179
  	BUG_ON(out + in > vq->vring.num);
  	BUG_ON(out + in == 0);
0a8a69dd7   Rusty Russell   Virtio helper rou...
180
181
182
183
  	if (vq->num_free < out + in) {
  		pr_debug("Can't add buf len %i - avail = %i
  ",
  			 out + in, vq->num_free);
44653eae1   Rusty Russell   virtio: don't alw...
184
185
186
187
188
  		/* FIXME: for historical reasons, we force a notify here if
  		 * there are outgoing parts to the buffer.  Presumably the
  		 * host should service the ring ASAP. */
  		if (out)
  			vq->notify(&vq->vq);
0a8a69dd7   Rusty Russell   Virtio helper rou...
189
190
191
192
193
194
195
196
197
198
  		END_USE(vq);
  		return -ENOSPC;
  	}
  
  	/* We're about to use some buffers from the free list. */
  	vq->num_free -= out + in;
  
  	head = vq->free_head;
  	for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) {
  		vq->vring.desc[i].flags = VRING_DESC_F_NEXT;
15f9c8903   Rusty Russell   virtio: Use the s...
199
  		vq->vring.desc[i].addr = sg_phys(sg);
0a8a69dd7   Rusty Russell   Virtio helper rou...
200
201
202
203
204
205
  		vq->vring.desc[i].len = sg->length;
  		prev = i;
  		sg++;
  	}
  	for (; in; i = vq->vring.desc[i].next, in--) {
  		vq->vring.desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
15f9c8903   Rusty Russell   virtio: Use the s...
206
  		vq->vring.desc[i].addr = sg_phys(sg);
0a8a69dd7   Rusty Russell   Virtio helper rou...
207
208
209
210
211
212
213
214
215
  		vq->vring.desc[i].len = sg->length;
  		prev = i;
  		sg++;
  	}
  	/* Last one doesn't continue. */
  	vq->vring.desc[prev].flags &= ~VRING_DESC_F_NEXT;
  
  	/* Update free pointer */
  	vq->free_head = i;
9fa29b9df   Mark McLoughlin   virtio: indirect ...
216
  add_head:
0a8a69dd7   Rusty Russell   Virtio helper rou...
217
218
219
220
221
222
223
224
225
226
227
  	/* Set token. */
  	vq->data[head] = data;
  
  	/* Put entry in available array (but don't update avail->idx until they
  	 * do sync).  FIXME: avoid modulus here? */
  	avail = (vq->vring.avail->idx + vq->num_added++) % vq->vring.num;
  	vq->vring.avail->ring[avail] = head;
  
  	pr_debug("Added buffer head %i to %p
  ", head, vq);
  	END_USE(vq);
3c1b27d50   Rusty Russell   virtio: make add_...
228

3c1b27d50   Rusty Russell   virtio: make add_...
229
  	return vq->num_free;
0a8a69dd7   Rusty Russell   Virtio helper rou...
230
  }
bbd603efb   Michael S. Tsirkin   virtio: add_buf_gfp
231
  EXPORT_SYMBOL_GPL(virtqueue_add_buf_gfp);
0a8a69dd7   Rusty Russell   Virtio helper rou...
232

7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
233
  void virtqueue_kick(struct virtqueue *_vq)
0a8a69dd7   Rusty Russell   Virtio helper rou...
234
235
  {
  	struct vring_virtqueue *vq = to_vvq(_vq);
a5c262c5f   Michael S. Tsirkin   virtio_ring: supp...
236
  	u16 new, old;
0a8a69dd7   Rusty Russell   Virtio helper rou...
237
238
239
  	START_USE(vq);
  	/* Descriptors and available array need to be set before we expose the
  	 * new available array entries. */
d57ed95da   Michael S. Tsirkin   virtio: use smp_X...
240
  	virtio_wmb();
0a8a69dd7   Rusty Russell   Virtio helper rou...
241

a5c262c5f   Michael S. Tsirkin   virtio_ring: supp...
242
243
  	old = vq->vring.avail->idx;
  	new = vq->vring.avail->idx = old + vq->num_added;
0a8a69dd7   Rusty Russell   Virtio helper rou...
244
245
246
  	vq->num_added = 0;
  
  	/* Need to update avail index before checking if we should notify */
d57ed95da   Michael S. Tsirkin   virtio: use smp_X...
247
  	virtio_mb();
0a8a69dd7   Rusty Russell   Virtio helper rou...
248

a5c262c5f   Michael S. Tsirkin   virtio_ring: supp...
249
250
251
  	if (vq->event ?
  	    vring_need_event(vring_avail_event(&vq->vring), new, old) :
  	    !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY))
0a8a69dd7   Rusty Russell   Virtio helper rou...
252
253
254
255
256
  		/* Prod other side to tell it about changes. */
  		vq->notify(&vq->vq);
  
  	END_USE(vq);
  }
7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
257
  EXPORT_SYMBOL_GPL(virtqueue_kick);
0a8a69dd7   Rusty Russell   Virtio helper rou...
258
259
260
261
262
263
264
265
266
267
  
  static void detach_buf(struct vring_virtqueue *vq, unsigned int head)
  {
  	unsigned int i;
  
  	/* Clear data ptr. */
  	vq->data[head] = NULL;
  
  	/* Put back on free list: find end */
  	i = head;
9fa29b9df   Mark McLoughlin   virtio: indirect ...
268
269
270
271
  
  	/* Free the indirect table */
  	if (vq->vring.desc[i].flags & VRING_DESC_F_INDIRECT)
  		kfree(phys_to_virt(vq->vring.desc[i].addr));
0a8a69dd7   Rusty Russell   Virtio helper rou...
272
273
274
275
276
277
278
279
280
281
  	while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) {
  		i = vq->vring.desc[i].next;
  		vq->num_free++;
  	}
  
  	vq->vring.desc[i].next = vq->free_head;
  	vq->free_head = head;
  	/* Plus final descriptor */
  	vq->num_free++;
  }
0a8a69dd7   Rusty Russell   Virtio helper rou...
282
283
284
285
  static inline bool more_used(const struct vring_virtqueue *vq)
  {
  	return vq->last_used_idx != vq->vring.used->idx;
  }
7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
286
  void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len)
0a8a69dd7   Rusty Russell   Virtio helper rou...
287
288
289
290
291
292
  {
  	struct vring_virtqueue *vq = to_vvq(_vq);
  	void *ret;
  	unsigned int i;
  
  	START_USE(vq);
5ef827526   Rusty Russell   virtio: ignore co...
293
294
295
296
  	if (unlikely(vq->broken)) {
  		END_USE(vq);
  		return NULL;
  	}
0a8a69dd7   Rusty Russell   Virtio helper rou...
297
298
299
300
301
302
  	if (!more_used(vq)) {
  		pr_debug("No more buffers in queue
  ");
  		END_USE(vq);
  		return NULL;
  	}
2d61ba950   Michael S. Tsirkin   virtio: order use...
303
  	/* Only get used array entries after they have been exposed by host. */
d57ed95da   Michael S. Tsirkin   virtio: use smp_X...
304
  	virtio_rmb();
2d61ba950   Michael S. Tsirkin   virtio: order use...
305

0a8a69dd7   Rusty Russell   Virtio helper rou...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  	i = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].id;
  	*len = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].len;
  
  	if (unlikely(i >= vq->vring.num)) {
  		BAD_RING(vq, "id %u out of range
  ", i);
  		return NULL;
  	}
  	if (unlikely(!vq->data[i])) {
  		BAD_RING(vq, "id %u is not a head!
  ", i);
  		return NULL;
  	}
  
  	/* detach_buf clears data, so grab it now. */
  	ret = vq->data[i];
  	detach_buf(vq, i);
  	vq->last_used_idx++;
a5c262c5f   Michael S. Tsirkin   virtio_ring: supp...
324
325
326
327
328
329
330
  	/* If we expect an interrupt for the next entry, tell host
  	 * by writing event index and flush out the write before
  	 * the read in the next get_buf call. */
  	if (!(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) {
  		vring_used_event(&vq->vring) = vq->last_used_idx;
  		virtio_mb();
  	}
0a8a69dd7   Rusty Russell   Virtio helper rou...
331
332
333
  	END_USE(vq);
  	return ret;
  }
7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
334
  EXPORT_SYMBOL_GPL(virtqueue_get_buf);
0a8a69dd7   Rusty Russell   Virtio helper rou...
335

7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
336
  void virtqueue_disable_cb(struct virtqueue *_vq)
18445c4d5   Rusty Russell   virtio: explicit ...
337
338
  {
  	struct vring_virtqueue *vq = to_vvq(_vq);
18445c4d5   Rusty Russell   virtio: explicit ...
339
  	vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
18445c4d5   Rusty Russell   virtio: explicit ...
340
  }
7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
341
  EXPORT_SYMBOL_GPL(virtqueue_disable_cb);
18445c4d5   Rusty Russell   virtio: explicit ...
342

7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
343
  bool virtqueue_enable_cb(struct virtqueue *_vq)
0a8a69dd7   Rusty Russell   Virtio helper rou...
344
345
346
347
  {
  	struct vring_virtqueue *vq = to_vvq(_vq);
  
  	START_USE(vq);
0a8a69dd7   Rusty Russell   Virtio helper rou...
348
349
350
  
  	/* We optimistically turn back on interrupts, then check if there was
  	 * more to do. */
a5c262c5f   Michael S. Tsirkin   virtio_ring: supp...
351
352
353
  	/* Depending on the VIRTIO_RING_F_EVENT_IDX feature, we need to
  	 * either clear the flags bit or point the event index at the next
  	 * entry. Always do both to keep code simple. */
0a8a69dd7   Rusty Russell   Virtio helper rou...
354
  	vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
a5c262c5f   Michael S. Tsirkin   virtio_ring: supp...
355
  	vring_used_event(&vq->vring) = vq->last_used_idx;
d57ed95da   Michael S. Tsirkin   virtio: use smp_X...
356
  	virtio_mb();
0a8a69dd7   Rusty Russell   Virtio helper rou...
357
  	if (unlikely(more_used(vq))) {
0a8a69dd7   Rusty Russell   Virtio helper rou...
358
359
360
361
362
363
364
  		END_USE(vq);
  		return false;
  	}
  
  	END_USE(vq);
  	return true;
  }
7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
365
  EXPORT_SYMBOL_GPL(virtqueue_enable_cb);
0a8a69dd7   Rusty Russell   Virtio helper rou...
366

7ab358c23   Michael S. Tsirkin   virtio: add api f...
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
  bool virtqueue_enable_cb_delayed(struct virtqueue *_vq)
  {
  	struct vring_virtqueue *vq = to_vvq(_vq);
  	u16 bufs;
  
  	START_USE(vq);
  
  	/* We optimistically turn back on interrupts, then check if there was
  	 * more to do. */
  	/* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
  	 * either clear the flags bit or point the event index at the next
  	 * entry. Always do both to keep code simple. */
  	vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
  	/* TODO: tune this threshold */
  	bufs = (u16)(vq->vring.avail->idx - vq->last_used_idx) * 3 / 4;
  	vring_used_event(&vq->vring) = vq->last_used_idx + bufs;
  	virtio_mb();
  	if (unlikely((u16)(vq->vring.used->idx - vq->last_used_idx) > bufs)) {
  		END_USE(vq);
  		return false;
  	}
  
  	END_USE(vq);
  	return true;
  }
  EXPORT_SYMBOL_GPL(virtqueue_enable_cb_delayed);
7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
393
  void *virtqueue_detach_unused_buf(struct virtqueue *_vq)
c021eac41   Shirley Ma   virtio: Add abili...
394
395
396
397
398
399
400
401
402
403
404
405
406
  {
  	struct vring_virtqueue *vq = to_vvq(_vq);
  	unsigned int i;
  	void *buf;
  
  	START_USE(vq);
  
  	for (i = 0; i < vq->vring.num; i++) {
  		if (!vq->data[i])
  			continue;
  		/* detach_buf clears data, so grab it now. */
  		buf = vq->data[i];
  		detach_buf(vq, i);
b3258ff1d   Amit Shah   virtio: Decrement...
407
  		vq->vring.avail->idx--;
c021eac41   Shirley Ma   virtio: Add abili...
408
409
410
411
412
413
414
415
416
  		END_USE(vq);
  		return buf;
  	}
  	/* That should have freed everything. */
  	BUG_ON(vq->num_free != vq->vring.num);
  
  	END_USE(vq);
  	return NULL;
  }
7c5e9ed0c   Michael S. Tsirkin   virtio_ring: remo...
417
  EXPORT_SYMBOL_GPL(virtqueue_detach_unused_buf);
c021eac41   Shirley Ma   virtio: Add abili...
418

0a8a69dd7   Rusty Russell   Virtio helper rou...
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  irqreturn_t vring_interrupt(int irq, void *_vq)
  {
  	struct vring_virtqueue *vq = to_vvq(_vq);
  
  	if (!more_used(vq)) {
  		pr_debug("virtqueue interrupt with no work for %p
  ", vq);
  		return IRQ_NONE;
  	}
  
  	if (unlikely(vq->broken))
  		return IRQ_HANDLED;
  
  	pr_debug("virtqueue callback for %p (%p)
  ", vq, vq->vq.callback);
18445c4d5   Rusty Russell   virtio: explicit ...
434
435
  	if (vq->vq.callback)
  		vq->vq.callback(&vq->vq);
0a8a69dd7   Rusty Russell   Virtio helper rou...
436
437
438
  
  	return IRQ_HANDLED;
  }
c6fd47011   Rusty Russell   virtio: Allow vir...
439
  EXPORT_SYMBOL_GPL(vring_interrupt);
0a8a69dd7   Rusty Russell   Virtio helper rou...
440

0a8a69dd7   Rusty Russell   Virtio helper rou...
441
  struct virtqueue *vring_new_virtqueue(unsigned int num,
87c7d57c1   Rusty Russell   virtio: hand virt...
442
  				      unsigned int vring_align,
0a8a69dd7   Rusty Russell   Virtio helper rou...
443
444
445
  				      struct virtio_device *vdev,
  				      void *pages,
  				      void (*notify)(struct virtqueue *),
9499f5e7e   Rusty Russell   virtio: add names...
446
447
  				      void (*callback)(struct virtqueue *),
  				      const char *name)
0a8a69dd7   Rusty Russell   Virtio helper rou...
448
449
450
  {
  	struct vring_virtqueue *vq;
  	unsigned int i;
42b36cc0c   Rusty Russell   virtio: Force use...
451
452
453
454
455
456
  	/* We assume num is a power of 2. */
  	if (num & (num - 1)) {
  		dev_warn(&vdev->dev, "Bad virtqueue length %u
  ", num);
  		return NULL;
  	}
0a8a69dd7   Rusty Russell   Virtio helper rou...
457
458
459
  	vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
  	if (!vq)
  		return NULL;
87c7d57c1   Rusty Russell   virtio: hand virt...
460
  	vring_init(&vq->vring, num, pages, vring_align);
0a8a69dd7   Rusty Russell   Virtio helper rou...
461
462
  	vq->vq.callback = callback;
  	vq->vq.vdev = vdev;
9499f5e7e   Rusty Russell   virtio: add names...
463
  	vq->vq.name = name;
0a8a69dd7   Rusty Russell   Virtio helper rou...
464
465
466
467
  	vq->notify = notify;
  	vq->broken = false;
  	vq->last_used_idx = 0;
  	vq->num_added = 0;
9499f5e7e   Rusty Russell   virtio: add names...
468
  	list_add_tail(&vq->vq.list, &vdev->vqs);
0a8a69dd7   Rusty Russell   Virtio helper rou...
469
470
471
  #ifdef DEBUG
  	vq->in_use = false;
  #endif
9fa29b9df   Mark McLoughlin   virtio: indirect ...
472
  	vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC);
a5c262c5f   Michael S. Tsirkin   virtio_ring: supp...
473
  	vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX);
9fa29b9df   Mark McLoughlin   virtio: indirect ...
474

0a8a69dd7   Rusty Russell   Virtio helper rou...
475
476
477
478
479
480
481
  	/* No callback?  Tell other side not to bother us. */
  	if (!callback)
  		vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
  
  	/* Put everything in free lists. */
  	vq->num_free = num;
  	vq->free_head = 0;
3b8706240   Amit Shah   virtio: Initializ...
482
  	for (i = 0; i < num-1; i++) {
0a8a69dd7   Rusty Russell   Virtio helper rou...
483
  		vq->vring.desc[i].next = i+1;
3b8706240   Amit Shah   virtio: Initializ...
484
485
486
  		vq->data[i] = NULL;
  	}
  	vq->data[i] = NULL;
0a8a69dd7   Rusty Russell   Virtio helper rou...
487
488
489
  
  	return &vq->vq;
  }
c6fd47011   Rusty Russell   virtio: Allow vir...
490
  EXPORT_SYMBOL_GPL(vring_new_virtqueue);
0a8a69dd7   Rusty Russell   Virtio helper rou...
491
492
493
  
  void vring_del_virtqueue(struct virtqueue *vq)
  {
9499f5e7e   Rusty Russell   virtio: add names...
494
  	list_del(&vq->list);
0a8a69dd7   Rusty Russell   Virtio helper rou...
495
496
  	kfree(to_vvq(vq));
  }
c6fd47011   Rusty Russell   virtio: Allow vir...
497
  EXPORT_SYMBOL_GPL(vring_del_virtqueue);
0a8a69dd7   Rusty Russell   Virtio helper rou...
498

e34f87256   Rusty Russell   virtio: Add trans...
499
500
501
502
503
504
505
  /* Manipulates transport-specific feature bits. */
  void vring_transport_features(struct virtio_device *vdev)
  {
  	unsigned int i;
  
  	for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++) {
  		switch (i) {
9fa29b9df   Mark McLoughlin   virtio: indirect ...
506
507
  		case VIRTIO_RING_F_INDIRECT_DESC:
  			break;
a5c262c5f   Michael S. Tsirkin   virtio_ring: supp...
508
509
  		case VIRTIO_RING_F_EVENT_IDX:
  			break;
e34f87256   Rusty Russell   virtio: Add trans...
510
511
512
513
514
515
516
  		default:
  			/* We don't understand this bit. */
  			clear_bit(i, vdev->features);
  		}
  	}
  }
  EXPORT_SYMBOL_GPL(vring_transport_features);
8f9f4668b   Rick Jones   Add ethtool -g su...
517
518
519
520
521
522
523
524
525
  /* return the size of the vring within the virtqueue */
  unsigned int virtqueue_get_vring_size(struct virtqueue *_vq)
  {
  
  	struct vring_virtqueue *vq = to_vvq(_vq);
  
  	return vq->vring.num;
  }
  EXPORT_SYMBOL_GPL(virtqueue_get_vring_size);
c6fd47011   Rusty Russell   virtio: Allow vir...
526
  MODULE_LICENSE("GPL");