Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus

* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
lguest: make Launcher see device status updates
lguest: remove bogus NULL cpu check
lguest: avoid using NR_CPUS as a bounds check.
virtio: add virtio disk geometry feature
virtio: explicit advertisement of driver features
virtio: change config to guest endian.
virtio: finer-grained features for virtio_net
virtio: wean net driver off NETDEV_TX_BUSY
virtio-blk: fix remove oops
virtio: fix scatterlist sizing in net driver.
virtio: de-structify virtio_block status byte
virtio: export more headers to userspace
virtio: fix sparse return void-valued expression warnings
virtio: fix tx_ stats in virtio_net
virtio: ignore corrupted virtqueues rather than spinning.

+323 -158
+41 -21
Documentation/lguest/lguest.c
··· 131 131 /* Any queues attached to this device */ 132 132 struct virtqueue *vq; 133 133 134 + /* Handle status being finalized (ie. feature bits stable). */ 135 + void (*ready)(struct device *me); 136 + 134 137 /* Device-specific data. */ 135 138 void *priv; 136 139 }; ··· 928 925 write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd)); 929 926 } 930 927 931 - /* When the Guest asks us to reset a device, it's is fairly easy. */ 932 - static void reset_device(struct device *dev) 928 + /* When the Guest tells us they updated the status field, we handle it. */ 929 + static void update_device_status(struct device *dev) 933 930 { 934 931 struct virtqueue *vq; 935 932 936 - verbose("Resetting device %s\n", dev->name); 937 - /* Clear the status. */ 938 - dev->desc->status = 0; 933 + /* This is a reset. */ 934 + if (dev->desc->status == 0) { 935 + verbose("Resetting device %s\n", dev->name); 939 936 940 - /* Clear any features they've acked. */ 941 - memset(get_feature_bits(dev) + dev->desc->feature_len, 0, 942 - dev->desc->feature_len); 937 + /* Clear any features they've acked. */ 938 + memset(get_feature_bits(dev) + dev->desc->feature_len, 0, 939 + dev->desc->feature_len); 943 940 944 - /* Zero out the virtqueues. */ 945 - for (vq = dev->vq; vq; vq = vq->next) { 946 - memset(vq->vring.desc, 0, 947 - vring_size(vq->config.num, getpagesize())); 948 - vq->last_avail_idx = 0; 941 + /* Zero out the virtqueues. */ 942 + for (vq = dev->vq; vq; vq = vq->next) { 943 + memset(vq->vring.desc, 0, 944 + vring_size(vq->config.num, getpagesize())); 945 + vq->last_avail_idx = 0; 946 + } 947 + } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) { 948 + warnx("Device %s configuration FAILED", dev->name); 949 + } else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) { 950 + unsigned int i; 951 + 952 + verbose("Device %s OK: offered", dev->name); 953 + for (i = 0; i < dev->desc->feature_len; i++) 954 + verbose(" %08x", get_feature_bits(dev)[i]); 955 + verbose(", accepted"); 956 + for (i = 0; i < dev->desc->feature_len; i++) 957 + verbose(" %08x", get_feature_bits(dev) 958 + [dev->desc->feature_len+i]); 959 + 960 + if (dev->ready) 961 + dev->ready(dev); 949 962 } 950 963 } 951 964 ··· 973 954 974 955 /* Check each device and virtqueue. */ 975 956 for (i = devices.dev; i; i = i->next) { 976 - /* Notifications to device descriptors reset the device. */ 957 + /* Notifications to device descriptors update device status. */ 977 958 if (from_guest_phys(addr) == i->desc) { 978 - reset_device(i); 959 + update_device_status(i); 979 960 return; 980 961 } 981 962 ··· 1189 1170 dev->handle_input = handle_input; 1190 1171 dev->name = name; 1191 1172 dev->vq = NULL; 1173 + dev->ready = NULL; 1192 1174 1193 1175 /* Append to device list. Prepending to a single-linked list is 1194 1176 * easier, but the user expects the devices to be arranged on the bus ··· 1418 1398 struct vblk_info *vblk = dev->priv; 1419 1399 unsigned int head, out_num, in_num, wlen; 1420 1400 int ret; 1421 - struct virtio_blk_inhdr *in; 1401 + u8 *in; 1422 1402 struct virtio_blk_outhdr *out; 1423 1403 struct iovec iov[dev->vq->vring.num]; 1424 1404 off64_t off; ··· 1436 1416 head, out_num, in_num); 1437 1417 1438 1418 out = convert(&iov[0], struct virtio_blk_outhdr); 1439 - in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr); 1419 + in = convert(&iov[out_num+in_num-1], u8); 1440 1420 off = out->sector * 512; 1441 1421 1442 1422 /* The block device implements "barriers", where the Guest indicates ··· 1450 1430 * It'd be nice if we supported eject, for example, but we don't. */ 1451 1431 if (out->type & VIRTIO_BLK_T_SCSI_CMD) { 1452 1432 fprintf(stderr, "Scsi commands unsupported\n"); 1453 - in->status = VIRTIO_BLK_S_UNSUPP; 1433 + *in = VIRTIO_BLK_S_UNSUPP; 1454 1434 wlen = sizeof(*in); 1455 1435 } else if (out->type & VIRTIO_BLK_T_OUT) { 1456 1436 /* Write */ ··· 1473 1453 errx(1, "Write past end %llu+%u", off, ret); 1474 1454 } 1475 1455 wlen = sizeof(*in); 1476 - in->status = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); 1456 + *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); 1477 1457 } else { 1478 1458 /* Read */ 1479 1459 ··· 1486 1466 verbose("READ from sector %llu: %i\n", out->sector, ret); 1487 1467 if (ret >= 0) { 1488 1468 wlen = sizeof(*in) + ret; 1489 - in->status = VIRTIO_BLK_S_OK; 1469 + *in = VIRTIO_BLK_S_OK; 1490 1470 } else { 1491 1471 wlen = sizeof(*in); 1492 - in->status = VIRTIO_BLK_S_IOERR; 1472 + *in = VIRTIO_BLK_S_IOERR; 1493 1473 } 1494 1474 } 1495 1475
+32 -12
drivers/block/virtio_blk.c
··· 35 35 struct list_head list; 36 36 struct request *req; 37 37 struct virtio_blk_outhdr out_hdr; 38 - struct virtio_blk_inhdr in_hdr; 38 + u8 status; 39 39 }; 40 40 41 41 static void blk_done(struct virtqueue *vq) ··· 48 48 spin_lock_irqsave(&vblk->lock, flags); 49 49 while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) { 50 50 int uptodate; 51 - switch (vbr->in_hdr.status) { 51 + switch (vbr->status) { 52 52 case VIRTIO_BLK_S_OK: 53 53 uptodate = 1; 54 54 break; ··· 101 101 sg_init_table(vblk->sg, VIRTIO_MAX_SG); 102 102 sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr)); 103 103 num = blk_rq_map_sg(q, vbr->req, vblk->sg+1); 104 - sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr)); 104 + sg_set_buf(&vblk->sg[num+1], &vbr->status, sizeof(vbr->status)); 105 105 106 106 if (rq_data_dir(vbr->req) == WRITE) { 107 107 vbr->out_hdr.type |= VIRTIO_BLK_T_OUT; ··· 157 157 /* We provide getgeo only to please some old bootloader/partitioning tools */ 158 158 static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) 159 159 { 160 - /* some standard values, similar to sd */ 161 - geo->heads = 1 << 6; 162 - geo->sectors = 1 << 5; 163 - geo->cylinders = get_capacity(bd->bd_disk) >> 11; 160 + struct virtio_blk *vblk = bd->bd_disk->private_data; 161 + struct virtio_blk_geometry vgeo; 162 + int err; 163 + 164 + /* see if the host passed in geometry config */ 165 + err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY, 166 + offsetof(struct virtio_blk_config, geometry), 167 + &vgeo); 168 + 169 + if (!err) { 170 + geo->heads = vgeo.heads; 171 + geo->sectors = vgeo.sectors; 172 + geo->cylinders = vgeo.cylinders; 173 + } else { 174 + /* some standard values, similar to sd */ 175 + geo->heads = 1 << 6; 176 + geo->sectors = 1 << 5; 177 + geo->cylinders = get_capacity(bd->bd_disk) >> 11; 178 + } 164 179 return 0; 165 180 } 166 181 ··· 257 242 index++; 258 243 259 244 /* If barriers are supported, tell block layer that queue is ordered */ 260 - if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) 245 + if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) 261 246 blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); 262 247 263 248 /* Host must always specify the capacity. */ 264 - __virtio_config_val(vdev, offsetof(struct virtio_blk_config, capacity), 265 - &cap); 249 + vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), 250 + &cap, sizeof(cap)); 266 251 267 252 /* If capacity is too big, truncate with warning. */ 268 253 if ((sector_t)cap != cap) { ··· 304 289 static void virtblk_remove(struct virtio_device *vdev) 305 290 { 306 291 struct virtio_blk *vblk = vdev->priv; 307 - int major = vblk->disk->major; 308 292 309 293 /* Nothing should be pending. */ 310 294 BUG_ON(!list_empty(&vblk->reqs)); ··· 313 299 314 300 blk_cleanup_queue(vblk->disk->queue); 315 301 put_disk(vblk->disk); 316 - unregister_blkdev(major, "virtblk"); 317 302 mempool_destroy(vblk->pool); 318 303 vdev->config->del_vq(vblk->vq); 319 304 kfree(vblk); ··· 323 310 { 0 }, 324 311 }; 325 312 313 + static unsigned int features[] = { 314 + VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, 315 + VIRTIO_BLK_F_GEOMETRY, 316 + }; 317 + 326 318 static struct virtio_driver virtio_blk = { 319 + .feature_table = features, 320 + .feature_table_size = ARRAY_SIZE(features), 327 321 .driver.name = KBUILD_MODNAME, 328 322 .driver.owner = THIS_MODULE, 329 323 .id_table = id_table,
+41 -27
drivers/lguest/lguest_device.c
··· 85 85 + desc->config_len; 86 86 } 87 87 88 - /* This tests (and acknowleges) a feature bit. */ 89 - static bool lg_feature(struct virtio_device *vdev, unsigned fbit) 88 + /* This gets the device's feature bits. */ 89 + static u32 lg_get_features(struct virtio_device *vdev) 90 90 { 91 + unsigned int i; 92 + u32 features = 0; 91 93 struct lguest_device_desc *desc = to_lgdev(vdev)->desc; 92 - u8 *features; 94 + u8 *in_features = lg_features(desc); 93 95 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; 96 + /* We do this the slow but generic way. */ 97 + for (i = 0; i < min(desc->feature_len * 8, 32); i++) 98 + if (in_features[i / 8] & (1 << (i % 8))) 99 + features |= (1 << i); 98 100 99 - /* The feature bitmap comes after the virtqueues. */ 100 - features = lg_features(desc); 101 - if (!(features[fbit / 8] & (1 << (fbit % 8)))) 102 - return false; 101 + return features; 102 + } 103 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; 104 + static void lg_set_features(struct virtio_device *vdev, u32 features) 105 + { 106 + unsigned int i; 107 + struct lguest_device_desc *desc = to_lgdev(vdev)->desc; 108 + /* Second half of bitmap is features we accept. */ 109 + u8 *out_features = lg_features(desc) + desc->feature_len; 110 + 111 + memset(out_features, 0, desc->feature_len); 112 + for (i = 0; i < min(desc->feature_len * 8, 32); i++) { 113 + if (features & (1 << i)) 114 + out_features[i / 8] |= (1 << (i % 8)); 115 + } 109 116 } 110 117 111 118 /* Once they've found a field, getting a copy of it is easy. */ ··· 144 137 return to_lgdev(vdev)->desc->status; 145 138 } 146 139 147 - static void lg_set_status(struct virtio_device *vdev, u8 status) 148 - { 149 - BUG_ON(!status); 150 - to_lgdev(vdev)->desc->status = status; 151 - } 152 - 153 - /* To reset the device, we (ab)use the NOTIFY hypercall, with the descriptor 154 - * address of the device. The Host will zero the status and all the 155 - * features. */ 156 - static void lg_reset(struct virtio_device *vdev) 140 + /* To notify on status updates, we (ab)use the NOTIFY hypercall, with the 141 + * descriptor address of the device. A zero status means "reset". */ 142 + static void set_status(struct virtio_device *vdev, u8 status) 157 143 { 158 144 unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices; 159 145 146 + /* We set the status. */ 147 + to_lgdev(vdev)->desc->status = status; 160 148 hcall(LHCALL_NOTIFY, (max_pfn<<PAGE_SHIFT) + offset, 0, 0); 149 + } 150 + 151 + static void lg_set_status(struct virtio_device *vdev, u8 status) 152 + { 153 + BUG_ON(!status); 154 + set_status(vdev, status); 155 + } 156 + 157 + static void lg_reset(struct virtio_device *vdev) 158 + { 159 + set_status(vdev, 0); 161 160 } 162 161 163 162 /* ··· 299 286 300 287 /* The ops structure which hooks everything together. */ 301 288 static struct virtio_config_ops lguest_config_ops = { 302 - .feature = lg_feature, 289 + .get_features = lg_get_features, 290 + .set_features = lg_set_features, 303 291 .get = lg_get, 304 292 .set = lg_set, 305 293 .get_status = lg_get_status,
+1 -3
drivers/lguest/lguest_user.c
··· 102 102 static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) 103 103 { 104 104 /* We have a limited number the number of CPUs in the lguest struct. */ 105 - if (id >= NR_CPUS) 105 + if (id >= ARRAY_SIZE(cpu->lg->cpus)) 106 106 return -EINVAL; 107 107 108 108 /* Set up this CPU's id, and pointer back to the lguest struct. */ ··· 251 251 if (!lg || (cpu_id >= lg->nr_cpus)) 252 252 return -EINVAL; 253 253 cpu = &lg->cpus[cpu_id]; 254 - if (!cpu) 255 - return -EINVAL; 256 254 257 255 /* Once the Guest is dead, you can only read() why it died. */ 258 256 if (lg->dead)
+68 -28
drivers/net/virtio_net.c
··· 41 41 struct net_device *dev; 42 42 struct napi_struct napi; 43 43 44 + /* The skb we couldn't send because buffers were full. */ 45 + struct sk_buff *last_xmit_skb; 46 + 44 47 /* Number of input buffers, and max we've ever had. */ 45 48 unsigned int num, max; 46 49 ··· 145 142 static void try_fill_recv(struct virtnet_info *vi) 146 143 { 147 144 struct sk_buff *skb; 148 - struct scatterlist sg[1+MAX_SKB_FRAGS]; 145 + struct scatterlist sg[2+MAX_SKB_FRAGS]; 149 146 int num, err; 150 147 151 - sg_init_table(sg, 1+MAX_SKB_FRAGS); 148 + sg_init_table(sg, 2+MAX_SKB_FRAGS); 152 149 for (;;) { 153 150 skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); 154 151 if (unlikely(!skb)) ··· 224 221 while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) { 225 222 pr_debug("Sent skb %p\n", skb); 226 223 __skb_unlink(skb, &vi->send); 227 - vi->dev->stats.tx_bytes += len; 224 + vi->dev->stats.tx_bytes += skb->len; 228 225 vi->dev->stats.tx_packets++; 229 226 kfree_skb(skb); 230 227 } 231 228 } 232 229 233 - static int start_xmit(struct sk_buff *skb, struct net_device *dev) 230 + static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) 234 231 { 235 - struct virtnet_info *vi = netdev_priv(dev); 236 - int num, err; 237 - struct scatterlist sg[1+MAX_SKB_FRAGS]; 232 + int num; 233 + struct scatterlist sg[2+MAX_SKB_FRAGS]; 238 234 struct virtio_net_hdr *hdr; 239 235 const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; 240 236 241 - sg_init_table(sg, 1+MAX_SKB_FRAGS); 237 + sg_init_table(sg, 2+MAX_SKB_FRAGS); 242 238 243 - pr_debug("%s: xmit %p " MAC_FMT "\n", dev->name, skb, 239 + pr_debug("%s: xmit %p " MAC_FMT "\n", vi->dev->name, skb, 244 240 dest[0], dest[1], dest[2], 245 241 dest[3], dest[4], dest[5]); 246 242 ··· 274 272 275 273 vnet_hdr_to_sg(sg, skb); 276 274 num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; 277 - __skb_queue_head(&vi->send, skb); 275 + 276 + return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); 277 + } 278 + 279 + static int start_xmit(struct sk_buff *skb, struct net_device *dev) 280 + { 281 + struct virtnet_info *vi = netdev_priv(dev); 278 282 279 283 again: 280 284 /* Free up any pending old buffers before queueing new ones. */ 281 285 free_old_xmit_skbs(vi); 282 - err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); 283 - if (err) { 284 - pr_debug("%s: virtio not prepared to send\n", dev->name); 285 - netif_stop_queue(dev); 286 286 287 - /* Activate callback for using skbs: if this returns false it 288 - * means some were used in the meantime. */ 289 - if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { 290 - vi->svq->vq_ops->disable_cb(vi->svq); 291 - netif_start_queue(dev); 292 - goto again; 287 + /* If we has a buffer left over from last time, send it now. */ 288 + if (vi->last_xmit_skb) { 289 + if (xmit_skb(vi, vi->last_xmit_skb) != 0) { 290 + /* Drop this skb: we only queue one. */ 291 + vi->dev->stats.tx_dropped++; 292 + kfree_skb(skb); 293 + goto stop_queue; 293 294 } 294 - __skb_unlink(skb, &vi->send); 295 - 296 - return NETDEV_TX_BUSY; 295 + vi->last_xmit_skb = NULL; 297 296 } 298 - vi->svq->vq_ops->kick(vi->svq); 299 297 300 - return 0; 298 + /* Put new one in send queue and do transmit */ 299 + __skb_queue_head(&vi->send, skb); 300 + if (xmit_skb(vi, skb) != 0) { 301 + vi->last_xmit_skb = skb; 302 + goto stop_queue; 303 + } 304 + done: 305 + vi->svq->vq_ops->kick(vi->svq); 306 + return NETDEV_TX_OK; 307 + 308 + stop_queue: 309 + pr_debug("%s: virtio not prepared to send\n", dev->name); 310 + netif_stop_queue(dev); 311 + 312 + /* Activate callback for using skbs: if this returns false it 313 + * means some were used in the meantime. */ 314 + if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { 315 + vi->svq->vq_ops->disable_cb(vi->svq); 316 + netif_start_queue(dev); 317 + goto again; 318 + } 319 + goto done; 301 320 } 302 321 303 322 #ifdef CONFIG_NET_POLL_CONTROLLER ··· 378 355 SET_NETDEV_DEV(dev, &vdev->dev); 379 356 380 357 /* Do we support "hardware" checksums? */ 381 - if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) { 358 + if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { 382 359 /* This opens up the world of extra features. */ 383 360 dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; 384 - if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) { 361 + if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { 385 362 dev->features |= NETIF_F_TSO | NETIF_F_UFO 386 363 | NETIF_F_TSO_ECN | NETIF_F_TSO6; 387 364 } 365 + /* Individual feature bits: what can host handle? */ 366 + if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4)) 367 + dev->features |= NETIF_F_TSO; 368 + if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6)) 369 + dev->features |= NETIF_F_TSO6; 370 + if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) 371 + dev->features |= NETIF_F_TSO_ECN; 372 + if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) 373 + dev->features |= NETIF_F_UFO; 388 374 } 389 375 390 376 /* Configuration may specify what MAC to use. Otherwise random. */ 391 - if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) { 377 + if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) { 392 378 vdev->config->get(vdev, 393 379 offsetof(struct virtio_net_config, mac), 394 380 dev->dev_addr, dev->addr_len); ··· 486 454 { 0 }, 487 455 }; 488 456 457 + static unsigned int features[] = { 458 + VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, 459 + VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, 460 + VIRTIO_NET_F_HOST_ECN, 461 + }; 462 + 489 463 static struct virtio_driver virtio_net = { 464 + .feature_table = features, 465 + .feature_table_size = ARRAY_SIZE(features), 490 466 .driver.name = KBUILD_MODNAME, 491 467 .driver.owner = THIS_MODULE, 492 468 .id_table = id_table,
+36 -2
drivers/virtio/virtio.c
··· 80 80 dev->config->set_status(dev, dev->config->get_status(dev) | status); 81 81 } 82 82 83 + void virtio_check_driver_offered_feature(const struct virtio_device *vdev, 84 + unsigned int fbit) 85 + { 86 + unsigned int i; 87 + struct virtio_driver *drv = container_of(vdev->dev.driver, 88 + struct virtio_driver, driver); 89 + 90 + for (i = 0; i < drv->feature_table_size; i++) 91 + if (drv->feature_table[i] == fbit) 92 + return; 93 + BUG(); 94 + } 95 + EXPORT_SYMBOL_GPL(virtio_check_driver_offered_feature); 96 + 83 97 static int virtio_dev_probe(struct device *_d) 84 98 { 85 - int err; 99 + int err, i; 86 100 struct virtio_device *dev = container_of(_d,struct virtio_device,dev); 87 101 struct virtio_driver *drv = container_of(dev->dev.driver, 88 102 struct virtio_driver, driver); 103 + u32 device_features; 89 104 105 + /* We have a driver! */ 90 106 add_status(dev, VIRTIO_CONFIG_S_DRIVER); 107 + 108 + /* Figure out what features the device supports. */ 109 + device_features = dev->config->get_features(dev); 110 + 111 + /* Features supported by both device and driver into dev->features. */ 112 + memset(dev->features, 0, sizeof(dev->features)); 113 + for (i = 0; i < drv->feature_table_size; i++) { 114 + unsigned int f = drv->feature_table[i]; 115 + BUG_ON(f >= 32); 116 + if (device_features & (1 << f)) 117 + set_bit(f, dev->features); 118 + } 119 + 91 120 err = drv->probe(dev); 92 121 if (err) 93 122 add_status(dev, VIRTIO_CONFIG_S_FAILED); 94 - else 123 + else { 95 124 add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); 125 + /* They should never have set feature bits beyond 32 */ 126 + dev->config->set_features(dev, dev->features[0]); 127 + } 96 128 return err; 97 129 } 98 130 ··· 146 114 147 115 int register_virtio_driver(struct virtio_driver *driver) 148 116 { 117 + /* Catch this early. */ 118 + BUG_ON(driver->feature_table_size && !driver->feature_table); 149 119 driver->driver.bus = &virtio_bus; 150 120 driver->driver.probe = virtio_dev_probe; 151 121 driver->driver.remove = virtio_dev_remove;
+8 -4
drivers/virtio/virtio_balloon.c
··· 155 155 static inline s64 towards_target(struct virtio_balloon *vb) 156 156 { 157 157 u32 v; 158 - __virtio_config_val(vb->vdev, 159 - offsetof(struct virtio_balloon_config, num_pages), 160 - &v); 158 + vb->vdev->config->get(vb->vdev, 159 + offsetof(struct virtio_balloon_config, num_pages), 160 + &v, sizeof(v)); 161 161 return v - vb->num_pages; 162 162 } 163 163 ··· 227 227 } 228 228 229 229 vb->tell_host_first 230 - = vdev->config->feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); 230 + = virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); 231 231 232 232 return 0; 233 233 ··· 259 259 kfree(vb); 260 260 } 261 261 262 + static unsigned int features[] = { VIRTIO_BALLOON_F_MUST_TELL_HOST }; 263 + 262 264 static struct virtio_driver virtio_balloon = { 265 + .feature_table = features, 266 + .feature_table_size = ARRAY_SIZE(features), 263 267 .driver.name = KBUILD_MODNAME, 264 268 .driver.owner = THIS_MODULE, 265 269 .id_table = id_table,
+16 -16
drivers/virtio/virtio_pci.c
··· 87 87 return container_of(vdev, struct virtio_pci_device, vdev); 88 88 } 89 89 90 - /* virtio config->feature() implementation */ 91 - static bool vp_feature(struct virtio_device *vdev, unsigned bit) 90 + /* virtio config->get_features() implementation */ 91 + static u32 vp_get_features(struct virtio_device *vdev) 92 92 { 93 93 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 94 - u32 mask; 95 94 96 - /* Since this function is supposed to have the side effect of 97 - * enabling a queried feature, we simulate that by doing a read 98 - * from the host feature bitmask and then writing to the guest 99 - * feature bitmask */ 100 - mask = ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); 101 - if (mask & (1 << bit)) { 102 - mask |= (1 << bit); 103 - iowrite32(mask, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); 104 - } 95 + /* When someone needs more than 32 feature bits, we'll need to 96 + * steal a bit to indicate that the rest are somewhere else. */ 97 + return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); 98 + } 105 99 106 - return !!(mask & (1 << bit)); 100 + /* virtio config->set_features() implementation */ 101 + static void vp_set_features(struct virtio_device *vdev, u32 features) 102 + { 103 + struct virtio_pci_device *vp_dev = to_vp_device(vdev); 104 + 105 + iowrite32(features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); 107 106 } 108 107 109 108 /* virtio config->get() implementation */ ··· 144 145 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 145 146 /* We should never be setting status to 0. */ 146 147 BUG_ON(status == 0); 147 - return iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); 148 + iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); 148 149 } 149 150 150 151 static void vp_reset(struct virtio_device *vdev) 151 152 { 152 153 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 153 154 /* 0 status means a reset. */ 154 - return iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); 155 + iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); 155 156 } 156 157 157 158 /* the notify function used when creating a virt queue */ ··· 292 293 } 293 294 294 295 static struct virtio_config_ops virtio_pci_config_ops = { 295 - .feature = vp_feature, 296 296 .get = vp_get, 297 297 .set = vp_set, 298 298 .get_status = vp_get_status, ··· 299 301 .reset = vp_reset, 300 302 .find_vq = vp_find_vq, 301 303 .del_vq = vp_del_vq, 304 + .get_features = vp_get_features, 305 + .set_features = vp_set_features, 302 306 }; 303 307 304 308 /* the PCI probing function */
+5
drivers/virtio/virtio_ring.c
··· 184 184 185 185 START_USE(vq); 186 186 187 + if (unlikely(vq->broken)) { 188 + END_USE(vq); 189 + return NULL; 190 + } 191 + 187 192 if (!more_used(vq)) { 188 193 pr_debug("No more buffers in queue\n"); 189 194 END_USE(vq);
+5
include/linux/Kbuild
··· 346 346 unifdef-y += virtio_config.h 347 347 unifdef-y += virtio_blk.h 348 348 unifdef-y += virtio_net.h 349 + unifdef-y += virtio_9p.h 350 + unifdef-y += virtio_balloon.h 351 + unifdef-y += virtio_console.h 352 + unifdef-y += virtio_pci.h 353 + unifdef-y += virtio_ring.h 349 354 unifdef-y += vt.h 350 355 unifdef-y += wait.h 351 356 unifdef-y += wanrouter.h
+7
include/linux/virtio.h
··· 76 76 * @dev: underlying device. 77 77 * @id: the device type identification (used to match it with a driver). 78 78 * @config: the configuration ops for this device. 79 + * @features: the features supported by both driver and device. 79 80 * @priv: private pointer for the driver's use. 80 81 */ 81 82 struct virtio_device ··· 85 84 struct device dev; 86 85 struct virtio_device_id id; 87 86 struct virtio_config_ops *config; 87 + /* Note that this is a Linux set_bit-style bitmap. */ 88 + unsigned long features[1]; 88 89 void *priv; 89 90 }; 90 91 ··· 97 94 * virtio_driver - operations for a virtio I/O driver 98 95 * @driver: underlying device driver (populate name and owner). 99 96 * @id_table: the ids serviced by this driver. 97 + * @feature_table: an array of feature numbers supported by this device. 98 + * @feature_table_size: number of entries in the feature table array. 100 99 * @probe: the function to call when a device is found. Returns a token for 101 100 * remove, or PTR_ERR(). 102 101 * @remove: the function when a device is removed. ··· 108 103 struct virtio_driver { 109 104 struct device_driver driver; 110 105 const struct virtio_device_id *id_table; 106 + const unsigned int *feature_table; 107 + unsigned int feature_table_size; 111 108 int (*probe)(struct virtio_device *dev); 112 109 void (*remove)(struct virtio_device *dev); 113 110 void (*config_changed)(struct virtio_device *dev);
+8 -6
include/linux/virtio_blk.h
··· 9 9 #define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */ 10 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 + #define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */ 12 13 13 14 struct virtio_blk_config 14 15 { ··· 19 18 __le32 size_max; 20 19 /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ 21 20 __le32 seg_max; 21 + /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ 22 + struct virtio_blk_geometry { 23 + __le16 cylinders; 24 + __u8 heads; 25 + __u8 sectors; 26 + } geometry; 22 27 } __attribute__((packed)); 23 28 24 29 /* These two define direction. */ ··· 48 41 __u64 sector; 49 42 }; 50 43 44 + /* And this is the final byte of the write scatter-gather list. */ 51 45 #define VIRTIO_BLK_S_OK 0 52 46 #define VIRTIO_BLK_S_IOERR 1 53 47 #define VIRTIO_BLK_S_UNSUPP 2 54 - 55 - /* This is the first element of the write scatter-gather list */ 56 - struct virtio_blk_inhdr 57 - { 58 - unsigned char status; 59 - }; 60 48 #endif /* _LINUX_VIRTIO_BLK_H */
+44 -37
include/linux/virtio_config.h
··· 16 16 #define VIRTIO_CONFIG_S_FAILED 0x80 17 17 18 18 #ifdef __KERNEL__ 19 - struct virtio_device; 19 + #include <linux/virtio.h> 20 20 21 21 /** 22 22 * virtio_config_ops - operations for configuring a virtio device 23 - * @feature: search for a feature in this config 24 - * vdev: the virtio_device 25 - * bit: the feature bit 26 - * Returns true if the feature is supported. Acknowledges the feature 27 - * so the host can see it. 28 23 * @get: read the value of a configuration field 29 24 * vdev: the virtio_device 30 25 * offset: the offset of the configuration field 31 26 * buf: the buffer to write the field value into. 32 27 * len: the length of the buffer 33 - * Note that contents are conventionally little-endian. 34 28 * @set: write the value of a configuration field 35 29 * vdev: the virtio_device 36 30 * offset: the offset of the configuration field 37 31 * buf: the buffer to read the field value from. 38 32 * len: the length of the buffer 39 - * Note that contents are conventionally little-endian. 40 33 * @get_status: read the status byte 41 34 * vdev: the virtio_device 42 35 * Returns the status byte ··· 45 52 * callback: the virqtueue callback 46 53 * Returns the new virtqueue or ERR_PTR() (eg. -ENOENT). 47 54 * @del_vq: free a virtqueue found by find_vq(). 55 + * @get_features: get the array of feature bits for this device. 56 + * vdev: the virtio_device 57 + * Returns the first 32 feature bits (all we currently need). 58 + * @set_features: confirm what device features we'll be using. 59 + * vdev: the virtio_device 60 + * feature: the first 32 feature bits 48 61 */ 49 62 struct virtio_config_ops 50 63 { 51 - bool (*feature)(struct virtio_device *vdev, unsigned bit); 52 64 void (*get)(struct virtio_device *vdev, unsigned offset, 53 65 void *buf, unsigned len); 54 66 void (*set)(struct virtio_device *vdev, unsigned offset, ··· 65 67 unsigned index, 66 68 void (*callback)(struct virtqueue *)); 67 69 void (*del_vq)(struct virtqueue *vq); 70 + u32 (*get_features)(struct virtio_device *vdev); 71 + void (*set_features)(struct virtio_device *vdev, u32 features); 68 72 }; 69 73 74 + /* If driver didn't advertise the feature, it will never appear. */ 75 + void virtio_check_driver_offered_feature(const struct virtio_device *vdev, 76 + unsigned int fbit); 77 + 70 78 /** 71 - * virtio_config_val - look for a feature and get a single virtio config. 79 + * virtio_has_feature - helper to determine if this device has this feature. 80 + * @vdev: the device 81 + * @fbit: the feature bit 82 + */ 83 + static inline bool virtio_has_feature(const struct virtio_device *vdev, 84 + unsigned int fbit) 85 + { 86 + /* Did you forget to fix assumptions on max features? */ 87 + if (__builtin_constant_p(fbit)) 88 + BUILD_BUG_ON(fbit >= 32); 89 + 90 + virtio_check_driver_offered_feature(vdev, fbit); 91 + return test_bit(fbit, vdev->features); 92 + } 93 + 94 + /** 95 + * virtio_config_val - look for a feature and get a virtio config entry. 72 96 * @vdev: the virtio device 73 97 * @fbit: the feature bit 74 98 * @offset: the type to search for. 75 99 * @val: a pointer to the value to fill in. 76 100 * 77 101 * The return value is -ENOENT if the feature doesn't exist. Otherwise 78 - * the value is endian-corrected and returned in v. */ 79 - #define virtio_config_val(vdev, fbit, offset, v) ({ \ 80 - int _err; \ 81 - if ((vdev)->config->feature((vdev), (fbit))) { \ 82 - __virtio_config_val((vdev), (offset), (v)); \ 83 - _err = 0; \ 84 - } else \ 85 - _err = -ENOENT; \ 86 - _err; \ 87 - }) 102 + * the config value is copied into whatever is pointed to by v. */ 103 + #define virtio_config_val(vdev, fbit, offset, v) \ 104 + virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(v)) 88 105 89 - /** 90 - * __virtio_config_val - get a single virtio config without feature check. 91 - * @vdev: the virtio device 92 - * @offset: the type to search for. 93 - * @val: a pointer to the value to fill in. 94 - * 95 - * The value is endian-corrected and returned in v. */ 96 - #define __virtio_config_val(vdev, offset, v) do { \ 97 - BUILD_BUG_ON(sizeof(*(v)) != 1 && sizeof(*(v)) != 2 \ 98 - && sizeof(*(v)) != 4 && sizeof(*(v)) != 8); \ 99 - (vdev)->config->get((vdev), (offset), (v), sizeof(*(v))); \ 100 - switch (sizeof(*(v))) { \ 101 - case 2: le16_to_cpus((__u16 *) v); break; \ 102 - case 4: le32_to_cpus((__u32 *) v); break; \ 103 - case 8: le64_to_cpus((__u64 *) v); break; \ 104 - } \ 105 - } while(0) 106 + static inline int virtio_config_buf(struct virtio_device *vdev, 107 + unsigned int fbit, 108 + unsigned int offset, 109 + void *buf, unsigned len) 110 + { 111 + if (!virtio_has_feature(vdev, fbit)) 112 + return -ENOENT; 113 + 114 + vdev->config->get(vdev, offset, buf, len); 115 + return 0; 116 + } 106 117 #endif /* __KERNEL__ */ 107 118 #endif /* _LINUX_VIRTIO_CONFIG_H */
+11 -2
include/linux/virtio_net.h
··· 6 6 #define VIRTIO_ID_NET 1 7 7 8 8 /* The feature bitmap for virtio net */ 9 - #define VIRTIO_NET_F_CSUM 0 /* Can handle pkts w/ partial csum */ 9 + #define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */ 10 + #define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */ 10 11 #define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */ 11 - #define VIRTIO_NET_F_GSO 6 /* Can handle pkts w/ any GSO type */ 12 + #define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ 13 + #define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */ 14 + #define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */ 15 + #define VIRTIO_NET_F_GUEST_ECN 9 /* Guest can handle TSO[6] w/ ECN in. */ 16 + #define VIRTIO_NET_F_GUEST_UFO 10 /* Guest can handle UFO in. */ 17 + #define VIRTIO_NET_F_HOST_TSO4 11 /* Host can handle TSOv4 in. */ 18 + #define VIRTIO_NET_F_HOST_TSO6 12 /* Host can handle TSOv6 in. */ 19 + #define VIRTIO_NET_F_HOST_ECN 13 /* Host can handle TSO[6] w/ ECN in. */ 20 + #define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */ 12 21 13 22 struct virtio_net_config 14 23 {