diff --git a/bsp_diff/common/kernel/lts2019-chromium/27_0027-VIRTIO-Freeze-and-Restore-Implementation.patch b/bsp_diff/common/kernel/lts2019-chromium/27_0027-VIRTIO-Freeze-and-Restore-Implementation.patch new file mode 100644 index 0000000000..cd79ece9c8 --- /dev/null +++ b/bsp_diff/common/kernel/lts2019-chromium/27_0027-VIRTIO-Freeze-and-Restore-Implementation.patch @@ -0,0 +1,152 @@ +From ac91eeb67b4f235fee19c000aff27b8e1991ad53 Mon Sep 17 00:00:00 2001 +From: Vilas R K +Date: Wed, 23 Mar 2022 21:05:33 +0530 +Subject: [PATCH] Freeze and Restore Implementation. + +Whenever VM goes for suspend if there are any +active VSOCK connections used to communicate with host +respective vsock connections were unable to resume as +freeze and restore functionality was not implemented i +virtio driver. +This change will fix VSOCK reconnect in case +of Suspend and Resume + +In freeze case: +Change will reset all connected sockets when the devic +disappears and flush all device writes and interrupts +and also delete virtqueues and flush outstanding +callbacks if any. + +In Restore case: +Change will initialize all the necessary parameter to +make the virtio device ready + +Tracked-On: OAM-100107 +Signed-off-by: Stefano Garzarella +Signed-off-by: Bharat Panda +--- + net/vmw_vsock/virtio_transport.c | 100 +++++++++++++++++++++++++++++++ + 1 file changed, 100 insertions(+) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index 9d012817cefc..f505f476973d 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -696,6 +696,104 @@ static void virtio_vsock_remove(struct virtio_device *vdev) + kfree(vsock); + } + ++static int virtio_vsock_freeze(struct virtio_device *vdev) ++{ ++ struct virtio_vsock *vsock = vdev->priv; ++ struct virtio_vsock_pkt *pkt; ++ mutex_lock(&the_virtio_vsock_mutex); ++ rcu_assign_pointer(the_virtio_vsock, NULL); ++ synchronize_rcu(); ++ /* Reset all connected sockets when the device disappear */ ++ // vsock_for_each_connected_socket(&virtio_transport.transport,virtio_vsock_reset_sock); //Original ++ vsock_for_each_connected_socket(virtio_vsock_reset_sock); ++ /* Stop all work handlers to make sure no one is accessing the device, ++ * so we can safely call virtio_reset_device(). ++ */ ++ mutex_lock(&vsock->rx_lock); ++ vsock->rx_run = false; ++ mutex_unlock(&vsock->rx_lock); ++ mutex_lock(&vsock->tx_lock); ++ vsock->tx_run = false; ++ mutex_unlock(&vsock->tx_lock); ++ mutex_lock(&vsock->event_lock); ++ vsock->event_run = false; ++ mutex_unlock(&vsock->event_lock); ++ ++ mutex_lock(&vsock->rx_lock); ++ while ((pkt = virtqueue_detach_unused_buf(vsock->vqs[VSOCK_VQ_RX]))) ++ virtio_transport_free_pkt(pkt); ++ mutex_unlock(&vsock->rx_lock); ++ mutex_lock(&vsock->tx_lock); ++ while ((pkt = virtqueue_detach_unused_buf(vsock->vqs[VSOCK_VQ_TX]))) ++ virtio_transport_free_pkt(pkt); ++ mutex_unlock(&vsock->tx_lock); ++ spin_lock_bh(&vsock->send_pkt_list_lock); ++ while (!list_empty(&vsock->send_pkt_list)) { ++ pkt = list_first_entry(&vsock->send_pkt_list, ++ struct virtio_vsock_pkt, list); ++ list_del(&pkt->list); ++ virtio_transport_free_pkt(pkt); ++ } ++ spin_unlock_bh(&vsock->send_pkt_list_lock); ++ /* Delete virtqueues and flush outstanding callbacks if any */ ++ vdev->config->del_vqs(vdev); ++ ++ /* Other works can be queued before 'config->del_vqs()', so we flush ++ * all works before to free the vsock object to avoid use after free. ++ */ ++ flush_work(&vsock->rx_work); ++ flush_work(&vsock->tx_work); ++ flush_work(&vsock->event_work); ++ flush_work(&vsock->send_pkt_work); ++ ++ mutex_unlock(&the_virtio_vsock_mutex); ++ ++ printk("virtio_vsock_freeze: ok\n"); ++ ++ return 0; ++} ++ ++static int virtio_vsock_restore(struct virtio_device *vdev) ++{ ++ vq_callback_t *callbacks[] = { ++ virtio_vsock_rx_done, ++ virtio_vsock_tx_done, ++ virtio_vsock_event_done, ++ }; ++ static const char * const names[] = { ++ "rx", ++ "tx", ++ "event", ++ }; ++ struct virtio_vsock *vsock = vdev->priv; ++ int ret; ++ mutex_lock(&the_virtio_vsock_mutex); ++ ret = virtio_find_vqs(vsock->vdev, VSOCK_VQ_MAX, ++ vsock->vqs, callbacks, names, ++ NULL); ++ if (ret < 0) ++ goto out; ++ virtio_device_ready(vdev); ++ virtio_vsock_update_guest_cid(vsock); ++ vsock_for_each_connected_socket(virtio_vsock_reset_sock); ++ mutex_lock(&vsock->tx_lock); ++ vsock->tx_run = true; ++ mutex_unlock(&vsock->tx_lock); ++ mutex_lock(&vsock->rx_lock); ++ virtio_vsock_rx_fill(vsock); ++ vsock->rx_run = true; ++ mutex_unlock(&vsock->rx_lock); ++ mutex_lock(&vsock->event_lock); ++ virtio_vsock_event_fill(vsock); ++ vsock->event_run = true; ++ mutex_unlock(&vsock->event_lock); ++ rcu_assign_pointer(the_virtio_vsock, vsock); ++ printk("virtio_vsock_restore: ok\n"); ++ ret = 0; ++out: ++ mutex_unlock(&the_virtio_vsock_mutex); ++ return ret; ++} + static struct virtio_device_id id_table[] = { + { VIRTIO_ID_VSOCK, VIRTIO_DEV_ANY_ID }, + { 0 }, +@@ -712,6 +810,8 @@ static struct virtio_driver virtio_vsock_driver = { + .id_table = id_table, + .probe = virtio_vsock_probe, + .remove = virtio_vsock_remove, ++ .freeze = virtio_vsock_freeze, ++ .restore = virtio_vsock_restore, + }; + + static int __init virtio_vsock_init(void) +-- +2.17.1 +