diff options
-rw-r--r-- | Documentation/lguest/lguest.c | 9 | ||||
-rw-r--r-- | drivers/block/virtio_blk.c | 10 | ||||
-rw-r--r-- | drivers/lguest/lguest_device.c | 2 | ||||
-rw-r--r-- | drivers/net/virtio_net.c | 12 | ||||
-rw-r--r-- | drivers/virtio/virtio.c | 13 | ||||
-rw-r--r-- | kernel/module.c | 8 |
6 files changed, 41 insertions, 13 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 42008395534d..9b0e322118b5 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -1040,6 +1040,11 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, | |||
1040 | / getpagesize(); | 1040 | / getpagesize(); |
1041 | p = get_pages(pages); | 1041 | p = get_pages(pages); |
1042 | 1042 | ||
1043 | /* Initialize the virtqueue */ | ||
1044 | vq->next = NULL; | ||
1045 | vq->last_avail_idx = 0; | ||
1046 | vq->dev = dev; | ||
1047 | |||
1043 | /* Initialize the configuration. */ | 1048 | /* Initialize the configuration. */ |
1044 | vq->config.num = num_descs; | 1049 | vq->config.num = num_descs; |
1045 | vq->config.irq = devices.next_irq++; | 1050 | vq->config.irq = devices.next_irq++; |
@@ -1057,9 +1062,6 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, | |||
1057 | for (i = &dev->vq; *i; i = &(*i)->next); | 1062 | for (i = &dev->vq; *i; i = &(*i)->next); |
1058 | *i = vq; | 1063 | *i = vq; |
1059 | 1064 | ||
1060 | /* Link virtqueue back to device. */ | ||
1061 | vq->dev = dev; | ||
1062 | |||
1063 | /* Set the routine to call when the Guest does something to this | 1065 | /* Set the routine to call when the Guest does something to this |
1064 | * virtqueue. */ | 1066 | * virtqueue. */ |
1065 | vq->handle_output = handle_output; | 1067 | vq->handle_output = handle_output; |
@@ -1093,6 +1095,7 @@ static struct device *new_device(const char *name, u16 type, int fd, | |||
1093 | dev->desc = new_dev_desc(type); | 1095 | dev->desc = new_dev_desc(type); |
1094 | dev->handle_input = handle_input; | 1096 | dev->handle_input = handle_input; |
1095 | dev->name = name; | 1097 | dev->name = name; |
1098 | dev->vq = NULL; | ||
1096 | return dev; | 1099 | return dev; |
1097 | } | 1100 | } |
1098 | 1101 | ||
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 3cf7129d83e6..924ddd8bccd2 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -223,7 +223,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
223 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); | 223 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); |
224 | if (err) { | 224 | if (err) { |
225 | dev_err(&vdev->dev, "Bad/missing capacity in config\n"); | 225 | dev_err(&vdev->dev, "Bad/missing capacity in config\n"); |
226 | goto out_put_disk; | 226 | goto out_cleanup_queue; |
227 | } | 227 | } |
228 | 228 | ||
229 | /* If capacity is too big, truncate with warning. */ | 229 | /* If capacity is too big, truncate with warning. */ |
@@ -239,7 +239,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
239 | blk_queue_max_segment_size(vblk->disk->queue, v); | 239 | blk_queue_max_segment_size(vblk->disk->queue, v); |
240 | else if (err != -ENOENT) { | 240 | else if (err != -ENOENT) { |
241 | dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); | 241 | dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); |
242 | goto out_put_disk; | 242 | goto out_cleanup_queue; |
243 | } | 243 | } |
244 | 244 | ||
245 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); | 245 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); |
@@ -247,12 +247,14 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
247 | blk_queue_max_hw_segments(vblk->disk->queue, v); | 247 | blk_queue_max_hw_segments(vblk->disk->queue, v); |
248 | else if (err != -ENOENT) { | 248 | else if (err != -ENOENT) { |
249 | dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); | 249 | dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); |
250 | goto out_put_disk; | 250 | goto out_cleanup_queue; |
251 | } | 251 | } |
252 | 252 | ||
253 | add_disk(vblk->disk); | 253 | add_disk(vblk->disk); |
254 | return 0; | 254 | return 0; |
255 | 255 | ||
256 | out_cleanup_queue: | ||
257 | blk_cleanup_queue(vblk->disk->queue); | ||
256 | out_put_disk: | 258 | out_put_disk: |
257 | put_disk(vblk->disk); | 259 | put_disk(vblk->disk); |
258 | out_unregister_blkdev: | 260 | out_unregister_blkdev: |
@@ -277,6 +279,8 @@ static void virtblk_remove(struct virtio_device *vdev) | |||
277 | put_disk(vblk->disk); | 279 | put_disk(vblk->disk); |
278 | unregister_blkdev(major, "virtblk"); | 280 | unregister_blkdev(major, "virtblk"); |
279 | mempool_destroy(vblk->pool); | 281 | mempool_destroy(vblk->pool); |
282 | /* There should be nothing in the queue now, so no need to shutdown */ | ||
283 | vdev->config->del_vq(vblk->vq); | ||
280 | kfree(vblk); | 284 | kfree(vblk); |
281 | } | 285 | } |
282 | 286 | ||
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 66f38722253a..e2eec38c83c2 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c | |||
@@ -247,6 +247,8 @@ static void lg_del_vq(struct virtqueue *vq) | |||
247 | { | 247 | { |
248 | struct lguest_vq_info *lvq = vq->priv; | 248 | struct lguest_vq_info *lvq = vq->priv; |
249 | 249 | ||
250 | /* Release the interrupt */ | ||
251 | free_irq(lvq->config.irq, vq); | ||
250 | /* Tell virtio_ring.c to free the virtqueue. */ | 252 | /* Tell virtio_ring.c to free the virtqueue. */ |
251 | vring_del_virtqueue(vq); | 253 | vring_del_virtqueue(vq); |
252 | /* Unmap the pages containing the ring. */ | 254 | /* Unmap the pages containing the ring. */ |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index a75be57fb209..5413dbf3d4ac 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -198,8 +198,8 @@ again: | |||
198 | if (vi->num < vi->max / 2) | 198 | if (vi->num < vi->max / 2) |
199 | try_fill_recv(vi); | 199 | try_fill_recv(vi); |
200 | 200 | ||
201 | /* All done? */ | 201 | /* Out of packets? */ |
202 | if (!skb) { | 202 | if (received < budget) { |
203 | netif_rx_complete(vi->dev, napi); | 203 | netif_rx_complete(vi->dev, napi); |
204 | if (unlikely(!vi->rvq->vq_ops->restart(vi->rvq)) | 204 | if (unlikely(!vi->rvq->vq_ops->restart(vi->rvq)) |
205 | && netif_rx_reschedule(vi->dev, napi)) | 205 | && netif_rx_reschedule(vi->dev, napi)) |
@@ -404,8 +404,12 @@ free: | |||
404 | 404 | ||
405 | static void virtnet_remove(struct virtio_device *vdev) | 405 | static void virtnet_remove(struct virtio_device *vdev) |
406 | { | 406 | { |
407 | unregister_netdev(vdev->priv); | 407 | struct virtnet_info *vi = vdev->priv; |
408 | free_netdev(vdev->priv); | 408 | |
409 | vdev->config->del_vq(vi->svq); | ||
410 | vdev->config->del_vq(vi->rvq); | ||
411 | unregister_netdev(vi->dev); | ||
412 | free_netdev(vi->dev); | ||
409 | } | 413 | } |
410 | 414 | ||
411 | static struct virtio_device_id id_table[] = { | 415 | static struct virtio_device_id id_table[] = { |
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 15d7787dea87..69d7ea02cd48 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
@@ -96,10 +96,23 @@ static int virtio_dev_probe(struct device *_d) | |||
96 | return err; | 96 | return err; |
97 | } | 97 | } |
98 | 98 | ||
99 | static int virtio_dev_remove(struct device *_d) | ||
100 | { | ||
101 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | ||
102 | struct virtio_driver *drv = container_of(dev->dev.driver, | ||
103 | struct virtio_driver, driver); | ||
104 | |||
105 | dev->config->set_status(dev, dev->config->get_status(dev) | ||
106 | & ~VIRTIO_CONFIG_S_DRIVER); | ||
107 | drv->remove(dev); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
99 | int register_virtio_driver(struct virtio_driver *driver) | 111 | int register_virtio_driver(struct virtio_driver *driver) |
100 | { | 112 | { |
101 | driver->driver.bus = &virtio_bus; | 113 | driver->driver.bus = &virtio_bus; |
102 | driver->driver.probe = virtio_dev_probe; | 114 | driver->driver.probe = virtio_dev_probe; |
115 | driver->driver.remove = virtio_dev_remove; | ||
103 | return driver_register(&driver->driver); | 116 | return driver_register(&driver->driver); |
104 | } | 117 | } |
105 | EXPORT_SYMBOL_GPL(register_virtio_driver); | 118 | EXPORT_SYMBOL_GPL(register_virtio_driver); |
diff --git a/kernel/module.c b/kernel/module.c index 3202c9950073..91fe6958b6e1 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -81,7 +81,8 @@ int unregister_module_notifier(struct notifier_block * nb) | |||
81 | } | 81 | } |
82 | EXPORT_SYMBOL(unregister_module_notifier); | 82 | EXPORT_SYMBOL(unregister_module_notifier); |
83 | 83 | ||
84 | /* We require a truly strong try_module_get() */ | 84 | /* We require a truly strong try_module_get(): 0 means failure due to |
85 | ongoing or failed initialization etc. */ | ||
85 | static inline int strong_try_module_get(struct module *mod) | 86 | static inline int strong_try_module_get(struct module *mod) |
86 | { | 87 | { |
87 | if (mod && mod->state == MODULE_STATE_COMING) | 88 | if (mod && mod->state == MODULE_STATE_COMING) |
@@ -952,7 +953,8 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, | |||
952 | ret = __find_symbol(name, &owner, &crc, | 953 | ret = __find_symbol(name, &owner, &crc, |
953 | !(mod->taints & TAINT_PROPRIETARY_MODULE)); | 954 | !(mod->taints & TAINT_PROPRIETARY_MODULE)); |
954 | if (ret) { | 955 | if (ret) { |
955 | /* use_module can fail due to OOM, or module unloading */ | 956 | /* use_module can fail due to OOM, |
957 | or module initialization or unloading */ | ||
956 | if (!check_version(sechdrs, versindex, name, mod, crc) || | 958 | if (!check_version(sechdrs, versindex, name, mod, crc) || |
957 | !use_module(mod, owner)) | 959 | !use_module(mod, owner)) |
958 | ret = 0; | 960 | ret = 0; |
@@ -1369,7 +1371,7 @@ dup: | |||
1369 | return ret; | 1371 | return ret; |
1370 | } | 1372 | } |
1371 | 1373 | ||
1372 | /* Change all symbols so that sh_value encodes the pointer directly. */ | 1374 | /* Change all symbols so that st_value encodes the pointer directly. */ |
1373 | static int simplify_symbols(Elf_Shdr *sechdrs, | 1375 | static int simplify_symbols(Elf_Shdr *sechdrs, |
1374 | unsigned int symindex, | 1376 | unsigned int symindex, |
1375 | const char *strtab, | 1377 | const char *strtab, |