aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-02-04 23:49:56 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-02-04 07:49:57 -0500
commita586d4f6016f7139d8c26df0e6927131168d3b5b (patch)
tree1c47e1a6b6b8fb18baa42f32980f29c4ae9cbbdc
parentf35d9d8aae08940b7fdd1bb8110619da2ece6b28 (diff)
virtio: simplify config mechanism.
Previously we used a type/len pair within the config space, but this seems overkill. We now simply define a structure which represents the layout in the config space: the config space can now only be extended at the end. The main driver-visible changes: 1) We indicate what fields are present with an explicit feature bit. 2) Virtqueues are explicitly numbered, and not in the config space. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--Documentation/lguest/lguest.c176
-rw-r--r--drivers/block/virtio_blk.c35
-rw-r--r--drivers/char/virtio_console.c4
-rw-r--r--drivers/lguest/lguest_device.c132
-rw-r--r--drivers/net/virtio_net.c25
-rw-r--r--drivers/virtio/virtio.c45
-rw-r--r--include/linux/lguest_launcher.h9
-rw-r--r--include/linux/virtio_blk.h22
-rw-r--r--include/linux/virtio_config.h98
-rw-r--r--include/linux/virtio_net.h11
-rw-r--r--net/9p/trans_virtio.c4
11 files changed, 280 insertions, 281 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 6c8a2386cd5..4df1804169d 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -34,6 +34,8 @@
34#include <zlib.h> 34#include <zlib.h>
35#include <assert.h> 35#include <assert.h>
36#include <sched.h> 36#include <sched.h>
37#include <limits.h>
38#include <stddef.h>
37#include "linux/lguest_launcher.h" 39#include "linux/lguest_launcher.h"
38#include "linux/virtio_config.h" 40#include "linux/virtio_config.h"
39#include "linux/virtio_net.h" 41#include "linux/virtio_net.h"
@@ -99,13 +101,11 @@ struct device_list
99 /* The descriptor page for the devices. */ 101 /* The descriptor page for the devices. */
100 u8 *descpage; 102 u8 *descpage;
101 103
102 /* The tail of the last descriptor. */
103 unsigned int desc_used;
104
105 /* A single linked list of devices. */ 104 /* A single linked list of devices. */
106 struct device *dev; 105 struct device *dev;
107 /* ... And an end pointer so we can easily append new devices */ 106 /* And a pointer to the last device for easy append and also for
108 struct device **lastdev; 107 * configuration appending. */
108 struct device *lastdev;
109}; 109};
110 110
111/* The list of Guest devices, based on command line arguments. */ 111/* The list of Guest devices, based on command line arguments. */
@@ -191,7 +191,7 @@ static void *_convert(struct iovec *iov, size_t size, size_t align,
191#define cpu_to_le64(v64) (v64) 191#define cpu_to_le64(v64) (v64)
192#define le16_to_cpu(v16) (v16) 192#define le16_to_cpu(v16) (v16)
193#define le32_to_cpu(v32) (v32) 193#define le32_to_cpu(v32) (v32)
194#define le64_to_cpu(v32) (v64) 194#define le64_to_cpu(v64) (v64)
195 195
196/*L:100 The Launcher code itself takes us out into userspace, that scary place 196/*L:100 The Launcher code itself takes us out into userspace, that scary place
197 * where pointers run wild and free! Unfortunately, like most userspace 197 * where pointers run wild and free! Unfortunately, like most userspace
@@ -986,54 +986,44 @@ static void handle_input(int fd)
986 * 986 *
987 * All devices need a descriptor so the Guest knows it exists, and a "struct 987 * All devices need a descriptor so the Guest knows it exists, and a "struct
988 * device" so the Launcher can keep track of it. We have common helper 988 * device" so the Launcher can keep track of it. We have common helper
989 * routines to allocate them. 989 * routines to allocate and manage them. */
990 *
991 * This routine allocates a new "struct lguest_device_desc" from descriptor
992 * table just above the Guest's normal memory. It returns a pointer to that
993 * descriptor. */
994static struct lguest_device_desc *new_dev_desc(u16 type)
995{
996 struct lguest_device_desc *d;
997 990
998 /* We only have one page for all the descriptors. */ 991/* The layout of the device page is a "struct lguest_device_desc" followed by a
999 if (devices.desc_used + sizeof(*d) > getpagesize()) 992 * number of virtqueue descriptors, then two sets of feature bits, then an
1000 errx(1, "Too many devices"); 993 * array of configuration bytes. This routine returns the configuration
1001 994 * pointer. */
1002 /* We don't need to set config_len or status: page is 0 already. */ 995static u8 *device_config(const struct device *dev)
1003 d = (void *)devices.descpage + devices.desc_used; 996{
1004 d->type = type; 997 return (void *)(dev->desc + 1)
1005 devices.desc_used += sizeof(*d); 998 + dev->desc->num_vq * sizeof(struct lguest_vqconfig)
1006 999 + dev->desc->feature_len * 2;
1007 return d;
1008} 1000}
1009 1001
1010/* Each device descriptor is followed by some configuration information. 1002/* This routine allocates a new "struct lguest_device_desc" from descriptor
1011 * Each configuration field looks like: u8 type, u8 len, [... len bytes...]. 1003 * table page just above the Guest's normal memory. It returns a pointer to
1012 * 1004 * that descriptor. */
1013 * This routine adds a new field to an existing device's descriptor. It only 1005static struct lguest_device_desc *new_dev_desc(u16 type)
1014 * works for the last device, but that's OK because that's how we use it. */
1015static void add_desc_field(struct device *dev, u8 type, u8 len, const void *c)
1016{ 1006{
1017 /* This is the last descriptor, right? */ 1007 struct lguest_device_desc d = { .type = type };
1018 assert(devices.descpage + devices.desc_used 1008 void *p;
1019 == (u8 *)(dev->desc + 1) + dev->desc->config_len);
1020 1009
1021 /* We only have one page of device descriptions. */ 1010 /* Figure out where the next device config is, based on the last one. */
1022 if (devices.desc_used + 2 + len > getpagesize()) 1011 if (devices.lastdev)
1023 errx(1, "Too many devices"); 1012 p = device_config(devices.lastdev)
1013 + devices.lastdev->desc->config_len;
1014 else
1015 p = devices.descpage;
1024 1016
1025 /* Copy in the new config header: type then length. */ 1017 /* We only have one page for all the descriptors. */
1026 devices.descpage[devices.desc_used++] = type; 1018 if (p + sizeof(d) > (void *)devices.descpage + getpagesize())
1027 devices.descpage[devices.desc_used++] = len; 1019 errx(1, "Too many devices");
1028 memcpy(devices.descpage + devices.desc_used, c, len);
1029 devices.desc_used += len;
1030 1020
1031 /* Update the device descriptor length: two byte head then data. */ 1021 /* p might not be aligned, so we memcpy in. */
1032 dev->desc->config_len += 2 + len; 1022 return memcpy(p, &d, sizeof(d));
1033} 1023}
1034 1024
1035/* This routine adds a virtqueue to a device. We specify how many descriptors 1025/* Each device descriptor is followed by the description of its virtqueues. We
1036 * the virtqueue is to have. */ 1026 * specify how many descriptors the virtqueue is to have. */
1037static void add_virtqueue(struct device *dev, unsigned int num_descs, 1027static void add_virtqueue(struct device *dev, unsigned int num_descs,
1038 void (*handle_output)(int fd, struct virtqueue *me)) 1028 void (*handle_output)(int fd, struct virtqueue *me))
1039{ 1029{
@@ -1059,9 +1049,15 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
1059 /* Initialize the vring. */ 1049 /* Initialize the vring. */
1060 vring_init(&vq->vring, num_descs, p, getpagesize()); 1050 vring_init(&vq->vring, num_descs, p, getpagesize());
1061 1051
1062 /* Add the configuration information to this device's descriptor. */ 1052 /* Append virtqueue to this device's descriptor. We use
1063 add_desc_field(dev, VIRTIO_CONFIG_F_VIRTQUEUE, 1053 * device_config() to get the end of the device's current virtqueues;
1064 sizeof(vq->config), &vq->config); 1054 * we check that we haven't added any config or feature information
1055 * yet, otherwise we'd be overwriting them. */
1056 assert(dev->desc->config_len == 0 && dev->desc->feature_len == 0);
1057 memcpy(device_config(dev), &vq->config, sizeof(vq->config));
1058 dev->desc->num_vq++;
1059
1060 verbose("Virtqueue page %#lx\n", to_guest_phys(p));
1065 1061
1066 /* Add to tail of list, so dev->vq is first vq, dev->vq->next is 1062 /* Add to tail of list, so dev->vq is first vq, dev->vq->next is
1067 * second. */ 1063 * second. */
@@ -1077,6 +1073,37 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
1077 vq->vring.used->flags = VRING_USED_F_NO_NOTIFY; 1073 vq->vring.used->flags = VRING_USED_F_NO_NOTIFY;
1078} 1074}
1079 1075
1076/* The virtqueue descriptors are followed by feature bytes. */
1077static void add_feature(struct device *dev, unsigned bit)
1078{
1079 u8 *features;
1080
1081 /* We can't extend the feature bits once we've added config bytes */
1082 if (dev->desc->feature_len <= bit / CHAR_BIT) {
1083 assert(dev->desc->config_len == 0);
1084 dev->desc->feature_len = (bit / CHAR_BIT) + 1;
1085 }
1086
1087 features = (u8 *)(dev->desc + 1)
1088 + dev->desc->num_vq * sizeof(struct lguest_vqconfig);
1089
1090 features[bit / CHAR_BIT] |= (1 << (bit % CHAR_BIT));
1091}
1092
1093/* This routine sets the configuration fields for an existing device's
1094 * descriptor. It only works for the last device, but that's OK because that's
1095 * how we use it. */
1096static void set_config(struct device *dev, unsigned len, const void *conf)
1097{
1098 /* Check we haven't overflowed our single page. */
1099 if (device_config(dev) + len > devices.descpage + getpagesize())
1100 errx(1, "Too many devices");
1101
1102 /* Copy in the config information, and store the length. */
1103 memcpy(device_config(dev), conf, len);
1104 dev->desc->config_len = len;
1105}
1106
1080/* This routine does all the creation and setup of a new device, including 1107/* This routine does all the creation and setup of a new device, including
1081 * calling new_dev_desc() to allocate the descriptor and device memory. */ 1108 * calling new_dev_desc() to allocate the descriptor and device memory. */
1082static struct device *new_device(const char *name, u16 type, int fd, 1109static struct device *new_device(const char *name, u16 type, int fd,
@@ -1084,14 +1111,6 @@ static struct device *new_device(const char *name, u16 type, int fd,
1084{ 1111{
1085 struct device *dev = malloc(sizeof(*dev)); 1112 struct device *dev = malloc(sizeof(*dev));
1086 1113
1087 /* Append to device list. Prepending to a single-linked list is
1088 * easier, but the user expects the devices to be arranged on the bus
1089 * in command-line order. The first network device on the command line
1090 * is eth0, the first block device /dev/vda, etc. */
1091 *devices.lastdev = dev;
1092 dev->next = NULL;
1093 devices.lastdev = &dev->next;
1094
1095 /* Now we populate the fields one at a time. */ 1114 /* Now we populate the fields one at a time. */
1096 dev->fd = fd; 1115 dev->fd = fd;
1097 /* If we have an input handler for this file descriptor, then we add it 1116 /* If we have an input handler for this file descriptor, then we add it
@@ -1102,6 +1121,17 @@ static struct device *new_device(const char *name, u16 type, int fd,
1102 dev->handle_input = handle_input; 1121 dev->handle_input = handle_input;
1103 dev->name = name; 1122 dev->name = name;
1104 dev->vq = NULL; 1123 dev->vq = NULL;
1124
1125 /* Append to device list. Prepending to a single-linked list is
1126 * easier, but the user expects the devices to be arranged on the bus
1127 * in command-line order. The first network device on the command line
1128 * is eth0, the first block device /dev/vda, etc. */
1129 if (devices.lastdev)
1130 devices.lastdev->next = dev;
1131 else
1132 devices.dev = dev;
1133 devices.lastdev = dev;
1134
1105 return dev; 1135 return dev;
1106} 1136}
1107 1137
@@ -1226,7 +1256,7 @@ static void setup_tun_net(const char *arg)
1226 int netfd, ipfd; 1256 int netfd, ipfd;
1227 u32 ip; 1257 u32 ip;
1228 const char *br_name = NULL; 1258 const char *br_name = NULL;
1229 u8 hwaddr[6]; 1259 struct virtio_net_config conf;
1230 1260
1231 /* We open the /dev/net/tun device and tell it we want a tap device. A 1261 /* We open the /dev/net/tun device and tell it we want a tap device. A
1232 * tap device is like a tun device, only somehow different. To tell 1262 * tap device is like a tun device, only somehow different. To tell
@@ -1265,12 +1295,13 @@ static void setup_tun_net(const char *arg)
1265 ip = str2ip(arg); 1295 ip = str2ip(arg);
1266 1296
1267 /* Set up the tun device, and get the mac address for the interface. */ 1297 /* Set up the tun device, and get the mac address for the interface. */
1268 configure_device(ipfd, ifr.ifr_name, ip, hwaddr); 1298 configure_device(ipfd, ifr.ifr_name, ip, conf.mac);
1269 1299
1270 /* Tell Guest what MAC address to use. */ 1300 /* Tell Guest what MAC address to use. */
1271 add_desc_field(dev, VIRTIO_CONFIG_NET_MAC_F, sizeof(hwaddr), hwaddr); 1301 add_feature(dev, VIRTIO_NET_F_MAC);
1302 set_config(dev, sizeof(conf), &conf);
1272 1303
1273 /* We don't seed the socket any more; setup is done. */ 1304 /* We don't need the socket any more; setup is done. */
1274 close(ipfd); 1305 close(ipfd);
1275 1306
1276 verbose("device %u: tun net %u.%u.%u.%u\n", 1307 verbose("device %u: tun net %u.%u.%u.%u\n",
@@ -1458,8 +1489,7 @@ static void setup_block_file(const char *filename)
1458 struct device *dev; 1489 struct device *dev;
1459 struct vblk_info *vblk; 1490 struct vblk_info *vblk;
1460 void *stack; 1491 void *stack;
1461 u64 cap; 1492 struct virtio_blk_config conf;
1462 unsigned int val;
1463 1493
1464 /* This is the pipe the I/O thread will use to tell us I/O is done. */ 1494 /* This is the pipe the I/O thread will use to tell us I/O is done. */
1465 pipe(p); 1495 pipe(p);
@@ -1477,14 +1507,18 @@ static void setup_block_file(const char *filename)
1477 vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE); 1507 vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE);
1478 vblk->len = lseek64(vblk->fd, 0, SEEK_END); 1508 vblk->len = lseek64(vblk->fd, 0, SEEK_END);
1479 1509
1510 /* We support barriers. */
1511 add_feature(dev, VIRTIO_BLK_F_BARRIER);
1512
1480 /* Tell Guest how many sectors this device has. */ 1513 /* Tell Guest how many sectors this device has. */
1481 cap = cpu_to_le64(vblk->len / 512); 1514 conf.capacity = cpu_to_le64(vblk->len / 512);
1482 add_desc_field(dev, VIRTIO_CONFIG_BLK_F_CAPACITY, sizeof(cap), &cap);
1483 1515
1484 /* Tell Guest not to put in too many descriptors at once: two are used 1516 /* Tell Guest not to put in too many descriptors at once: two are used
1485 * for the in and out elements. */ 1517 * for the in and out elements. */
1486 val = cpu_to_le32(VIRTQUEUE_NUM - 2); 1518 add_feature(dev, VIRTIO_BLK_F_SEG_MAX);
1487 add_desc_field(dev, VIRTIO_CONFIG_BLK_F_SEG_MAX, sizeof(val), &val); 1519 conf.seg_max = cpu_to_le32(VIRTQUEUE_NUM - 2);
1520
1521 set_config(dev, sizeof(conf), &conf);
1488 1522
1489 /* The I/O thread writes to this end of the pipe when done. */ 1523 /* The I/O thread writes to this end of the pipe when done. */
1490 vblk->done_fd = p[1]; 1524 vblk->done_fd = p[1];
@@ -1505,7 +1539,7 @@ static void setup_block_file(const char *filename)
1505 close(vblk->workpipe[0]); 1539 close(vblk->workpipe[0]);
1506 1540
1507 verbose("device %u: virtblock %llu sectors\n", 1541 verbose("device %u: virtblock %llu sectors\n",
1508 devices.device_num, cap); 1542 devices.device_num, le64_to_cpu(conf.capacity));
1509} 1543}
1510/* That's the end of device setup. :*/ 1544/* That's the end of device setup. :*/
1511 1545
@@ -1610,12 +1644,12 @@ int main(int argc, char *argv[])
1610 /* First we initialize the device list. Since console and network 1644 /* First we initialize the device list. Since console and network
1611 * device receive input from a file descriptor, we keep an fdset 1645 * device receive input from a file descriptor, we keep an fdset
1612 * (infds) and the maximum fd number (max_infd) with the head of the 1646 * (infds) and the maximum fd number (max_infd) with the head of the
1613 * list. We also keep a pointer to the last device, for easy appending 1647 * list. We also keep a pointer to the last device. Finally, we keep
1614 * to the list. Finally, we keep the next interrupt number to hand out 1648 * the next interrupt number to hand out (1: remember that 0 is used by
1615 * (1: remember that 0 is used by the timer). */ 1649 * the timer). */
1616 FD_ZERO(&devices.infds); 1650 FD_ZERO(&devices.infds);
1617 devices.max_infd = -1; 1651 devices.max_infd = -1;
1618 devices.lastdev = &devices.dev; 1652 devices.lastdev = NULL;
1619 devices.next_irq = 1; 1653 devices.next_irq = 1;
1620 1654
1621 cpu_id = 0; 1655 cpu_id = 0;
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 924ddd8bccd..1c63d5b64c2 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -162,8 +162,6 @@ static int virtblk_probe(struct virtio_device *vdev)
162{ 162{
163 struct virtio_blk *vblk; 163 struct virtio_blk *vblk;
164 int err, major; 164 int err, major;
165 void *token;
166 unsigned int len;
167 u64 cap; 165 u64 cap;
168 u32 v; 166 u32 v;
169 167
@@ -178,7 +176,7 @@ static int virtblk_probe(struct virtio_device *vdev)
178 vblk->vdev = vdev; 176 vblk->vdev = vdev;
179 177
180 /* We expect one virtqueue, for output. */ 178 /* We expect one virtqueue, for output. */
181 vblk->vq = vdev->config->find_vq(vdev, blk_done); 179 vblk->vq = vdev->config->find_vq(vdev, 0, blk_done);
182 if (IS_ERR(vblk->vq)) { 180 if (IS_ERR(vblk->vq)) {
183 err = PTR_ERR(vblk->vq); 181 err = PTR_ERR(vblk->vq);
184 goto out_free_vblk; 182 goto out_free_vblk;
@@ -216,15 +214,12 @@ static int virtblk_probe(struct virtio_device *vdev)
216 vblk->disk->fops = &virtblk_fops; 214 vblk->disk->fops = &virtblk_fops;
217 215
218 /* If barriers are supported, tell block layer that queue is ordered */ 216 /* If barriers are supported, tell block layer that queue is ordered */
219 token = vdev->config->find(vdev, VIRTIO_CONFIG_BLK_F, &len); 217 if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER))
220 if (virtio_use_bit(vdev, token, len, VIRTIO_BLK_F_BARRIER))
221 blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); 218 blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL);
222 219
223 err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); 220 /* Host must always specify the capacity. */
224 if (err) { 221 __virtio_config_val(vdev, offsetof(struct virtio_blk_config, capacity),
225 dev_err(&vdev->dev, "Bad/missing capacity in config\n"); 222 &cap);
226 goto out_cleanup_queue;
227 }
228 223
229 /* If capacity is too big, truncate with warning. */ 224 /* If capacity is too big, truncate with warning. */
230 if ((sector_t)cap != cap) { 225 if ((sector_t)cap != cap) {
@@ -234,27 +229,23 @@ static int virtblk_probe(struct virtio_device *vdev)
234 } 229 }
235 set_capacity(vblk->disk, cap); 230 set_capacity(vblk->disk, cap);
236 231
237 err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SIZE_MAX, &v); 232 /* Host can optionally specify maximum segment size and number of
233 * segments. */
234 err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX,
235 offsetof(struct virtio_blk_config, size_max),
236 &v);
238 if (!err) 237 if (!err)
239 blk_queue_max_segment_size(vblk->disk->queue, v); 238 blk_queue_max_segment_size(vblk->disk->queue, v);
240 else if (err != -ENOENT) {
241 dev_err(&vdev->dev, "Bad SIZE_MAX in config\n");
242 goto out_cleanup_queue;
243 }
244 239
245 err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); 240 err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX,
241 offsetof(struct virtio_blk_config, seg_max),
242 &v);
246 if (!err) 243 if (!err)
247 blk_queue_max_hw_segments(vblk->disk->queue, v); 244 blk_queue_max_hw_segments(vblk->disk->queue, v);
248 else if (err != -ENOENT) {
249 dev_err(&vdev->dev, "Bad SEG_MAX in config\n");
250 goto out_cleanup_queue;
251 }
252 245
253 add_disk(vblk->disk); 246 add_disk(vblk->disk);
254 return 0; 247 return 0;
255 248
256out_cleanup_queue:
257 blk_cleanup_queue(vblk->disk->queue);
258out_put_disk: 249out_put_disk:
259 put_disk(vblk->disk); 250 put_disk(vblk->disk);
260out_unregister_blkdev: 251out_unregister_blkdev:
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index e34da5c9719..dc17fe3a88b 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -158,13 +158,13 @@ static int __devinit virtcons_probe(struct virtio_device *dev)
158 /* Find the input queue. */ 158 /* Find the input queue. */
159 /* FIXME: This is why we want to wean off hvc: we do nothing 159 /* FIXME: This is why we want to wean off hvc: we do nothing
160 * when input comes in. */ 160 * when input comes in. */
161 in_vq = vdev->config->find_vq(vdev, NULL); 161 in_vq = vdev->config->find_vq(vdev, 0, NULL);
162 if (IS_ERR(in_vq)) { 162 if (IS_ERR(in_vq)) {
163 err = PTR_ERR(in_vq); 163 err = PTR_ERR(in_vq);
164 goto free; 164 goto free;
165 } 165 }
166 166
167 out_vq = vdev->config->find_vq(vdev, NULL); 167 out_vq = vdev->config->find_vq(vdev, 1, NULL);
168 if (IS_ERR(out_vq)) { 168 if (IS_ERR(out_vq)) {
169 err = PTR_ERR(out_vq); 169 err = PTR_ERR(out_vq);
170 goto free_in_vq; 170 goto free_in_vq;
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index e2eec38c83c..07f57a53658 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -52,57 +52,82 @@ struct lguest_device {
52/*D:130 52/*D:130
53 * Device configurations 53 * Device configurations
54 * 54 *
55 * The configuration information for a device consists of a series of fields. 55 * The configuration information for a device consists of one or more
56 * We don't really care what they are: the Launcher set them up, and the driver 56 * virtqueues, a feature bitmaks, and some configuration bytes. The
57 * will look at them during setup. 57 * configuration bytes don't really matter to us: the Launcher set them up, and
58 * the driver will look at them during setup.
58 * 59 *
59 * For us these fields come immediately after that device's descriptor in the 60 * A convenient routine to return the device's virtqueue config array:
60 * lguest_devices page. 61 * immediately after the descriptor. */
61 * 62static struct lguest_vqconfig *lg_vq(const struct lguest_device_desc *desc)
62 * Each field starts with a "type" byte, a "length" byte, then that number of 63{
63 * bytes of configuration information. The device descriptor tells us the 64 return (void *)(desc + 1);
64 * total configuration length so we know when we've reached the last field. */ 65}
65 66
66/* type + length bytes */ 67/* The features come immediately after the virtqueues. */
67#define FHDR_LEN 2 68static u8 *lg_features(const struct lguest_device_desc *desc)
69{
70 return (void *)(lg_vq(desc) + desc->num_vq);
71}
68 72
69/* This finds the first field of a given type for a device's configuration. */ 73/* The config space comes after the two feature bitmasks. */
70static void *lg_find(struct virtio_device *vdev, u8 type, unsigned int *len) 74static u8 *lg_config(const struct lguest_device_desc *desc)
71{ 75{
72 struct lguest_device_desc *desc = to_lgdev(vdev)->desc; 76 return lg_features(desc) + desc->feature_len * 2;
73 int i; 77}
74
75 for (i = 0; i < desc->config_len; i += FHDR_LEN + desc->config[i+1]) {
76 if (desc->config[i] == type) {
77 /* Mark it used, so Host can know we looked at it, and
78 * also so we won't find the same one twice. */
79 desc->config[i] |= 0x80;
80 /* Remember, the second byte is the length. */
81 *len = desc->config[i+1];
82 /* We return a pointer to the field header. */
83 return desc->config + i;
84 }
85 }
86 78
87 /* Not found: return NULL for failure. */ 79/* The total size of the config page used by this device (incl. desc) */
88 return NULL; 80static unsigned desc_size(const struct lguest_device_desc *desc)
81{
82 return sizeof(*desc)
83 + desc->num_vq * sizeof(struct lguest_vqconfig)
84 + desc->feature_len * 2
85 + desc->config_len;
86}
87
88/* This tests (and acknowleges) a feature bit. */
89static bool lg_feature(struct virtio_device *vdev, unsigned fbit)
90{
91 struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
92 u8 *features;
93
94 /* Obviously if they ask for a feature off the end of our feature
95 * bitmap, it's not set. */
96 if (fbit / 8 > desc->feature_len)
97 return false;
98
99 /* The feature bitmap comes after the virtqueues. */
100 features = lg_features(desc);
101 if (!(features[fbit / 8] & (1 << (fbit % 8))))
102 return false;
103
104 /* We set the matching bit in the other half of the bitmap to tell the
105 * Host we want to use this feature. We don't use this yet, but we
106 * could in future. */
107 features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8));
108 return true;
89} 109}
90 110
91/* Once they've found a field, getting a copy of it is easy. */ 111/* Once they've found a field, getting a copy of it is easy. */
92static void lg_get(struct virtio_device *vdev, void *token, 112static void lg_get(struct virtio_device *vdev, unsigned int offset,
93 void *buf, unsigned len) 113 void *buf, unsigned len)
94{ 114{
95 /* Check they didn't ask for more than the length of the field! */ 115 struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
96 BUG_ON(len > ((u8 *)token)[1]); 116
97 memcpy(buf, token + FHDR_LEN, len); 117 /* Check they didn't ask for more than the length of the config! */
118 BUG_ON(offset + len > desc->config_len);
119 memcpy(buf, lg_config(desc) + offset, len);
98} 120}
99 121
100/* Setting the contents is also trivial. */ 122/* Setting the contents is also trivial. */
101static void lg_set(struct virtio_device *vdev, void *token, 123static void lg_set(struct virtio_device *vdev, unsigned int offset,
102 const void *buf, unsigned len) 124 const void *buf, unsigned len)
103{ 125{
104 BUG_ON(len > ((u8 *)token)[1]); 126 struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
105 memcpy(token + FHDR_LEN, buf, len); 127
128 /* Check they didn't ask for more than the length of the config! */
129 BUG_ON(offset + len > desc->config_len);
130 memcpy(lg_config(desc) + offset, buf, len);
106} 131}
107 132
108/* The operations to get and set the status word just access the status field 133/* The operations to get and set the status word just access the status field
@@ -165,39 +190,29 @@ static void lg_notify(struct virtqueue *vq)
165 * 190 *
166 * So we provide devices with a "find virtqueue and set it up" function. */ 191 * So we provide devices with a "find virtqueue and set it up" function. */
167static struct virtqueue *lg_find_vq(struct virtio_device *vdev, 192static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
193 unsigned index,
168 bool (*callback)(struct virtqueue *vq)) 194 bool (*callback)(struct virtqueue *vq))
169{ 195{
196 struct lguest_device *ldev = to_lgdev(vdev);
170 struct lguest_vq_info *lvq; 197 struct lguest_vq_info *lvq;
171 struct virtqueue *vq; 198 struct virtqueue *vq;
172 unsigned int len;
173 void *token;
174 int err; 199 int err;
175 200
176 /* Look for a field of the correct type to mark a virtqueue. Note that 201 /* We must have this many virtqueues. */
177 * if this succeeds, then the type will be changed so it won't be found 202 if (index >= ldev->desc->num_vq)
178 * again, and future lg_find_vq() calls will find the next
179 * virtqueue (if any). */
180 token = vdev->config->find(vdev, VIRTIO_CONFIG_F_VIRTQUEUE, &len);
181 if (!token)
182 return ERR_PTR(-ENOENT); 203 return ERR_PTR(-ENOENT);
183 204
184 lvq = kmalloc(sizeof(*lvq), GFP_KERNEL); 205 lvq = kmalloc(sizeof(*lvq), GFP_KERNEL);
185 if (!lvq) 206 if (!lvq)
186 return ERR_PTR(-ENOMEM); 207 return ERR_PTR(-ENOMEM);
187 208
188 /* Note: we could use a configuration space inside here, just like we 209 /* Make a copy of the "struct lguest_vqconfig" entry, which sits after
189 * do for the device. This would allow expansion in future, because 210 * the descriptor. We need a copy because the config space might not
190 * our configuration system is designed to be expansible. But this is 211 * be aligned correctly. */
191 * way easier. */ 212 memcpy(&lvq->config, lg_vq(ldev->desc)+index, sizeof(lvq->config));
192 if (len != sizeof(lvq->config)) {
193 dev_err(&vdev->dev, "Unexpected virtio config len %u\n", len);
194 err = -EIO;
195 goto free_lvq;
196 }
197 /* Make a copy of the "struct lguest_vqconfig" field. We need a copy
198 * because the config space might not be aligned correctly. */
199 vdev->config->get(vdev, token, &lvq->config, sizeof(lvq->config));
200 213
214 printk("Mapping virtqueue %i addr %lx\n", index,
215 (unsigned long)lvq->config.pfn << PAGE_SHIFT);
201 /* Figure out how many pages the ring will take, and map that memory */ 216 /* Figure out how many pages the ring will take, and map that memory */
202 lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT, 217 lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT,
203 DIV_ROUND_UP(vring_size(lvq->config.num, 218 DIV_ROUND_UP(vring_size(lvq->config.num,
@@ -259,7 +274,7 @@ static void lg_del_vq(struct virtqueue *vq)
259 274
260/* The ops structure which hooks everything together. */ 275/* The ops structure which hooks everything together. */
261static struct virtio_config_ops lguest_config_ops = { 276static struct virtio_config_ops lguest_config_ops = {
262 .find = lg_find, 277 .feature = lg_feature,
263 .get = lg_get, 278 .get = lg_get,
264 .set = lg_set, 279 .set = lg_set,
265 .get_status = lg_get_status, 280 .get_status = lg_get_status,
@@ -329,13 +344,14 @@ static void scan_devices(void)
329 struct lguest_device_desc *d; 344 struct lguest_device_desc *d;
330 345
331 /* We start at the page beginning, and skip over each entry. */ 346 /* We start at the page beginning, and skip over each entry. */
332 for (i = 0; i < PAGE_SIZE; i += sizeof(*d) + d->config_len) { 347 for (i = 0; i < PAGE_SIZE; i += desc_size(d)) {
333 d = lguest_devices + i; 348 d = lguest_devices + i;
334 349
335 /* Once we hit a zero, stop. */ 350 /* Once we hit a zero, stop. */
336 if (d->type == 0) 351 if (d->type == 0)
337 break; 352 break;
338 353
354 printk("Device at %i has size %u\n", i, desc_size(d));
339 add_lguest_device(d); 355 add_lguest_device(d);
340 } 356 }
341} 357}
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index a60505c8f82..4b813831275 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -311,10 +311,8 @@ static int virtnet_close(struct net_device *dev)
311static int virtnet_probe(struct virtio_device *vdev) 311static int virtnet_probe(struct virtio_device *vdev)
312{ 312{
313 int err; 313 int err;
314 unsigned int len;
315 struct net_device *dev; 314 struct net_device *dev;
316 struct virtnet_info *vi; 315 struct virtnet_info *vi;
317 void *token;
318 316
319 /* Allocate ourselves a network device with room for our info */ 317 /* Allocate ourselves a network device with room for our info */
320 dev = alloc_etherdev(sizeof(struct virtnet_info)); 318 dev = alloc_etherdev(sizeof(struct virtnet_info));
@@ -330,25 +328,24 @@ static int virtnet_probe(struct virtio_device *vdev)
330 SET_NETDEV_DEV(dev, &vdev->dev); 328 SET_NETDEV_DEV(dev, &vdev->dev);
331 329
332 /* Do we support "hardware" checksums? */ 330 /* Do we support "hardware" checksums? */
333 token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_F, &len); 331 if (vdev->config->feature(vdev, VIRTIO_NET_F_NO_CSUM)) {
334 if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_NO_CSUM)) {
335 /* This opens up the world of extra features. */ 332 /* This opens up the world of extra features. */
336 dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; 333 dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
337 if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4)) 334 if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO4))
338 dev->features |= NETIF_F_TSO; 335 dev->features |= NETIF_F_TSO;
339 if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_UFO)) 336 if (vdev->config->feature(vdev, VIRTIO_NET_F_UFO))
340 dev->features |= NETIF_F_UFO; 337 dev->features |= NETIF_F_UFO;
341 if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO4_ECN)) 338 if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO4_ECN))
342 dev->features |= NETIF_F_TSO_ECN; 339 dev->features |= NETIF_F_TSO_ECN;
343 if (virtio_use_bit(vdev, token, len, VIRTIO_NET_F_TSO6)) 340 if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO6))
344 dev->features |= NETIF_F_TSO6; 341 dev->features |= NETIF_F_TSO6;
345 } 342 }
346 343
347 /* Configuration may specify what MAC to use. Otherwise random. */ 344 /* Configuration may specify what MAC to use. Otherwise random. */
348 token = vdev->config->find(vdev, VIRTIO_CONFIG_NET_MAC_F, &len); 345 if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) {
349 if (token) { 346 vdev->config->get(vdev,
350 dev->addr_len = len; 347 offsetof(struct virtio_net_config, mac),
351 vdev->config->get(vdev, token, dev->dev_addr, len); 348 dev->dev_addr, dev->addr_len);
352 } else 349 } else
353 random_ether_addr(dev->dev_addr); 350 random_ether_addr(dev->dev_addr);
354 351
@@ -359,13 +356,13 @@ static int virtnet_probe(struct virtio_device *vdev)
359 vi->vdev = vdev; 356 vi->vdev = vdev;
360 357
361 /* We expect two virtqueues, receive then send. */ 358 /* We expect two virtqueues, receive then send. */
362 vi->rvq = vdev->config->find_vq(vdev, skb_recv_done); 359 vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done);
363 if (IS_ERR(vi->rvq)) { 360 if (IS_ERR(vi->rvq)) {
364 err = PTR_ERR(vi->rvq); 361 err = PTR_ERR(vi->rvq);
365 goto free; 362 goto free;
366 } 363 }
367 364
368 vi->svq = vdev->config->find_vq(vdev, skb_xmit_done); 365 vi->svq = vdev->config->find_vq(vdev, 1, skb_xmit_done);
369 if (IS_ERR(vi->svq)) { 366 if (IS_ERR(vi->svq)) {
370 err = PTR_ERR(vi->svq); 367 err = PTR_ERR(vi->svq);
371 goto free_recv; 368 goto free_recv;
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 69d7ea02cd4..303cb6f9010 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -148,51 +148,6 @@ void unregister_virtio_device(struct virtio_device *dev)
148} 148}
149EXPORT_SYMBOL_GPL(unregister_virtio_device); 149EXPORT_SYMBOL_GPL(unregister_virtio_device);
150 150
151int __virtio_config_val(struct virtio_device *vdev,
152 u8 type, void *val, size_t size)
153{
154 void *token;
155 unsigned int len;
156
157 token = vdev->config->find(vdev, type, &len);
158 if (!token)
159 return -ENOENT;
160
161 if (len != size)
162 return -EIO;
163
164 vdev->config->get(vdev, token, val, size);
165 return 0;
166}
167EXPORT_SYMBOL_GPL(__virtio_config_val);
168
169int virtio_use_bit(struct virtio_device *vdev,
170 void *token, unsigned int len, unsigned int bitnum)
171{
172 unsigned long bits[16];
173
174 /* This makes it convenient to pass-through find() results. */
175 if (!token)
176 return 0;
177
178 /* bit not in range of this bitfield? */
179 if (bitnum * 8 >= len / 2)
180 return 0;
181
182 /* Giant feature bitfields are silly. */
183 BUG_ON(len > sizeof(bits));
184 vdev->config->get(vdev, token, bits, len);
185
186 if (!test_bit(bitnum, bits))
187 return 0;
188
189 /* Set acknowledge bit, and write it back. */
190 set_bit(bitnum + len * 8 / 2, bits);
191 vdev->config->set(vdev, token, bits, len);
192 return 1;
193}
194EXPORT_SYMBOL_GPL(virtio_use_bit);
195
196static int virtio_init(void) 151static int virtio_init(void)
197{ 152{
198 if (bus_register(&virtio_bus) != 0) 153 if (bus_register(&virtio_bus) != 0)
diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h
index 697104da91f..589be3e1f3a 100644
--- a/include/linux/lguest_launcher.h
+++ b/include/linux/lguest_launcher.h
@@ -23,7 +23,12 @@
23struct lguest_device_desc { 23struct lguest_device_desc {
24 /* The device type: console, network, disk etc. Type 0 terminates. */ 24 /* The device type: console, network, disk etc. Type 0 terminates. */
25 __u8 type; 25 __u8 type;
26 /* The number of bytes of the config array. */ 26 /* The number of virtqueues (first in config array) */
27 __u8 num_vq;
28 /* The number of bytes of feature bits. Multiply by 2: one for host
29 * features and one for guest acknowledgements. */
30 __u8 feature_len;
31 /* The number of bytes of the config array after virtqueues. */
27 __u8 config_len; 32 __u8 config_len;
28 /* A status byte, written by the Guest. */ 33 /* A status byte, written by the Guest. */
29 __u8 status; 34 __u8 status;
@@ -31,7 +36,7 @@ struct lguest_device_desc {
31}; 36};
32 37
33/*D:135 This is how we expect the device configuration field for a virtqueue 38/*D:135 This is how we expect the device configuration field for a virtqueue
34 * (type VIRTIO_CONFIG_F_VIRTQUEUE) to be laid out: */ 39 * to be laid out in config space. */
35struct lguest_vqconfig { 40struct lguest_vqconfig {
36 /* The number of entries in the virtio_ring */ 41 /* The number of entries in the virtio_ring */
37 __u16 num; 42 __u16 num;
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
index 7bd2bce0cfd..e54635666f2 100644
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -6,15 +6,19 @@
6#define VIRTIO_ID_BLOCK 2 6#define VIRTIO_ID_BLOCK 2
7 7
8/* Feature bits */ 8/* Feature bits */
9#define VIRTIO_CONFIG_BLK_F 0x40 9#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
10#define VIRTIO_BLK_F_BARRIER 1 /* Does host support barriers? */ 10#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */
11 11#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */
12/* The capacity (in 512-byte sectors). */ 12
13#define VIRTIO_CONFIG_BLK_F_CAPACITY 0x41 13struct virtio_blk_config
14/* The maximum segment size. */ 14{
15#define VIRTIO_CONFIG_BLK_F_SIZE_MAX 0x42 15 /* The capacity (in 512-byte sectors). */
16/* The maximum number of segments. */ 16 __le64 capacity;
17#define VIRTIO_CONFIG_BLK_F_SEG_MAX 0x43 17 /* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */
18 __le32 size_max;
19 /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
20 __le32 seg_max;
21} __attribute__((packed));
18 22
19/* These two define direction. */ 23/* These two define direction. */
20#define VIRTIO_BLK_T_IN 0 24#define VIRTIO_BLK_T_IN 0
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index bcc01888df7..70bb26062d7 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -5,7 +5,7 @@
5 * store and access that space differently. */ 5 * store and access that space differently. */
6#include <linux/types.h> 6#include <linux/types.h>
7 7
8/* Status byte for guest to report progress, and synchronize config. */ 8/* Status byte for guest to report progress, and synchronize features. */
9/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */ 9/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
10#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 10#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1
11/* We have found a driver for the device. */ 11/* We have found a driver for the device. */
@@ -15,34 +15,27 @@
15/* We've given up on this device. */ 15/* We've given up on this device. */
16#define VIRTIO_CONFIG_S_FAILED 0x80 16#define VIRTIO_CONFIG_S_FAILED 0x80
17 17
18/* Feature byte (actually 7 bits availabe): */
19/* Requirements/features of the virtio implementation. */
20#define VIRTIO_CONFIG_F_VIRTIO 1
21/* Requirements/features of the virtqueue (may have more than one). */
22#define VIRTIO_CONFIG_F_VIRTQUEUE 2
23
24#ifdef __KERNEL__ 18#ifdef __KERNEL__
25struct virtio_device; 19struct virtio_device;
26 20
27/** 21/**
28 * virtio_config_ops - operations for configuring a virtio device 22 * virtio_config_ops - operations for configuring a virtio device
29 * @find: search for the next configuration field of the given type. 23 * @feature: search for a feature in this config
30 * vdev: the virtio_device 24 * vdev: the virtio_device
31 * type: the feature type 25 * bit: the feature bit
32 * len: the (returned) length of the field if found. 26 * Returns true if the feature is supported. Acknowledges the feature
33 * Returns a token if found, or NULL. Never returnes the same field twice 27 * so the host can see it.
34 * (ie. it's used up). 28 * @get: read the value of a configuration field
35 * @get: read the value of a configuration field after find().
36 * vdev: the virtio_device 29 * vdev: the virtio_device
37 * token: the token returned from find(). 30 * offset: the offset of the configuration field
38 * buf: the buffer to write the field value into. 31 * buf: the buffer to write the field value into.
39 * len: the length of the buffer (given by find()). 32 * len: the length of the buffer
40 * Note that contents are conventionally little-endian. 33 * Note that contents are conventionally little-endian.
41 * @set: write the value of a configuration field after find(). 34 * @set: write the value of a configuration field
42 * vdev: the virtio_device 35 * vdev: the virtio_device
43 * token: the token returned from find(). 36 * offset: the offset of the configuration field
44 * buf: the buffer to read the field value from. 37 * buf: the buffer to read the field value from.
45 * len: the length of the buffer (given by find()). 38 * len: the length of the buffer
46 * Note that contents are conventionally little-endian. 39 * Note that contents are conventionally little-endian.
47 * @get_status: read the status byte 40 * @get_status: read the status byte
48 * vdev: the virtio_device 41 * vdev: the virtio_device
@@ -50,62 +43,63 @@ struct virtio_device;
50 * @set_status: write the status byte 43 * @set_status: write the status byte
51 * vdev: the virtio_device 44 * vdev: the virtio_device
52 * status: the new status byte 45 * status: the new status byte
53 * @find_vq: find the first VIRTIO_CONFIG_F_VIRTQUEUE and create a virtqueue. 46 * @find_vq: find a virtqueue and instantiate it.
54 * vdev: the virtio_device 47 * vdev: the virtio_device
48 * index: the 0-based virtqueue number in case there's more than one.
55 * callback: the virqtueue callback 49 * callback: the virqtueue callback
56 * Returns the new virtqueue or ERR_PTR(). 50 * Returns the new virtqueue or ERR_PTR() (eg. -ENOENT).
57 * @del_vq: free a virtqueue found by find_vq(). 51 * @del_vq: free a virtqueue found by find_vq().
58 */ 52 */
59struct virtio_config_ops 53struct virtio_config_ops
60{ 54{
61 void *(*find)(struct virtio_device *vdev, u8 type, unsigned *len); 55 bool (*feature)(struct virtio_device *vdev, unsigned bit);
62 void (*get)(struct virtio_device *vdev, void *token, 56 void (*get)(struct virtio_device *vdev, unsigned offset,
63 void *buf, unsigned len); 57 void *buf, unsigned len);
64 void (*set)(struct virtio_device *vdev, void *token, 58 void (*set)(struct virtio_device *vdev, unsigned offset,
65 const void *buf, unsigned len); 59 const void *buf, unsigned len);
66 u8 (*get_status)(struct virtio_device *vdev); 60 u8 (*get_status)(struct virtio_device *vdev);
67 void (*set_status)(struct virtio_device *vdev, u8 status); 61 void (*set_status)(struct virtio_device *vdev, u8 status);
68 struct virtqueue *(*find_vq)(struct virtio_device *vdev, 62 struct virtqueue *(*find_vq)(struct virtio_device *vdev,
63 unsigned index,
69 bool (*callback)(struct virtqueue *)); 64 bool (*callback)(struct virtqueue *));
70 void (*del_vq)(struct virtqueue *vq); 65 void (*del_vq)(struct virtqueue *vq);
71}; 66};
72 67
73/** 68/**
74 * virtio_config_val - get a single virtio config and mark it used. 69 * virtio_config_val - look for a feature and get a single virtio config.
75 * @config: the virtio config space 70 * @vdev: the virtio device
76 * @type: the type to search for. 71 * @fbit: the feature bit
72 * @offset: the type to search for.
77 * @val: a pointer to the value to fill in. 73 * @val: a pointer to the value to fill in.
78 * 74 *
79 * Once used, the config type is marked with VIRTIO_CONFIG_F_USED so it can't 75 * The return value is -ENOENT if the feature doesn't exist. Otherwise
80 * be found again. This version does endian conversion. */ 76 * the value is endian-corrected and returned in v. */
81#define virtio_config_val(vdev, type, v) ({ \ 77#define virtio_config_val(vdev, fbit, offset, v) ({ \
82 int _err = __virtio_config_val((vdev),(type),(v),sizeof(*(v))); \ 78 int _err; \
83 \ 79 if ((vdev)->config->feature((vdev), (fbit))) { \
84 BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2 \ 80 __virtio_config_val((vdev), (offset), (v)); \
85 && sizeof(*(v)) != 4 && sizeof(*(v)) != 8); \ 81 _err = 0; \
86 if (!_err) { \ 82 } else \
87 switch (sizeof(*(v))) { \ 83 _err = -ENOENT; \
88 case 2: le16_to_cpus((__u16 *) v); break; \
89 case 4: le32_to_cpus((__u32 *) v); break; \
90 case 8: le64_to_cpus((__u64 *) v); break; \
91 } \
92 } \
93 _err; \ 84 _err; \
94}) 85})
95 86
96int __virtio_config_val(struct virtio_device *dev,
97 u8 type, void *val, size_t size);
98
99/** 87/**
100 * virtio_use_bit - helper to use a feature bit in a bitfield value. 88 * __virtio_config_val - get a single virtio config without feature check.
101 * @dev: the virtio device 89 * @vdev: the virtio device
102 * @token: the token as returned from vdev->config->find(). 90 * @offset: the type to search for.
103 * @len: the length of the field. 91 * @val: a pointer to the value to fill in.
104 * @bitnum: the bit to test.
105 * 92 *
106 * If handed a NULL token, it returns false, otherwise returns bit status. 93 * The value is endian-corrected and returned in v. */
107 * If it's one, it sets the mirroring acknowledgement bit. */ 94#define __virtio_config_val(vdev, offset, v) do { \
108int virtio_use_bit(struct virtio_device *vdev, 95 BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2 \
109 void *token, unsigned int len, unsigned int bitnum); 96 && sizeof(*(v)) != 4 && sizeof(*(v)) != 8); \
97 (vdev)->config->get((vdev), (offset), (v), sizeof(*(v))); \
98 switch (sizeof(*(v))) { \
99 case 2: le16_to_cpus((__u16 *) v); break; \
100 case 4: le32_to_cpus((__u32 *) v); break; \
101 case 8: le64_to_cpus((__u64 *) v); break; \
102 } \
103} while(0)
110#endif /* __KERNEL__ */ 104#endif /* __KERNEL__ */
111#endif /* _LINUX_VIRTIO_CONFIG_H */ 105#endif /* _LINUX_VIRTIO_CONFIG_H */
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index ae469ae55d3..6e8fdfea8cd 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -5,16 +5,19 @@
5/* The ID for virtio_net */ 5/* The ID for virtio_net */
6#define VIRTIO_ID_NET 1 6#define VIRTIO_ID_NET 1
7 7
8/* The bitmap of config for virtio net */ 8/* The feature bitmap for virtio net */
9#define VIRTIO_CONFIG_NET_F 0x40
10#define VIRTIO_NET_F_NO_CSUM 0 9#define VIRTIO_NET_F_NO_CSUM 0
11#define VIRTIO_NET_F_TSO4 1 10#define VIRTIO_NET_F_TSO4 1
12#define VIRTIO_NET_F_UFO 2 11#define VIRTIO_NET_F_UFO 2
13#define VIRTIO_NET_F_TSO4_ECN 3 12#define VIRTIO_NET_F_TSO4_ECN 3
14#define VIRTIO_NET_F_TSO6 4 13#define VIRTIO_NET_F_TSO6 4
14#define VIRTIO_NET_F_MAC 5
15 15
16/* The config defining mac address. */ 16struct virtio_net_config
17#define VIRTIO_CONFIG_NET_MAC_F 0x41 17{
18 /* The config defining mac address (if VIRTIO_NET_F_MAC) */
19 __u8 mac[6];
20} __attribute__((packed));
18 21
19/* This is the first element of the scatter-gather list. If you don't 22/* This is the first element of the scatter-gather list. If you don't
20 * specify GSO or CSUM features, you can simply ignore the header. */ 23 * specify GSO or CSUM features, you can simply ignore the header. */
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 40b71a29fc3..78d7946f81f 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -236,13 +236,13 @@ static int p9_virtio_probe(struct virtio_device *dev)
236 236
237 /* Find the input queue. */ 237 /* Find the input queue. */
238 dev->priv = chan; 238 dev->priv = chan;
239 chan->in_vq = dev->config->find_vq(dev, p9_virtio_intr); 239 chan->in_vq = dev->config->find_vq(dev, 0, p9_virtio_intr);
240 if (IS_ERR(chan->in_vq)) { 240 if (IS_ERR(chan->in_vq)) {
241 err = PTR_ERR(chan->in_vq); 241 err = PTR_ERR(chan->in_vq);
242 goto free; 242 goto free;
243 } 243 }
244 244
245 chan->out_vq = dev->config->find_vq(dev, NULL); 245 chan->out_vq = dev->config->find_vq(dev, 1, NULL);
246 if (IS_ERR(chan->out_vq)) { 246 if (IS_ERR(chan->out_vq)) {
247 err = PTR_ERR(chan->out_vq); 247 err = PTR_ERR(chan->out_vq);
248 goto free_in_vq; 248 goto free_in_vq;