Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * The Virtio 9p transport driver
4 : : *
5 : : * This is a block based transport driver based on the lguest block driver
6 : : * code.
7 : : *
8 : : * Copyright (C) 2007, 2008 Eric Van Hensbergen, IBM Corporation
9 : : *
10 : : * Based on virtio console driver
11 : : * Copyright (C) 2006, 2007 Rusty Russell, IBM Corporation
12 : : */
13 : :
14 : : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 : :
16 : : #include <linux/in.h>
17 : : #include <linux/module.h>
18 : : #include <linux/net.h>
19 : : #include <linux/ipv6.h>
20 : : #include <linux/errno.h>
21 : : #include <linux/kernel.h>
22 : : #include <linux/un.h>
23 : : #include <linux/uaccess.h>
24 : : #include <linux/inet.h>
25 : : #include <linux/idr.h>
26 : : #include <linux/file.h>
27 : : #include <linux/highmem.h>
28 : : #include <linux/slab.h>
29 : : #include <net/9p/9p.h>
30 : : #include <linux/parser.h>
31 : : #include <net/9p/client.h>
32 : : #include <net/9p/transport.h>
33 : : #include <linux/scatterlist.h>
34 : : #include <linux/swap.h>
35 : : #include <linux/virtio.h>
36 : : #include <linux/virtio_9p.h>
37 : : #include "trans_common.h"
38 : :
39 : : #define VIRTQUEUE_NUM 128
40 : :
41 : : /* a single mutex to manage channel initialization and attachment */
42 : : static DEFINE_MUTEX(virtio_9p_lock);
43 : : static DECLARE_WAIT_QUEUE_HEAD(vp_wq);
44 : : static atomic_t vp_pinned = ATOMIC_INIT(0);
45 : :
46 : : /**
47 : : * struct virtio_chan - per-instance transport information
48 : : * @inuse: whether the channel is in use
49 : : * @lock: protects multiple elements within this structure
50 : : * @client: client instance
51 : : * @vdev: virtio dev associated with this channel
52 : : * @vq: virtio queue associated with this channel
53 : : * @sg: scatter gather list which is used to pack a request (protected?)
54 : : *
55 : : * We keep all per-channel information in a structure.
56 : : * This structure is allocated within the devices dev->mem space.
57 : : * A pointer to the structure will get put in the transport private.
58 : : *
59 : : */
60 : :
61 : : struct virtio_chan {
62 : : bool inuse;
63 : :
64 : : spinlock_t lock;
65 : :
66 : : struct p9_client *client;
67 : : struct virtio_device *vdev;
68 : : struct virtqueue *vq;
69 : : int ring_bufs_avail;
70 : : wait_queue_head_t *vc_wq;
71 : : /* This is global limit. Since we don't have a global structure,
72 : : * will be placing it in each channel.
73 : : */
74 : : unsigned long p9_max_pages;
75 : : /* Scatterlist: can be too big for stack. */
76 : : struct scatterlist sg[VIRTQUEUE_NUM];
77 : : /*
78 : : * tag name to identify a mount null terminated
79 : : */
80 : : char *tag;
81 : :
82 : : struct list_head chan_list;
83 : : };
84 : :
85 : : static struct list_head virtio_chan_list;
86 : :
87 : : /* How many bytes left in this page. */
88 : 0 : static unsigned int rest_of_page(void *data)
89 : : {
90 : 0 : return PAGE_SIZE - offset_in_page(data);
91 : : }
92 : :
93 : : /**
94 : : * p9_virtio_close - reclaim resources of a channel
95 : : * @client: client instance
96 : : *
97 : : * This reclaims a channel by freeing its resources and
98 : : * reseting its inuse flag.
99 : : *
100 : : */
101 : :
102 : 0 : static void p9_virtio_close(struct p9_client *client)
103 : : {
104 : 0 : struct virtio_chan *chan = client->trans;
105 : :
106 : 0 : mutex_lock(&virtio_9p_lock);
107 [ # # ]: 0 : if (chan)
108 : 0 : chan->inuse = false;
109 : 0 : mutex_unlock(&virtio_9p_lock);
110 : 0 : }
111 : :
112 : : /**
113 : : * req_done - callback which signals activity from the server
114 : : * @vq: virtio queue activity was received on
115 : : *
116 : : * This notifies us that the server has triggered some activity
117 : : * on the virtio channel - most likely a response to request we
118 : : * sent. Figure out which requests now have responses and wake up
119 : : * those threads.
120 : : *
121 : : * Bugs: could do with some additional sanity checking, but appears to work.
122 : : *
123 : : */
124 : :
125 : 0 : static void req_done(struct virtqueue *vq)
126 : : {
127 : 0 : struct virtio_chan *chan = vq->vdev->priv;
128 : 0 : unsigned int len;
129 : 0 : struct p9_req_t *req;
130 : 0 : bool need_wakeup = false;
131 : 0 : unsigned long flags;
132 : :
133 : 0 : p9_debug(P9_DEBUG_TRANS, ": request done\n");
134 : :
135 : 0 : spin_lock_irqsave(&chan->lock, flags);
136 [ # # ]: 0 : while ((req = virtqueue_get_buf(chan->vq, &len)) != NULL) {
137 [ # # ]: 0 : if (!chan->ring_bufs_avail) {
138 : 0 : chan->ring_bufs_avail = 1;
139 : 0 : need_wakeup = true;
140 : : }
141 : :
142 [ # # ]: 0 : if (len) {
143 : 0 : req->rc.size = len;
144 : 0 : p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
145 : : }
146 : : }
147 : 0 : spin_unlock_irqrestore(&chan->lock, flags);
148 : : /* Wakeup if anyone waiting for VirtIO ring space. */
149 [ # # ]: 0 : if (need_wakeup)
150 : 0 : wake_up(chan->vc_wq);
151 : 0 : }
152 : :
153 : : /**
154 : : * pack_sg_list - pack a scatter gather list from a linear buffer
155 : : * @sg: scatter/gather list to pack into
156 : : * @start: which segment of the sg_list to start at
157 : : * @limit: maximum segment to pack data to
158 : : * @data: data to pack into scatter/gather list
159 : : * @count: amount of data to pack into the scatter/gather list
160 : : *
161 : : * sg_lists have multiple segments of various sizes. This will pack
162 : : * arbitrary data into an existing scatter gather list, segmenting the
163 : : * data as necessary within constraints.
164 : : *
165 : : */
166 : :
167 : 0 : static int pack_sg_list(struct scatterlist *sg, int start,
168 : : int limit, char *data, int count)
169 : : {
170 : 0 : int s;
171 : 0 : int index = start;
172 : :
173 [ # # ]: 0 : while (count) {
174 : 0 : s = rest_of_page(data);
175 : 0 : if (s > count)
176 : : s = count;
177 [ # # ]: 0 : BUG_ON(index >= limit);
178 : : /* Make sure we don't terminate early. */
179 : 0 : sg_unmark_end(&sg[index]);
180 : 0 : sg_set_buf(&sg[index++], data, s);
181 : 0 : count -= s;
182 : 0 : data += s;
183 : : }
184 [ # # ]: 0 : if (index-start)
185 : 0 : sg_mark_end(&sg[index - 1]);
186 : 0 : return index-start;
187 : : }
188 : :
189 : : /* We don't currently allow canceling of virtio requests */
190 : 0 : static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
191 : : {
192 : 0 : return 1;
193 : : }
194 : :
195 : : /* Reply won't come, so drop req ref */
196 : 0 : static int p9_virtio_cancelled(struct p9_client *client, struct p9_req_t *req)
197 : : {
198 : 0 : p9_req_put(req);
199 : 0 : return 0;
200 : : }
201 : :
202 : : /**
203 : : * pack_sg_list_p - Just like pack_sg_list. Instead of taking a buffer,
204 : : * this takes a list of pages.
205 : : * @sg: scatter/gather list to pack into
206 : : * @start: which segment of the sg_list to start at
207 : : * @pdata: a list of pages to add into sg.
208 : : * @nr_pages: number of pages to pack into the scatter/gather list
209 : : * @offs: amount of data in the beginning of first page _not_ to pack
210 : : * @count: amount of data to pack into the scatter/gather list
211 : : */
212 : : static int
213 : 0 : pack_sg_list_p(struct scatterlist *sg, int start, int limit,
214 : : struct page **pdata, int nr_pages, size_t offs, int count)
215 : : {
216 : 0 : int i = 0, s;
217 : 0 : int data_off = offs;
218 : 0 : int index = start;
219 : :
220 [ # # ]: 0 : BUG_ON(nr_pages > (limit - start));
221 : : /*
222 : : * if the first page doesn't start at
223 : : * page boundary find the offset
224 : : */
225 [ # # ]: 0 : while (nr_pages) {
226 : 0 : s = PAGE_SIZE - data_off;
227 : 0 : if (s > count)
228 : : s = count;
229 [ # # ]: 0 : BUG_ON(index >= limit);
230 : : /* Make sure we don't terminate early. */
231 [ # # ]: 0 : sg_unmark_end(&sg[index]);
232 [ # # ]: 0 : sg_set_page(&sg[index++], pdata[i++], s, data_off);
233 : 0 : data_off = 0;
234 : 0 : count -= s;
235 : 0 : nr_pages--;
236 : : }
237 : :
238 [ # # ]: 0 : if (index-start)
239 : 0 : sg_mark_end(&sg[index - 1]);
240 : 0 : return index - start;
241 : : }
242 : :
243 : : /**
244 : : * p9_virtio_request - issue a request
245 : : * @client: client instance issuing the request
246 : : * @req: request to be issued
247 : : *
248 : : */
249 : :
250 : : static int
251 : 0 : p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
252 : : {
253 : 0 : int err;
254 : 0 : int in, out, out_sgs, in_sgs;
255 : 0 : unsigned long flags;
256 : 0 : struct virtio_chan *chan = client->trans;
257 : 0 : struct scatterlist *sgs[2];
258 : :
259 : 0 : p9_debug(P9_DEBUG_TRANS, "9p debug: virtio request\n");
260 : :
261 : 0 : req->status = REQ_STATUS_SENT;
262 : 0 : req_retry:
263 : 0 : spin_lock_irqsave(&chan->lock, flags);
264 : :
265 : 0 : out_sgs = in_sgs = 0;
266 : : /* Handle out VirtIO ring buffers */
267 : 0 : out = pack_sg_list(chan->sg, 0,
268 : 0 : VIRTQUEUE_NUM, req->tc.sdata, req->tc.size);
269 [ # # ]: 0 : if (out)
270 : 0 : sgs[out_sgs++] = chan->sg;
271 : :
272 : 0 : in = pack_sg_list(chan->sg, out,
273 : 0 : VIRTQUEUE_NUM, req->rc.sdata, req->rc.capacity);
274 [ # # ]: 0 : if (in)
275 : 0 : sgs[out_sgs + in_sgs++] = chan->sg + out;
276 : :
277 : 0 : err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req,
278 : : GFP_ATOMIC);
279 [ # # ]: 0 : if (err < 0) {
280 [ # # ]: 0 : if (err == -ENOSPC) {
281 : 0 : chan->ring_bufs_avail = 0;
282 : 0 : spin_unlock_irqrestore(&chan->lock, flags);
283 [ # # # # : 0 : err = wait_event_killable(*chan->vc_wq,
# # ]
284 : : chan->ring_bufs_avail);
285 [ # # ]: 0 : if (err == -ERESTARTSYS)
286 : : return err;
287 : :
288 : 0 : p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
289 : 0 : goto req_retry;
290 : : } else {
291 : 0 : spin_unlock_irqrestore(&chan->lock, flags);
292 : 0 : p9_debug(P9_DEBUG_TRANS,
293 : : "virtio rpc add_sgs returned failure\n");
294 : 0 : return -EIO;
295 : : }
296 : : }
297 : 0 : virtqueue_kick(chan->vq);
298 : 0 : spin_unlock_irqrestore(&chan->lock, flags);
299 : :
300 : 0 : p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
301 : 0 : return 0;
302 : : }
303 : :
304 : : static int p9_get_mapped_pages(struct virtio_chan *chan,
305 : : struct page ***pages,
306 : : struct iov_iter *data,
307 : : int count,
308 : : size_t *offs,
309 : : int *need_drop)
310 : : {
311 : : int nr_pages;
312 : : int err;
313 : :
314 : : if (!iov_iter_count(data))
315 : : return 0;
316 : :
317 : : if (!iov_iter_is_kvec(data)) {
318 : : int n;
319 : : /*
320 : : * We allow only p9_max_pages pinned. We wait for the
321 : : * Other zc request to finish here
322 : : */
323 : : if (atomic_read(&vp_pinned) >= chan->p9_max_pages) {
324 : : err = wait_event_killable(vp_wq,
325 : : (atomic_read(&vp_pinned) < chan->p9_max_pages));
326 : : if (err == -ERESTARTSYS)
327 : : return err;
328 : : }
329 : : n = iov_iter_get_pages_alloc(data, pages, count, offs);
330 : : if (n < 0)
331 : : return n;
332 : : *need_drop = 1;
333 : : nr_pages = DIV_ROUND_UP(n + *offs, PAGE_SIZE);
334 : : atomic_add(nr_pages, &vp_pinned);
335 : : return n;
336 : : } else {
337 : : /* kernel buffer, no need to pin pages */
338 : : int index;
339 : : size_t len;
340 : : void *p;
341 : :
342 : : /* we'd already checked that it's non-empty */
343 : : while (1) {
344 : : len = iov_iter_single_seg_count(data);
345 : : if (likely(len)) {
346 : : p = data->kvec->iov_base + data->iov_offset;
347 : : break;
348 : : }
349 : : iov_iter_advance(data, 0);
350 : : }
351 : : if (len > count)
352 : : len = count;
353 : :
354 : : nr_pages = DIV_ROUND_UP((unsigned long)p + len, PAGE_SIZE) -
355 : : (unsigned long)p / PAGE_SIZE;
356 : :
357 : : *pages = kmalloc_array(nr_pages, sizeof(struct page *),
358 : : GFP_NOFS);
359 : : if (!*pages)
360 : : return -ENOMEM;
361 : :
362 : : *need_drop = 0;
363 : : p -= (*offs = offset_in_page(p));
364 : : for (index = 0; index < nr_pages; index++) {
365 : : if (is_vmalloc_addr(p))
366 : : (*pages)[index] = vmalloc_to_page(p);
367 : : else
368 : : (*pages)[index] = kmap_to_page(p);
369 : : p += PAGE_SIZE;
370 : : }
371 : : return len;
372 : : }
373 : : }
374 : :
375 : : /**
376 : : * p9_virtio_zc_request - issue a zero copy request
377 : : * @client: client instance issuing the request
378 : : * @req: request to be issued
379 : : * @uidata: user buffer that should be used for zero copy read
380 : : * @uodata: user buffer that should be used for zero copy write
381 : : * @inlen: read buffer size
382 : : * @outlen: write buffer size
383 : : * @in_hdr_len: reader header size, This is the size of response protocol data
384 : : *
385 : : */
386 : : static int
387 : 0 : p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
388 : : struct iov_iter *uidata, struct iov_iter *uodata,
389 : : int inlen, int outlen, int in_hdr_len)
390 : : {
391 : 0 : int in, out, err, out_sgs, in_sgs;
392 : 0 : unsigned long flags;
393 : 0 : int in_nr_pages = 0, out_nr_pages = 0;
394 : 0 : struct page **in_pages = NULL, **out_pages = NULL;
395 : 0 : struct virtio_chan *chan = client->trans;
396 : 0 : struct scatterlist *sgs[4];
397 : 0 : size_t offs;
398 : 0 : int need_drop = 0;
399 : 0 : int kicked = 0;
400 : :
401 : 0 : p9_debug(P9_DEBUG_TRANS, "virtio request\n");
402 : :
403 [ # # ]: 0 : if (uodata) {
404 : 0 : __le32 sz;
405 : 0 : int n = p9_get_mapped_pages(chan, &out_pages, uodata,
406 : : outlen, &offs, &need_drop);
407 [ # # ]: 0 : if (n < 0) {
408 : 0 : err = n;
409 : 0 : goto err_out;
410 : : }
411 : 0 : out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
412 [ # # ]: 0 : if (n != outlen) {
413 : 0 : __le32 v = cpu_to_le32(n);
414 : 0 : memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4);
415 : 0 : outlen = n;
416 : : }
417 : : /* The size field of the message must include the length of the
418 : : * header and the length of the data. We didn't actually know
419 : : * the length of the data until this point so add it in now.
420 : : */
421 : 0 : sz = cpu_to_le32(req->tc.size + outlen);
422 : 0 : memcpy(&req->tc.sdata[0], &sz, sizeof(sz));
423 [ # # ]: 0 : } else if (uidata) {
424 : 0 : int n = p9_get_mapped_pages(chan, &in_pages, uidata,
425 : : inlen, &offs, &need_drop);
426 [ # # ]: 0 : if (n < 0) {
427 : 0 : err = n;
428 : 0 : goto err_out;
429 : : }
430 : 0 : in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
431 [ # # ]: 0 : if (n != inlen) {
432 : 0 : __le32 v = cpu_to_le32(n);
433 : 0 : memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4);
434 : 0 : inlen = n;
435 : : }
436 : : }
437 : 0 : req->status = REQ_STATUS_SENT;
438 : 0 : req_retry_pinned:
439 : 0 : spin_lock_irqsave(&chan->lock, flags);
440 : :
441 : 0 : out_sgs = in_sgs = 0;
442 : :
443 : : /* out data */
444 : 0 : out = pack_sg_list(chan->sg, 0,
445 : 0 : VIRTQUEUE_NUM, req->tc.sdata, req->tc.size);
446 : :
447 [ # # ]: 0 : if (out)
448 : 0 : sgs[out_sgs++] = chan->sg;
449 : :
450 [ # # ]: 0 : if (out_pages) {
451 : 0 : sgs[out_sgs++] = chan->sg + out;
452 : 0 : out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
453 : : out_pages, out_nr_pages, offs, outlen);
454 : : }
455 : :
456 : : /*
457 : : * Take care of in data
458 : : * For example TREAD have 11.
459 : : * 11 is the read/write header = PDU Header(7) + IO Size (4).
460 : : * Arrange in such a way that server places header in the
461 : : * alloced memory and payload onto the user buffer.
462 : : */
463 : 0 : in = pack_sg_list(chan->sg, out,
464 : 0 : VIRTQUEUE_NUM, req->rc.sdata, in_hdr_len);
465 [ # # ]: 0 : if (in)
466 : 0 : sgs[out_sgs + in_sgs++] = chan->sg + out;
467 : :
468 [ # # ]: 0 : if (in_pages) {
469 : 0 : sgs[out_sgs + in_sgs++] = chan->sg + out + in;
470 : 0 : in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
471 : : in_pages, in_nr_pages, offs, inlen);
472 : : }
473 : :
474 : 0 : BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs));
475 : 0 : err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req,
476 : : GFP_ATOMIC);
477 [ # # ]: 0 : if (err < 0) {
478 [ # # ]: 0 : if (err == -ENOSPC) {
479 : 0 : chan->ring_bufs_avail = 0;
480 : 0 : spin_unlock_irqrestore(&chan->lock, flags);
481 [ # # # # : 0 : err = wait_event_killable(*chan->vc_wq,
# # ]
482 : : chan->ring_bufs_avail);
483 [ # # ]: 0 : if (err == -ERESTARTSYS)
484 : 0 : goto err_out;
485 : :
486 : 0 : p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
487 : 0 : goto req_retry_pinned;
488 : : } else {
489 : 0 : spin_unlock_irqrestore(&chan->lock, flags);
490 : 0 : p9_debug(P9_DEBUG_TRANS,
491 : : "virtio rpc add_sgs returned failure\n");
492 : 0 : err = -EIO;
493 : 0 : goto err_out;
494 : : }
495 : : }
496 : 0 : virtqueue_kick(chan->vq);
497 : 0 : spin_unlock_irqrestore(&chan->lock, flags);
498 : 0 : kicked = 1;
499 : 0 : p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
500 [ # # # # : 0 : err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
# # ]
501 : : /*
502 : : * Non kernel buffers are pinned, unpin them
503 : : */
504 : 0 : err_out:
505 [ # # ]: 0 : if (need_drop) {
506 [ # # ]: 0 : if (in_pages) {
507 : 0 : p9_release_pages(in_pages, in_nr_pages);
508 : 0 : atomic_sub(in_nr_pages, &vp_pinned);
509 : : }
510 [ # # ]: 0 : if (out_pages) {
511 : 0 : p9_release_pages(out_pages, out_nr_pages);
512 : 0 : atomic_sub(out_nr_pages, &vp_pinned);
513 : : }
514 : : /* wakeup anybody waiting for slots to pin pages */
515 : 0 : wake_up(&vp_wq);
516 : : }
517 : 0 : kvfree(in_pages);
518 : 0 : kvfree(out_pages);
519 [ # # ]: 0 : if (!kicked) {
520 : : /* reply won't come */
521 : 0 : p9_req_put(req);
522 : : }
523 : 0 : return err;
524 : : }
525 : :
526 : 0 : static ssize_t p9_mount_tag_show(struct device *dev,
527 : : struct device_attribute *attr, char *buf)
528 : : {
529 : 0 : struct virtio_chan *chan;
530 : 0 : struct virtio_device *vdev;
531 : 0 : int tag_len;
532 : :
533 : 0 : vdev = dev_to_virtio(dev);
534 : 0 : chan = vdev->priv;
535 : 0 : tag_len = strlen(chan->tag);
536 : :
537 : 0 : memcpy(buf, chan->tag, tag_len + 1);
538 : :
539 : 0 : return tag_len + 1;
540 : : }
541 : :
542 : : static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL);
543 : :
544 : : /**
545 : : * p9_virtio_probe - probe for existence of 9P virtio channels
546 : : * @vdev: virtio device to probe
547 : : *
548 : : * This probes for existing virtio channels.
549 : : *
550 : : */
551 : :
552 : 0 : static int p9_virtio_probe(struct virtio_device *vdev)
553 : : {
554 : 0 : __u16 tag_len;
555 : 0 : char *tag;
556 : 0 : int err;
557 : 0 : struct virtio_chan *chan;
558 : :
559 [ # # ]: 0 : if (!vdev->config->get) {
560 : 0 : dev_err(&vdev->dev, "%s failure: config access disabled\n",
561 : : __func__);
562 : 0 : return -EINVAL;
563 : : }
564 : :
565 : 0 : chan = kmalloc(sizeof(struct virtio_chan), GFP_KERNEL);
566 [ # # ]: 0 : if (!chan) {
567 : 0 : pr_err("Failed to allocate virtio 9P channel\n");
568 : 0 : err = -ENOMEM;
569 : 0 : goto fail;
570 : : }
571 : :
572 : 0 : chan->vdev = vdev;
573 : :
574 : : /* We expect one virtqueue, for requests. */
575 : 0 : chan->vq = virtio_find_single_vq(vdev, req_done, "requests");
576 [ # # ]: 0 : if (IS_ERR(chan->vq)) {
577 : 0 : err = PTR_ERR(chan->vq);
578 : 0 : goto out_free_chan;
579 : : }
580 : 0 : chan->vq->vdev->priv = chan;
581 : 0 : spin_lock_init(&chan->lock);
582 : :
583 : 0 : sg_init_table(chan->sg, VIRTQUEUE_NUM);
584 : :
585 : 0 : chan->inuse = false;
586 [ # # ]: 0 : if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
587 : 0 : virtio_cread(vdev, struct virtio_9p_config, tag_len, &tag_len);
588 : : } else {
589 : 0 : err = -EINVAL;
590 : 0 : goto out_free_vq;
591 : : }
592 : 0 : tag = kzalloc(tag_len + 1, GFP_KERNEL);
593 [ # # ]: 0 : if (!tag) {
594 : 0 : err = -ENOMEM;
595 : 0 : goto out_free_vq;
596 : : }
597 : :
598 : 0 : virtio_cread_bytes(vdev, offsetof(struct virtio_9p_config, tag),
599 : : tag, tag_len);
600 : 0 : chan->tag = tag;
601 : 0 : err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
602 [ # # ]: 0 : if (err) {
603 : 0 : goto out_free_tag;
604 : : }
605 : 0 : chan->vc_wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
606 [ # # ]: 0 : if (!chan->vc_wq) {
607 : 0 : err = -ENOMEM;
608 : 0 : goto out_free_tag;
609 : : }
610 : 0 : init_waitqueue_head(chan->vc_wq);
611 : 0 : chan->ring_bufs_avail = 1;
612 : : /* Ceiling limit to avoid denial of service attacks */
613 : 0 : chan->p9_max_pages = nr_free_buffer_pages()/4;
614 : :
615 : 0 : virtio_device_ready(vdev);
616 : :
617 : 0 : mutex_lock(&virtio_9p_lock);
618 : 0 : list_add_tail(&chan->chan_list, &virtio_chan_list);
619 : 0 : mutex_unlock(&virtio_9p_lock);
620 : :
621 : : /* Let udev rules use the new mount_tag attribute. */
622 : 0 : kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE);
623 : :
624 : 0 : return 0;
625 : :
626 : 0 : out_free_tag:
627 : 0 : kfree(tag);
628 : 0 : out_free_vq:
629 : 0 : vdev->config->del_vqs(vdev);
630 : 0 : out_free_chan:
631 : 0 : kfree(chan);
632 : : fail:
633 : : return err;
634 : : }
635 : :
636 : :
637 : : /**
638 : : * p9_virtio_create - allocate a new virtio channel
639 : : * @client: client instance invoking this transport
640 : : * @devname: string identifying the channel to connect to (unused)
641 : : * @args: args passed from sys_mount() for per-transport options (unused)
642 : : *
643 : : * This sets up a transport channel for 9p communication. Right now
644 : : * we only match the first available channel, but eventually we couldlook up
645 : : * alternate channels by matching devname versus a virtio_config entry.
646 : : * We use a simple reference count mechanism to ensure that only a single
647 : : * mount has a channel open at a time.
648 : : *
649 : : */
650 : :
651 : : static int
652 : 0 : p9_virtio_create(struct p9_client *client, const char *devname, char *args)
653 : : {
654 : 0 : struct virtio_chan *chan;
655 : 0 : int ret = -ENOENT;
656 : 0 : int found = 0;
657 : :
658 [ # # ]: 0 : if (devname == NULL)
659 : : return -EINVAL;
660 : :
661 : 0 : mutex_lock(&virtio_9p_lock);
662 [ # # ]: 0 : list_for_each_entry(chan, &virtio_chan_list, chan_list) {
663 [ # # ]: 0 : if (!strcmp(devname, chan->tag)) {
664 [ # # ]: 0 : if (!chan->inuse) {
665 : 0 : chan->inuse = true;
666 : 0 : found = 1;
667 : 0 : break;
668 : : }
669 : : ret = -EBUSY;
670 : : }
671 : : }
672 : 0 : mutex_unlock(&virtio_9p_lock);
673 : :
674 [ # # ]: 0 : if (!found) {
675 : 0 : pr_err("no channels available for device %s\n", devname);
676 : 0 : return ret;
677 : : }
678 : :
679 : 0 : client->trans = (void *)chan;
680 : 0 : client->status = Connected;
681 : 0 : chan->client = client;
682 : :
683 : 0 : return 0;
684 : : }
685 : :
686 : : /**
687 : : * p9_virtio_remove - clean up resources associated with a virtio device
688 : : * @vdev: virtio device to remove
689 : : *
690 : : */
691 : :
692 : 0 : static void p9_virtio_remove(struct virtio_device *vdev)
693 : : {
694 : 0 : struct virtio_chan *chan = vdev->priv;
695 : 0 : unsigned long warning_time;
696 : :
697 : 0 : mutex_lock(&virtio_9p_lock);
698 : :
699 : : /* Remove self from list so we don't get new users. */
700 : 0 : list_del(&chan->chan_list);
701 : 0 : warning_time = jiffies;
702 : :
703 : : /* Wait for existing users to close. */
704 [ # # ]: 0 : while (chan->inuse) {
705 : 0 : mutex_unlock(&virtio_9p_lock);
706 : 0 : msleep(250);
707 [ # # ]: 0 : if (time_after(jiffies, warning_time + 10 * HZ)) {
708 : 0 : dev_emerg(&vdev->dev,
709 : : "p9_virtio_remove: waiting for device in use.\n");
710 : 0 : warning_time = jiffies;
711 : : }
712 : 0 : mutex_lock(&virtio_9p_lock);
713 : : }
714 : :
715 : 0 : mutex_unlock(&virtio_9p_lock);
716 : :
717 : 0 : vdev->config->reset(vdev);
718 : 0 : vdev->config->del_vqs(vdev);
719 : :
720 : 0 : sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
721 : 0 : kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE);
722 : 0 : kfree(chan->tag);
723 : 0 : kfree(chan->vc_wq);
724 : 0 : kfree(chan);
725 : :
726 : 0 : }
727 : :
728 : : static struct virtio_device_id id_table[] = {
729 : : { VIRTIO_ID_9P, VIRTIO_DEV_ANY_ID },
730 : : { 0 },
731 : : };
732 : :
733 : : static unsigned int features[] = {
734 : : VIRTIO_9P_MOUNT_TAG,
735 : : };
736 : :
737 : : /* The standard "struct lguest_driver": */
738 : : static struct virtio_driver p9_virtio_drv = {
739 : : .feature_table = features,
740 : : .feature_table_size = ARRAY_SIZE(features),
741 : : .driver.name = KBUILD_MODNAME,
742 : : .driver.owner = THIS_MODULE,
743 : : .id_table = id_table,
744 : : .probe = p9_virtio_probe,
745 : : .remove = p9_virtio_remove,
746 : : };
747 : :
748 : : static struct p9_trans_module p9_virtio_trans = {
749 : : .name = "virtio",
750 : : .create = p9_virtio_create,
751 : : .close = p9_virtio_close,
752 : : .request = p9_virtio_request,
753 : : .zc_request = p9_virtio_zc_request,
754 : : .cancel = p9_virtio_cancel,
755 : : .cancelled = p9_virtio_cancelled,
756 : : /*
757 : : * We leave one entry for input and one entry for response
758 : : * headers. We also skip one more entry to accomodate, address
759 : : * that are not at page boundary, that can result in an extra
760 : : * page in zero copy.
761 : : */
762 : : .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3),
763 : : .def = 1,
764 : : .owner = THIS_MODULE,
765 : : };
766 : :
767 : : /* The standard init function */
768 : 28 : static int __init p9_virtio_init(void)
769 : : {
770 : 28 : int rc;
771 : :
772 : 28 : INIT_LIST_HEAD(&virtio_chan_list);
773 : :
774 : 28 : v9fs_register_trans(&p9_virtio_trans);
775 : 28 : rc = register_virtio_driver(&p9_virtio_drv);
776 [ - + ]: 28 : if (rc)
777 : 0 : v9fs_unregister_trans(&p9_virtio_trans);
778 : :
779 : 28 : return rc;
780 : : }
781 : :
782 : 0 : static void __exit p9_virtio_cleanup(void)
783 : : {
784 : 0 : unregister_virtio_driver(&p9_virtio_drv);
785 : 0 : v9fs_unregister_trans(&p9_virtio_trans);
786 : 0 : }
787 : :
788 : : module_init(p9_virtio_init);
789 : : module_exit(p9_virtio_cleanup);
790 : :
791 : : MODULE_DEVICE_TABLE(virtio, id_table);
792 : : MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
793 : : MODULE_DESCRIPTION("Virtio 9p Transport");
794 : : MODULE_LICENSE("GPL");
|