~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/driver-api/virtio/writing_virtio_drivers.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 .. SPDX-License-Identifier: GPL-2.0
  2 
  3 .. _writing_virtio_drivers:
  4 
  5 ======================
  6 Writing Virtio Drivers
  7 ======================
  8 
  9 Introduction
 10 ============
 11 
 12 This document serves as a basic guideline for driver programmers that
 13 need to hack a new virtio driver or understand the essentials of the
 14 existing ones. See :ref:`Virtio on Linux <virtio>` for a general
 15 overview of virtio.
 16 
 17 
 18 Driver boilerplate
 19 ==================
 20 
 21 As a bare minimum, a virtio driver needs to register in the virtio bus
 22 and configure the virtqueues for the device according to its spec, the
 23 configuration of the virtqueues in the driver side must match the
 24 virtqueue definitions in the device. A basic driver skeleton could look
 25 like this::
 26 
 27         #include <linux/virtio.h>
 28         #include <linux/virtio_ids.h>
 29         #include <linux/virtio_config.h>
 30         #include <linux/module.h>
 31 
 32         /* device private data (one per device) */
 33         struct virtio_dummy_dev {
 34                 struct virtqueue *vq;
 35         };
 36 
 37         static void virtio_dummy_recv_cb(struct virtqueue *vq)
 38         {
 39                 struct virtio_dummy_dev *dev = vq->vdev->priv;
 40                 char *buf;
 41                 unsigned int len;
 42 
 43                 while ((buf = virtqueue_get_buf(dev->vq, &len)) != NULL) {
 44                         /* process the received data */
 45                 }
 46         }
 47 
 48         static int virtio_dummy_probe(struct virtio_device *vdev)
 49         {
 50                 struct virtio_dummy_dev *dev = NULL;
 51 
 52                 /* initialize device data */
 53                 dev = kzalloc(sizeof(struct virtio_dummy_dev), GFP_KERNEL);
 54                 if (!dev)
 55                         return -ENOMEM;
 56 
 57                 /* the device has a single virtqueue */
 58                 dev->vq = virtio_find_single_vq(vdev, virtio_dummy_recv_cb, "input");
 59                 if (IS_ERR(dev->vq)) {
 60                         kfree(dev);
 61                         return PTR_ERR(dev->vq);
 62 
 63                 }
 64                 vdev->priv = dev;
 65 
 66                 /* from this point on, the device can notify and get callbacks */
 67                 virtio_device_ready(vdev);
 68 
 69                 return 0;
 70         }
 71 
 72         static void virtio_dummy_remove(struct virtio_device *vdev)
 73         {
 74                 struct virtio_dummy_dev *dev = vdev->priv;
 75 
 76                 /*
 77                  * disable vq interrupts: equivalent to
 78                  * vdev->config->reset(vdev)
 79                  */
 80                 virtio_reset_device(vdev);
 81 
 82                 /* detach unused buffers */
 83                 while ((buf = virtqueue_detach_unused_buf(dev->vq)) != NULL) {
 84                         kfree(buf);
 85                 }
 86 
 87                 /* remove virtqueues */
 88                 vdev->config->del_vqs(vdev);
 89 
 90                 kfree(dev);
 91         }
 92 
 93         static const struct virtio_device_id id_table[] = {
 94                 { VIRTIO_ID_DUMMY, VIRTIO_DEV_ANY_ID },
 95                 { 0 },
 96         };
 97 
 98         static struct virtio_driver virtio_dummy_driver = {
 99                 .driver.name =  KBUILD_MODNAME,
100                 .id_table =     id_table,
101                 .probe =        virtio_dummy_probe,
102                 .remove =       virtio_dummy_remove,
103         };
104 
105         module_virtio_driver(virtio_dummy_driver);
106         MODULE_DEVICE_TABLE(virtio, id_table);
107         MODULE_DESCRIPTION("Dummy virtio driver");
108         MODULE_LICENSE("GPL");
109 
110 The device id ``VIRTIO_ID_DUMMY`` here is a placeholder, virtio drivers
111 should be added only for devices that are defined in the spec, see
112 include/uapi/linux/virtio_ids.h. Device ids need to be at least reserved
113 in the virtio spec before being added to that file.
114 
115 If your driver doesn't have to do anything special in its ``init`` and
116 ``exit`` methods, you can use the module_virtio_driver() helper to
117 reduce the amount of boilerplate code.
118 
119 The ``probe`` method does the minimum driver setup in this case
120 (memory allocation for the device data) and initializes the
121 virtqueue. virtio_device_ready() is used to enable the virtqueue and to
122 notify the device that the driver is ready to manage the device
123 ("DRIVER_OK"). The virtqueues are anyway enabled automatically by the
124 core after ``probe`` returns.
125 
126 .. kernel-doc:: include/linux/virtio_config.h
127     :identifiers: virtio_device_ready
128 
129 In any case, the virtqueues need to be enabled before adding buffers to
130 them.
131 
132 Sending and receiving data
133 ==========================
134 
135 The virtio_dummy_recv_cb() callback in the code above will be triggered
136 when the device notifies the driver after it finishes processing a
137 descriptor or descriptor chain, either for reading or writing. However,
138 that's only the second half of the virtio device-driver communication
139 process, as the communication is always started by the driver regardless
140 of the direction of the data transfer.
141 
142 To configure a buffer transfer from the driver to the device, first you
143 have to add the buffers -- packed as `scatterlists` -- to the
144 appropriate virtqueue using any of the virtqueue_add_inbuf(),
145 virtqueue_add_outbuf() or virtqueue_add_sgs(), depending on whether you
146 need to add one input `scatterlist` (for the device to fill in), one
147 output `scatterlist` (for the device to consume) or multiple
148 `scatterlists`, respectively. Then, once the virtqueue is set up, a call
149 to virtqueue_kick() sends a notification that will be serviced by the
150 hypervisor that implements the device::
151 
152         struct scatterlist sg[1];
153         sg_init_one(sg, buffer, BUFLEN);
154         virtqueue_add_inbuf(dev->vq, sg, 1, buffer, GFP_ATOMIC);
155         virtqueue_kick(dev->vq);
156 
157 .. kernel-doc:: drivers/virtio/virtio_ring.c
158     :identifiers: virtqueue_add_inbuf
159 
160 .. kernel-doc:: drivers/virtio/virtio_ring.c
161     :identifiers: virtqueue_add_outbuf
162 
163 .. kernel-doc:: drivers/virtio/virtio_ring.c
164     :identifiers: virtqueue_add_sgs
165 
166 Then, after the device has read or written the buffers prepared by the
167 driver and notifies it back, the driver can call virtqueue_get_buf() to
168 read the data produced by the device (if the virtqueue was set up with
169 input buffers) or simply to reclaim the buffers if they were already
170 consumed by the device:
171 
172 .. kernel-doc:: drivers/virtio/virtio_ring.c
173     :identifiers: virtqueue_get_buf_ctx
174 
175 The virtqueue callbacks can be disabled and re-enabled using the
176 virtqueue_disable_cb() and the family of virtqueue_enable_cb() functions
177 respectively. See drivers/virtio/virtio_ring.c for more details:
178 
179 .. kernel-doc:: drivers/virtio/virtio_ring.c
180     :identifiers: virtqueue_disable_cb
181 
182 .. kernel-doc:: drivers/virtio/virtio_ring.c
183     :identifiers: virtqueue_enable_cb
184 
185 But note that some spurious callbacks can still be triggered under
186 certain scenarios. The way to disable callbacks reliably is to reset the
187 device or the virtqueue (virtio_reset_device()).
188 
189 
190 References
191 ==========
192 
193 _`[1]` Virtio Spec v1.2:
194 https://docs.oasis-open.org/virtio/virtio/v1.2/virtio-v1.2.html
195 
196 Check for later versions of the spec as well.

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php