LCOV - code coverage report
Current view: top level - net/9p - trans_virtio.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 7 339 2.1 %
Date: 2021-04-22 12:43:58 Functions: 1 15 6.7 %

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

Generated by: LCOV version 1.14