lkml.org 
[lkml]   [2019]   [Feb]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.20 54/81] vsock/virtio: fix kernel panic after device hot-unplug
    Date
    From: Stefano Garzarella <sgarzare@redhat.com>

    [ Upstream commit 22b5c0b63f32568e130fa2df4ba23efce3eb495b ]

    virtio_vsock_remove() invokes the vsock_core_exit() also if there
    are opened sockets for the AF_VSOCK protocol family. In this way
    the vsock "transport" pointer is set to NULL, triggering the
    kernel panic at the first socket activity.

    This patch move the vsock_core_init()/vsock_core_exit() in the
    virtio_vsock respectively in module_init and module_exit functions,
    that cannot be invoked until there are open sockets.

    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1609699
    Reported-by: Yan Fu <yafu@redhat.com>
    Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
    Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/vmw_vsock/virtio_transport.c | 26 ++++++++++++++++++--------
    1 file changed, 18 insertions(+), 8 deletions(-)

    diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
    index 5d3cce9e8744d..9dae54698737c 100644
    --- a/net/vmw_vsock/virtio_transport.c
    +++ b/net/vmw_vsock/virtio_transport.c
    @@ -75,6 +75,9 @@ static u32 virtio_transport_get_local_cid(void)
    {
    struct virtio_vsock *vsock = virtio_vsock_get();

    + if (!vsock)
    + return VMADDR_CID_ANY;
    +
    return vsock->guest_cid;
    }

    @@ -584,10 +587,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev)

    virtio_vsock_update_guest_cid(vsock);

    - ret = vsock_core_init(&virtio_transport.transport);
    - if (ret < 0)
    - goto out_vqs;
    -
    vsock->rx_buf_nr = 0;
    vsock->rx_buf_max_nr = 0;
    atomic_set(&vsock->queued_replies, 0);
    @@ -618,8 +617,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev)
    mutex_unlock(&the_virtio_vsock_mutex);
    return 0;

    -out_vqs:
    - vsock->vdev->config->del_vqs(vsock->vdev);
    out:
    kfree(vsock);
    mutex_unlock(&the_virtio_vsock_mutex);
    @@ -669,7 +666,6 @@ static void virtio_vsock_remove(struct virtio_device *vdev)

    mutex_lock(&the_virtio_vsock_mutex);
    the_virtio_vsock = NULL;
    - vsock_core_exit();
    mutex_unlock(&the_virtio_vsock_mutex);

    vdev->config->del_vqs(vdev);
    @@ -702,14 +698,28 @@ static int __init virtio_vsock_init(void)
    virtio_vsock_workqueue = alloc_workqueue("virtio_vsock", 0, 0);
    if (!virtio_vsock_workqueue)
    return -ENOMEM;
    +
    ret = register_virtio_driver(&virtio_vsock_driver);
    if (ret)
    - destroy_workqueue(virtio_vsock_workqueue);
    + goto out_wq;
    +
    + ret = vsock_core_init(&virtio_transport.transport);
    + if (ret)
    + goto out_vdr;
    +
    + return 0;
    +
    +out_vdr:
    + unregister_virtio_driver(&virtio_vsock_driver);
    +out_wq:
    + destroy_workqueue(virtio_vsock_workqueue);
    return ret;
    +
    }

    static void __exit virtio_vsock_exit(void)
    {
    + vsock_core_exit();
    unregister_virtio_driver(&virtio_vsock_driver);
    destroy_workqueue(virtio_vsock_workqueue);
    }
    --
    2.19.1
    \
     
     \ /
      Last update: 2019-02-28 16:30    [W:8.814 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site