| From: "Michael S. Tsirkin" <mst@redhat.com> |
| Date: Fri, 20 Apr 2018 21:00:13 +0300 |
| Subject: virtio_console: reset on out of memory |
| |
| commit 5c60300d68da32ca77f7f978039dc72bfc78b06b upstream. |
| |
| When out of memory and we can't add ctrl vq buffers, |
| probe fails. Unfortunately the error handling is |
| out of spec: it calls del_vqs without bothering |
| to reset the device first. |
| |
| To fix, call the full cleanup function in this case. |
| |
| Signed-off-by: Michael S. Tsirkin <mst@redhat.com> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/char/virtio_console.c | 17 ++++++++++------- |
| 1 file changed, 10 insertions(+), 7 deletions(-) |
| |
| --- a/drivers/char/virtio_console.c |
| +++ b/drivers/char/virtio_console.c |
| @@ -2073,6 +2073,7 @@ static int virtcons_probe(struct virtio_ |
| |
| spin_lock_init(&portdev->ports_lock); |
| INIT_LIST_HEAD(&portdev->ports); |
| + INIT_LIST_HEAD(&portdev->list); |
| |
| INIT_WORK(&portdev->config_work, &config_work_handler); |
| INIT_WORK(&portdev->control_work, &control_work_handler); |
| @@ -2088,8 +2089,15 @@ static int virtcons_probe(struct virtio_ |
| if (!nr_added_bufs) { |
| dev_err(&vdev->dev, |
| "Error allocating buffers for control queue\n"); |
| - err = -ENOMEM; |
| - goto free_vqs; |
| + /* |
| + * The host might want to notify mgmt sw about device |
| + * add failure. |
| + */ |
| + __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, |
| + VIRTIO_CONSOLE_DEVICE_READY, 0); |
| + /* Device was functional: we need full cleanup. */ |
| + virtcons_remove(vdev); |
| + return -ENOMEM; |
| } |
| } else { |
| /* |
| @@ -2120,11 +2128,6 @@ static int virtcons_probe(struct virtio_ |
| |
| return 0; |
| |
| -free_vqs: |
| - /* The host might want to notify mgmt sw about device add failure */ |
| - __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, |
| - VIRTIO_CONSOLE_DEVICE_READY, 0); |
| - remove_vqs(portdev); |
| free_chrdev: |
| unregister_chrdev(portdev->chr_major, "virtio-portsdev"); |
| free: |