From bfd1ce30e1c2e8ef6072af0b65df3ae453005c82 Mon Sep 17 00:00:00 2001 From: Alexandru Matei Date: Thu, 9 Nov 2023 14:13:21 +0200 Subject: [PATCH] kernel: Fix vsock packets drop when the vsock driver starts The virtio vsock driver has a small window during initialization where it can silently drop replies to connection requests. Because no reply is sent, kata waits for 10 seconds and in the end it generates a connection timeout error in HybridVSockDialer. Fixes: #8291 Signed-off-by: Alexandru Matei --- tools/packaging/kernel/kata_config_version | 2 +- ...id-potential-deadlock-when-vsock-dev.patch | 73 ++++++ ...sport-cycles-only-on-its-own-sockets.patch | 151 +++++++++++++ ...nitialize-vdev-priv-before-using-VQs.patch | 43 ++++ ...ock-virtio-enable-VQs-early-on-probe.patch | 38 ++++ ...tor-our-the-code-to-initialize-and-d.patch | 210 ++++++++++++++++++ ...dd-support-for-device-suspend-resume.patch | 87 ++++++++ ...tialize-the_virtio_vsock-before-usin.patch | 77 +++++++ ...tialize-the_virtio_vsock-before-usin.patch | 76 +++++++ .../kernel/patches/5.19.x/no_patches.txt | 0 ...tialize-the_virtio_vsock-before-usin.patch | 76 +++++++ .../patches/6.2-TDX-v1.x/no_patches.txt | 0 versions.yaml | 4 +- 13 files changed, 834 insertions(+), 3 deletions(-) create mode 100644 tools/packaging/kernel/patches/5.10.x/0001-vsock-virtio-avoid-potential-deadlock-when-vsock-dev.patch create mode 100644 tools/packaging/kernel/patches/5.10.x/0002-vsock-each-transport-cycles-only-on-its-own-sockets.patch create mode 100644 tools/packaging/kernel/patches/5.10.x/0003-vsock-virtio-initialize-vdev-priv-before-using-VQs.patch create mode 100644 tools/packaging/kernel/patches/5.10.x/0004-vsock-virtio-enable-VQs-early-on-probe.patch create mode 100644 tools/packaging/kernel/patches/5.10.x/0005-vsock-virtio-factor-our-the-code-to-initialize-and-d.patch create mode 100644 tools/packaging/kernel/patches/5.10.x/0006-vsock-virtio-add-support-for-device-suspend-resume.patch create mode 100644 tools/packaging/kernel/patches/5.10.x/0007-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch create mode 100644 tools/packaging/kernel/patches/5.19.x/0001-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch delete mode 100644 tools/packaging/kernel/patches/5.19.x/no_patches.txt create mode 100644 tools/packaging/kernel/patches/6.2-TDX-v1.x/0001-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch delete mode 100644 tools/packaging/kernel/patches/6.2-TDX-v1.x/no_patches.txt diff --git a/tools/packaging/kernel/kata_config_version b/tools/packaging/kernel/kata_config_version index 4699eb3cc96c..5bc6609e3d85 100644 --- a/tools/packaging/kernel/kata_config_version +++ b/tools/packaging/kernel/kata_config_version @@ -1 +1 @@ -116 +117 diff --git a/tools/packaging/kernel/patches/5.10.x/0001-vsock-virtio-avoid-potential-deadlock-when-vsock-dev.patch b/tools/packaging/kernel/patches/5.10.x/0001-vsock-virtio-avoid-potential-deadlock-when-vsock-dev.patch new file mode 100644 index 000000000000..0c1ad7a3e68f --- /dev/null +++ b/tools/packaging/kernel/patches/5.10.x/0001-vsock-virtio-avoid-potential-deadlock-when-vsock-dev.patch @@ -0,0 +1,73 @@ +From d03fb89b5e6dcaf399480708ee2d5a32dca70e7a Mon Sep 17 00:00:00 2001 +From: "Longpeng(Mike)" +Date: Thu, 12 Aug 2021 13:30:56 +0800 +Subject: [PATCH 1/7] vsock/virtio: avoid potential deadlock when vsock device + remove + +There's a potential deadlock case when remove the vsock device or +process the RESET event: + + vsock_for_each_connected_socket: + spin_lock_bh(&vsock_table_lock) ----------- (1) + ... + virtio_vsock_reset_sock: + lock_sock(sk) --------------------- (2) + ... + spin_unlock_bh(&vsock_table_lock) + +lock_sock() may do initiative schedule when the 'sk' is owned by +other thread at the same time, we would receivce a warning message +that "scheduling while atomic". + +Even worse, if the next task (selected by the scheduler) try to +release a 'sk', it need to request vsock_table_lock and the deadlock +occur, cause the system into softlockup state. + Call trace: + queued_spin_lock_slowpath + vsock_remove_bound + vsock_remove_sock + virtio_transport_release + __vsock_release + vsock_release + __sock_release + sock_close + __fput + ____fput + +So we should not require sk_lock in this case, just like the behavior +in vhost_vsock or vmci. + +Fixes: 0ea9e1d3a9e3 ("VSOCK: Introduce virtio_transport.ko") +Cc: Stefan Hajnoczi +Signed-off-by: Longpeng(Mike) +Reviewed-by: Stefano Garzarella +Link: https://lore.kernel.org/r/20210812053056.1699-1-longpeng2@huawei.com +Signed-off-by: Jakub Kicinski +--- + net/vmw_vsock/virtio_transport.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index 2700a63ab095..3a056f8affd1 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -356,11 +356,14 @@ static void virtio_vsock_event_fill(struct virtio_vsock *vsock) + + static void virtio_vsock_reset_sock(struct sock *sk) + { +- lock_sock(sk); ++ /* vmci_transport.c doesn't take sk_lock here either. At least we're ++ * under vsock_table_lock so the sock cannot disappear while we're ++ * executing. ++ */ ++ + sk->sk_state = TCP_CLOSE; + sk->sk_err = ECONNRESET; + sk->sk_error_report(sk); +- release_sock(sk); + } + + static void virtio_vsock_update_guest_cid(struct virtio_vsock *vsock) +-- +2.34.1 + diff --git a/tools/packaging/kernel/patches/5.10.x/0002-vsock-each-transport-cycles-only-on-its-own-sockets.patch b/tools/packaging/kernel/patches/5.10.x/0002-vsock-each-transport-cycles-only-on-its-own-sockets.patch new file mode 100644 index 000000000000..3551420f0aed --- /dev/null +++ b/tools/packaging/kernel/patches/5.10.x/0002-vsock-each-transport-cycles-only-on-its-own-sockets.patch @@ -0,0 +1,151 @@ +From a44b98fc926521d6cf642ed945e1d0781973d0d8 Mon Sep 17 00:00:00 2001 +From: Jiyong Park +Date: Fri, 11 Mar 2022 11:00:16 +0900 +Subject: [PATCH 2/7] vsock: each transport cycles only on its own sockets + +When iterating over sockets using vsock_for_each_connected_socket, make +sure that a transport filters out sockets that don't belong to the +transport. + +There actually was an issue caused by this; in a nested VM +configuration, destroying the nested VM (which often involves the +closing of /dev/vhost-vsock if there was h2g connections to the nested +VM) kills not only the h2g connections, but also all existing g2h +connections to the (outmost) host which are totally unrelated. + +Tested: Executed the following steps on Cuttlefish (Android running on a +VM) [1]: (1) Enter into an `adb shell` session - to have a g2h +connection inside the VM, (2) open and then close /dev/vhost-vsock by +`exec 3< /dev/vhost-vsock && exec 3<&-`, (3) observe that the adb +session is not reset. + +[1] https://android.googlesource.com/device/google/cuttlefish/ + +Fixes: c0cfa2d8a788 ("vsock: add multi-transports support") +Reviewed-by: Stefano Garzarella +Acked-by: Michael S. Tsirkin +Signed-off-by: Jiyong Park +Link: https://lore.kernel.org/r/20220311020017.1509316-1-jiyong@google.com +Signed-off-by: Jakub Kicinski +--- + drivers/vhost/vsock.c | 3 ++- + include/net/af_vsock.h | 3 ++- + net/vmw_vsock/af_vsock.c | 9 +++++++-- + net/vmw_vsock/virtio_transport.c | 7 +++++-- + net/vmw_vsock/vmci_transport.c | 5 ++++- + 5 files changed, 20 insertions(+), 7 deletions(-) + +diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c +index a483cec31d5c..e413aaaca8f9 100644 +--- a/drivers/vhost/vsock.c ++++ b/drivers/vhost/vsock.c +@@ -695,7 +695,8 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file) + + /* Iterating over all connections for all CIDs to find orphans is + * inefficient. Room for improvement here. */ +- vsock_for_each_connected_socket(vhost_vsock_reset_orphans); ++ vsock_for_each_connected_socket(&vhost_transport.transport, ++ vhost_vsock_reset_orphans); + + vhost_vsock_stop(vsock); + vhost_vsock_flush(vsock); +diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h +index b1c717286993..4d8589244dc7 100644 +--- a/include/net/af_vsock.h ++++ b/include/net/af_vsock.h +@@ -197,7 +197,8 @@ struct sock *vsock_find_bound_socket(struct sockaddr_vm *addr); + struct sock *vsock_find_connected_socket(struct sockaddr_vm *src, + struct sockaddr_vm *dst); + void vsock_remove_sock(struct vsock_sock *vsk); +-void vsock_for_each_connected_socket(void (*fn)(struct sock *sk)); ++void vsock_for_each_connected_socket(struct vsock_transport *transport, ++ void (*fn)(struct sock *sk)); + int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk); + bool vsock_find_cid(unsigned int cid); + +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 791955f5e7ec..bc3b85838158 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -333,7 +333,8 @@ void vsock_remove_sock(struct vsock_sock *vsk) + } + EXPORT_SYMBOL_GPL(vsock_remove_sock); + +-void vsock_for_each_connected_socket(void (*fn)(struct sock *sk)) ++void vsock_for_each_connected_socket(struct vsock_transport *transport, ++ void (*fn)(struct sock *sk)) + { + int i; + +@@ -342,8 +343,12 @@ void vsock_for_each_connected_socket(void (*fn)(struct sock *sk)) + for (i = 0; i < ARRAY_SIZE(vsock_connected_table); i++) { + struct vsock_sock *vsk; + list_for_each_entry(vsk, &vsock_connected_table[i], +- connected_table) ++ connected_table) { ++ if (vsk->transport != transport) ++ continue; ++ + fn(sk_vsock(vsk)); ++ } + } + + spin_unlock_bh(&vsock_table_lock); +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index 3a056f8affd1..e131121533ad 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -24,6 +24,7 @@ + static struct workqueue_struct *virtio_vsock_workqueue; + static struct virtio_vsock __rcu *the_virtio_vsock; + static DEFINE_MUTEX(the_virtio_vsock_mutex); /* protects the_virtio_vsock */ ++static struct virtio_transport virtio_transport; /* forward declaration */ + + struct virtio_vsock { + struct virtio_device *vdev; +@@ -383,7 +384,8 @@ static void virtio_vsock_event_handle(struct virtio_vsock *vsock, + switch (le32_to_cpu(event->id)) { + case VIRTIO_VSOCK_EVENT_TRANSPORT_RESET: + virtio_vsock_update_guest_cid(vsock); +- vsock_for_each_connected_socket(virtio_vsock_reset_sock); ++ vsock_for_each_connected_socket(&virtio_transport.transport, ++ virtio_vsock_reset_sock); + break; + } + } +@@ -635,7 +637,8 @@ static void virtio_vsock_remove(struct virtio_device *vdev) + synchronize_rcu(); + + /* Reset all connected sockets when the device disappear */ +- vsock_for_each_connected_socket(virtio_vsock_reset_sock); ++ vsock_for_each_connected_socket(&virtio_transport.transport, ++ virtio_vsock_reset_sock); + + /* Stop all work handlers to make sure no one is accessing the device, + * so we can safely call vdev->config->reset(). +diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c +index 8b65323207db..87de3477cb6d 100644 +--- a/net/vmw_vsock/vmci_transport.c ++++ b/net/vmw_vsock/vmci_transport.c +@@ -75,6 +75,8 @@ static u32 vmci_transport_qp_resumed_sub_id = VMCI_INVALID_ID; + + static int PROTOCOL_OVERRIDE = -1; + ++static struct vsock_transport vmci_transport; /* forward declaration */ ++ + /* Helper function to convert from a VMCI error code to a VSock error code. */ + + static s32 vmci_transport_error_to_vsock_error(s32 vmci_error) +@@ -883,7 +885,8 @@ static void vmci_transport_qp_resumed_cb(u32 sub_id, + const struct vmci_event_data *e_data, + void *client_data) + { +- vsock_for_each_connected_socket(vmci_transport_handle_detach); ++ vsock_for_each_connected_socket(&vmci_transport, ++ vmci_transport_handle_detach); + } + + static void vmci_transport_recv_pkt_work(struct work_struct *work) +-- +2.34.1 + diff --git a/tools/packaging/kernel/patches/5.10.x/0003-vsock-virtio-initialize-vdev-priv-before-using-VQs.patch b/tools/packaging/kernel/patches/5.10.x/0003-vsock-virtio-initialize-vdev-priv-before-using-VQs.patch new file mode 100644 index 000000000000..5075f8e5eaca --- /dev/null +++ b/tools/packaging/kernel/patches/5.10.x/0003-vsock-virtio-initialize-vdev-priv-before-using-VQs.patch @@ -0,0 +1,43 @@ +From d57616af2cfcd67e964f91867cdcc20124b49091 Mon Sep 17 00:00:00 2001 +From: Stefano Garzarella +Date: Wed, 23 Mar 2022 18:36:23 +0100 +Subject: [PATCH 3/7] vsock/virtio: initialize vdev->priv before using VQs + +When we fill VQs with empty buffers and kick the host, it may send +an interrupt. `vdev->priv` must be initialized before this since it +is used in the virtqueue callbacks. + +Fixes: 0deab087b16a ("vsock/virtio: use RCU to avoid use-after-free on the_virtio_vsock") +Suggested-by: Michael S. Tsirkin +Signed-off-by: Stefano Garzarella +Acked-by: Michael S. Tsirkin +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Jakub Kicinski +--- + net/vmw_vsock/virtio_transport.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index e131121533ad..0711aaed17da 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -599,6 +599,8 @@ static int virtio_vsock_probe(struct virtio_device *vdev) + INIT_WORK(&vsock->event_work, virtio_transport_event_work); + INIT_WORK(&vsock->send_pkt_work, virtio_transport_send_pkt_work); + ++ vdev->priv = vsock; ++ + mutex_lock(&vsock->tx_lock); + vsock->tx_run = true; + mutex_unlock(&vsock->tx_lock); +@@ -613,7 +615,6 @@ static int virtio_vsock_probe(struct virtio_device *vdev) + vsock->event_run = true; + mutex_unlock(&vsock->event_lock); + +- vdev->priv = vsock; + rcu_assign_pointer(the_virtio_vsock, vsock); + + mutex_unlock(&the_virtio_vsock_mutex); +-- +2.34.1 + diff --git a/tools/packaging/kernel/patches/5.10.x/0004-vsock-virtio-enable-VQs-early-on-probe.patch b/tools/packaging/kernel/patches/5.10.x/0004-vsock-virtio-enable-VQs-early-on-probe.patch new file mode 100644 index 000000000000..816c1be03752 --- /dev/null +++ b/tools/packaging/kernel/patches/5.10.x/0004-vsock-virtio-enable-VQs-early-on-probe.patch @@ -0,0 +1,38 @@ +From cbb4f49c1f4e761d1d35dab0bbed3b6aed52d456 Mon Sep 17 00:00:00 2001 +From: Stefano Garzarella +Date: Wed, 23 Mar 2022 18:36:25 +0100 +Subject: [PATCH 4/7] vsock/virtio: enable VQs early on probe + +virtio spec requires drivers to set DRIVER_OK before using VQs. +This is set automatically after probe returns, but virtio-vsock +driver uses VQs in the probe function to fill rx and event VQs +with new buffers. + +Let's fix this, calling virtio_device_ready() before using VQs +in the probe function. + +Fixes: 0ea9e1d3a9e3 ("VSOCK: Introduce virtio_transport.ko") +Signed-off-by: Stefano Garzarella +Acked-by: Michael S. Tsirkin +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Jakub Kicinski +--- + net/vmw_vsock/virtio_transport.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index 0711aaed17da..ae22cc8e1b27 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -601,6 +601,8 @@ static int virtio_vsock_probe(struct virtio_device *vdev) + + vdev->priv = vsock; + ++ virtio_device_ready(vdev); ++ + mutex_lock(&vsock->tx_lock); + vsock->tx_run = true; + mutex_unlock(&vsock->tx_lock); +-- +2.34.1 + diff --git a/tools/packaging/kernel/patches/5.10.x/0005-vsock-virtio-factor-our-the-code-to-initialize-and-d.patch b/tools/packaging/kernel/patches/5.10.x/0005-vsock-virtio-factor-our-the-code-to-initialize-and-d.patch new file mode 100644 index 000000000000..02e876aac448 --- /dev/null +++ b/tools/packaging/kernel/patches/5.10.x/0005-vsock-virtio-factor-our-the-code-to-initialize-and-d.patch @@ -0,0 +1,210 @@ +From 31098c59b505a031470341a519e3233987b8b0c9 Mon Sep 17 00:00:00 2001 +From: Stefano Garzarella +Date: Thu, 28 Apr 2022 15:22:40 +0200 +Subject: [PATCH 5/7] vsock/virtio: factor our the code to initialize and + delete VQs + +Add virtio_vsock_vqs_init() and virtio_vsock_vqs_del() with the code +that was in virtio_vsock_probe() and virtio_vsock_remove to initialize +and delete VQs. + +These new functions will be used in the next commit to support device +suspend/resume + +Signed-off-by: Stefano Garzarella +Acked-by: Michael S. Tsirkin +Signed-off-by: Jakub Kicinski +--- + net/vmw_vsock/virtio_transport.c | 143 +++++++++++++++++-------------- + 1 file changed, 81 insertions(+), 62 deletions(-) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index ae22cc8e1b27..dd4af6a56cad 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -543,64 +543,28 @@ static void virtio_transport_rx_work(struct work_struct *work) + mutex_unlock(&vsock->rx_lock); + } + +-static int virtio_vsock_probe(struct virtio_device *vdev) ++static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) + { +- vq_callback_t *callbacks[] = { +- virtio_vsock_rx_done, +- virtio_vsock_tx_done, +- virtio_vsock_event_done, +- }; ++ struct virtio_device *vdev = vsock->vdev; + static const char * const names[] = { + "rx", + "tx", + "event", + }; +- struct virtio_vsock *vsock = NULL; ++ vq_callback_t *callbacks[] = { ++ virtio_vsock_rx_done, ++ virtio_vsock_tx_done, ++ virtio_vsock_event_done, ++ }; + int ret; + +- ret = mutex_lock_interruptible(&the_virtio_vsock_mutex); +- if (ret) +- return ret; +- +- /* Only one virtio-vsock device per guest is supported */ +- if (rcu_dereference_protected(the_virtio_vsock, +- lockdep_is_held(&the_virtio_vsock_mutex))) { +- ret = -EBUSY; +- goto out; +- } +- +- vsock = kzalloc(sizeof(*vsock), GFP_KERNEL); +- if (!vsock) { +- ret = -ENOMEM; +- goto out; +- } +- +- vsock->vdev = vdev; +- +- ret = virtio_find_vqs(vsock->vdev, VSOCK_VQ_MAX, +- vsock->vqs, callbacks, names, ++ ret = virtio_find_vqs(vdev, VSOCK_VQ_MAX, vsock->vqs, callbacks, names, + NULL); + if (ret < 0) +- goto out; ++ return ret; + + virtio_vsock_update_guest_cid(vsock); + +- vsock->rx_buf_nr = 0; +- vsock->rx_buf_max_nr = 0; +- atomic_set(&vsock->queued_replies, 0); +- +- mutex_init(&vsock->tx_lock); +- mutex_init(&vsock->rx_lock); +- mutex_init(&vsock->event_lock); +- spin_lock_init(&vsock->send_pkt_list_lock); +- INIT_LIST_HEAD(&vsock->send_pkt_list); +- INIT_WORK(&vsock->rx_work, virtio_transport_rx_work); +- INIT_WORK(&vsock->tx_work, virtio_transport_tx_work); +- INIT_WORK(&vsock->event_work, virtio_transport_event_work); +- INIT_WORK(&vsock->send_pkt_work, virtio_transport_send_pkt_work); +- +- vdev->priv = vsock; +- + virtio_device_ready(vdev); + + mutex_lock(&vsock->tx_lock); +@@ -617,29 +581,15 @@ static int virtio_vsock_probe(struct virtio_device *vdev) + vsock->event_run = true; + mutex_unlock(&vsock->event_lock); + +- rcu_assign_pointer(the_virtio_vsock, vsock); +- +- mutex_unlock(&the_virtio_vsock_mutex); + return 0; +- +-out: +- kfree(vsock); +- mutex_unlock(&the_virtio_vsock_mutex); +- return ret; + } + +-static void virtio_vsock_remove(struct virtio_device *vdev) ++static void virtio_vsock_vqs_del(struct virtio_vsock *vsock) + { +- struct virtio_vsock *vsock = vdev->priv; ++ struct virtio_device *vdev = vsock->vdev; + struct virtio_vsock_pkt *pkt; + +- mutex_lock(&the_virtio_vsock_mutex); +- +- vdev->priv = NULL; +- rcu_assign_pointer(the_virtio_vsock, NULL); +- synchronize_rcu(); +- +- /* Reset all connected sockets when the device disappear */ ++ /* Reset all connected sockets when the VQs disappear */ + vsock_for_each_connected_socket(&virtio_transport.transport, + virtio_vsock_reset_sock); + +@@ -684,6 +634,75 @@ static void virtio_vsock_remove(struct virtio_device *vdev) + + /* Delete virtqueues and flush outstanding callbacks if any */ + vdev->config->del_vqs(vdev); ++} ++ ++static int virtio_vsock_probe(struct virtio_device *vdev) ++{ ++ struct virtio_vsock *vsock = NULL; ++ int ret; ++ ++ ret = mutex_lock_interruptible(&the_virtio_vsock_mutex); ++ if (ret) ++ return ret; ++ ++ /* Only one virtio-vsock device per guest is supported */ ++ if (rcu_dereference_protected(the_virtio_vsock, ++ lockdep_is_held(&the_virtio_vsock_mutex))) { ++ ret = -EBUSY; ++ goto out; ++ } ++ ++ vsock = kzalloc(sizeof(*vsock), GFP_KERNEL); ++ if (!vsock) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ vsock->vdev = vdev; ++ ++ vsock->rx_buf_nr = 0; ++ vsock->rx_buf_max_nr = 0; ++ atomic_set(&vsock->queued_replies, 0); ++ ++ mutex_init(&vsock->tx_lock); ++ mutex_init(&vsock->rx_lock); ++ mutex_init(&vsock->event_lock); ++ spin_lock_init(&vsock->send_pkt_list_lock); ++ INIT_LIST_HEAD(&vsock->send_pkt_list); ++ INIT_WORK(&vsock->rx_work, virtio_transport_rx_work); ++ INIT_WORK(&vsock->tx_work, virtio_transport_tx_work); ++ INIT_WORK(&vsock->event_work, virtio_transport_event_work); ++ INIT_WORK(&vsock->send_pkt_work, virtio_transport_send_pkt_work); ++ ++ vdev->priv = vsock; ++ ++ ret = virtio_vsock_vqs_init(vsock); ++ if (ret < 0) ++ goto out; ++ ++ rcu_assign_pointer(the_virtio_vsock, vsock); ++ ++ mutex_unlock(&the_virtio_vsock_mutex); ++ ++ return 0; ++ ++out: ++ kfree(vsock); ++ mutex_unlock(&the_virtio_vsock_mutex); ++ return ret; ++} ++ ++static void virtio_vsock_remove(struct virtio_device *vdev) ++{ ++ struct virtio_vsock *vsock = vdev->priv; ++ ++ mutex_lock(&the_virtio_vsock_mutex); ++ ++ vdev->priv = NULL; ++ rcu_assign_pointer(the_virtio_vsock, NULL); ++ synchronize_rcu(); ++ ++ virtio_vsock_vqs_del(vsock); + + /* 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. +-- +2.34.1 + diff --git a/tools/packaging/kernel/patches/5.10.x/0006-vsock-virtio-add-support-for-device-suspend-resume.patch b/tools/packaging/kernel/patches/5.10.x/0006-vsock-virtio-add-support-for-device-suspend-resume.patch new file mode 100644 index 000000000000..2a6f7a414c7f --- /dev/null +++ b/tools/packaging/kernel/patches/5.10.x/0006-vsock-virtio-add-support-for-device-suspend-resume.patch @@ -0,0 +1,87 @@ +From bca7681a7c3461da21ceac2aab05b38a190f8a43 Mon Sep 17 00:00:00 2001 +From: Stefano Garzarella +Date: Thu, 28 Apr 2022 15:22:41 +0200 +Subject: [PATCH 6/7] vsock/virtio: add support for device suspend/resume + +Implement .freeze and .restore callbacks of struct virtio_driver +to support device suspend/resume. + +During suspension all connected sockets are reset and VQs deleted. +During resume the VQs are re-initialized. + +Reported by: Vilas R K +Signed-off-by: Stefano Garzarella +Acked-by: Michael S. Tsirkin +Signed-off-by: Jakub Kicinski +--- + net/vmw_vsock/virtio_transport.c | 47 ++++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index dd4af6a56cad..793c4b1325f1 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -717,6 +717,49 @@ static void virtio_vsock_remove(struct virtio_device *vdev) + kfree(vsock); + } + ++#ifdef CONFIG_PM_SLEEP ++static int virtio_vsock_freeze(struct virtio_device *vdev) ++{ ++ struct virtio_vsock *vsock = vdev->priv; ++ ++ mutex_lock(&the_virtio_vsock_mutex); ++ ++ rcu_assign_pointer(the_virtio_vsock, NULL); ++ synchronize_rcu(); ++ ++ virtio_vsock_vqs_del(vsock); ++ ++ mutex_unlock(&the_virtio_vsock_mutex); ++ ++ return 0; ++} ++ ++static int virtio_vsock_restore(struct virtio_device *vdev) ++{ ++ struct virtio_vsock *vsock = vdev->priv; ++ int ret; ++ ++ mutex_lock(&the_virtio_vsock_mutex); ++ ++ /* Only one virtio-vsock device per guest is supported */ ++ if (rcu_dereference_protected(the_virtio_vsock, ++ lockdep_is_held(&the_virtio_vsock_mutex))) { ++ ret = -EBUSY; ++ goto out; ++ } ++ ++ ret = virtio_vsock_vqs_init(vsock); ++ if (ret < 0) ++ goto out; ++ ++ rcu_assign_pointer(the_virtio_vsock, vsock); ++ ++out: ++ mutex_unlock(&the_virtio_vsock_mutex); ++ return ret; ++} ++#endif /* CONFIG_PM_SLEEP */ ++ + static struct virtio_device_id id_table[] = { + { VIRTIO_ID_VSOCK, VIRTIO_DEV_ANY_ID }, + { 0 }, +@@ -733,6 +776,10 @@ static struct virtio_driver virtio_vsock_driver = { + .id_table = id_table, + .probe = virtio_vsock_probe, + .remove = virtio_vsock_remove, ++#ifdef CONFIG_PM_SLEEP ++ .freeze = virtio_vsock_freeze, ++ .restore = virtio_vsock_restore, ++#endif + }; + + static int __init virtio_vsock_init(void) +-- +2.34.1 + diff --git a/tools/packaging/kernel/patches/5.10.x/0007-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch b/tools/packaging/kernel/patches/5.10.x/0007-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch new file mode 100644 index 000000000000..3f60dd57c4da --- /dev/null +++ b/tools/packaging/kernel/patches/5.10.x/0007-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch @@ -0,0 +1,77 @@ +From a3f1a29e4d773c9a7f2236c623d7567587c1204d Mon Sep 17 00:00:00 2001 +From: Alexandru Matei +Date: Tue, 24 Oct 2023 22:17:42 +0300 +Subject: [PATCH 7/7] vsock/virtio: initialize the_virtio_vsock before using + VQs + +Once VQs are filled with empty buffers and we kick the host, it can send +connection requests. If the_virtio_vsock is not initialized before, +replies are silently dropped and do not reach the host. + +virtio_transport_send_pkt() can queue packets once the_virtio_vsock is +set, but they won't be processed until vsock->tx_run is set to true. We +queue vsock->send_pkt_work when initialization finishes to send those +packets queued earlier. + +Fixes: 0deab087b16a ("vsock/virtio: use RCU to avoid use-after-free on the_virtio_vsock") +Signed-off-by: Alexandru Matei +Reviewed-by: Stefano Garzarella +Link: https://lore.kernel.org/r/20231024191742.14259-1-alexandru.matei@uipath.com +Signed-off-by: Jakub Kicinski +--- + net/vmw_vsock/virtio_transport.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index 793c4b1325f1..25a9f03f0027 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -567,6 +567,11 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) + + virtio_device_ready(vdev); + ++ return 0; ++} ++ ++static void virtio_vsock_vqs_start(struct virtio_vsock *vsock) ++{ + mutex_lock(&vsock->tx_lock); + vsock->tx_run = true; + mutex_unlock(&vsock->tx_lock); +@@ -581,7 +586,16 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) + vsock->event_run = true; + mutex_unlock(&vsock->event_lock); + +- return 0; ++ /* virtio_transport_send_pkt() can queue packets once ++ * the_virtio_vsock is set, but they won't be processed until ++ * vsock->tx_run is set to true. We queue vsock->send_pkt_work ++ * when initialization finishes to send those packets queued ++ * earlier. ++ * We don't need to queue the other workers (rx, event) because ++ * as long as we don't fill the queues with empty buffers, the ++ * host can't send us any notification. ++ */ ++ queue_work(virtio_vsock_workqueue, &vsock->send_pkt_work); + } + + static void virtio_vsock_vqs_del(struct virtio_vsock *vsock) +@@ -681,6 +695,7 @@ static int virtio_vsock_probe(struct virtio_device *vdev) + goto out; + + rcu_assign_pointer(the_virtio_vsock, vsock); ++ virtio_vsock_vqs_start(vsock); + + mutex_unlock(&the_virtio_vsock_mutex); + +@@ -753,6 +768,7 @@ static int virtio_vsock_restore(struct virtio_device *vdev) + goto out; + + rcu_assign_pointer(the_virtio_vsock, vsock); ++ virtio_vsock_vqs_start(vsock); + + out: + mutex_unlock(&the_virtio_vsock_mutex); +-- +2.34.1 + diff --git a/tools/packaging/kernel/patches/5.19.x/0001-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch b/tools/packaging/kernel/patches/5.19.x/0001-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch new file mode 100644 index 000000000000..5fe19e9ea3ab --- /dev/null +++ b/tools/packaging/kernel/patches/5.19.x/0001-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch @@ -0,0 +1,76 @@ +From 0b992e5760051b2083bf7542b84c917b91ec4d41 Mon Sep 17 00:00:00 2001 +From: Alexandru Matei +Date: Tue, 24 Oct 2023 22:17:42 +0300 +Subject: [PATCH] vsock/virtio: initialize the_virtio_vsock before using VQs + +Once VQs are filled with empty buffers and we kick the host, it can send +connection requests. If the_virtio_vsock is not initialized before, +replies are silently dropped and do not reach the host. + +virtio_transport_send_pkt() can queue packets once the_virtio_vsock is +set, but they won't be processed until vsock->tx_run is set to true. We +queue vsock->send_pkt_work when initialization finishes to send those +packets queued earlier. + +Fixes: 0deab087b16a ("vsock/virtio: use RCU to avoid use-after-free on the_virtio_vsock") +Signed-off-by: Alexandru Matei +Reviewed-by: Stefano Garzarella +Link: https://lore.kernel.org/r/20231024191742.14259-1-alexandru.matei@uipath.com +Signed-off-by: Jakub Kicinski +--- + net/vmw_vsock/virtio_transport.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index ad64f403536a..460e7fbb42da 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -590,6 +590,11 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) + + virtio_device_ready(vdev); + ++ return 0; ++} ++ ++static void virtio_vsock_vqs_start(struct virtio_vsock *vsock) ++{ + mutex_lock(&vsock->tx_lock); + vsock->tx_run = true; + mutex_unlock(&vsock->tx_lock); +@@ -604,7 +609,16 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) + vsock->event_run = true; + mutex_unlock(&vsock->event_lock); + +- return 0; ++ /* virtio_transport_send_pkt() can queue packets once ++ * the_virtio_vsock is set, but they won't be processed until ++ * vsock->tx_run is set to true. We queue vsock->send_pkt_work ++ * when initialization finishes to send those packets queued ++ * earlier. ++ * We don't need to queue the other workers (rx, event) because ++ * as long as we don't fill the queues with empty buffers, the ++ * host can't send us any notification. ++ */ ++ queue_work(virtio_vsock_workqueue, &vsock->send_pkt_work); + } + + static void virtio_vsock_vqs_del(struct virtio_vsock *vsock) +@@ -707,6 +721,7 @@ static int virtio_vsock_probe(struct virtio_device *vdev) + goto out; + + rcu_assign_pointer(the_virtio_vsock, vsock); ++ virtio_vsock_vqs_start(vsock); + + mutex_unlock(&the_virtio_vsock_mutex); + +@@ -779,6 +794,7 @@ static int virtio_vsock_restore(struct virtio_device *vdev) + goto out; + + rcu_assign_pointer(the_virtio_vsock, vsock); ++ virtio_vsock_vqs_start(vsock); + + out: + mutex_unlock(&the_virtio_vsock_mutex); +-- +2.34.1 + diff --git a/tools/packaging/kernel/patches/5.19.x/no_patches.txt b/tools/packaging/kernel/patches/5.19.x/no_patches.txt deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tools/packaging/kernel/patches/6.2-TDX-v1.x/0001-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch b/tools/packaging/kernel/patches/6.2-TDX-v1.x/0001-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch new file mode 100644 index 000000000000..3e7ab011e0e7 --- /dev/null +++ b/tools/packaging/kernel/patches/6.2-TDX-v1.x/0001-vsock-virtio-initialize-the_virtio_vsock-before-usin.patch @@ -0,0 +1,76 @@ +From 04ae44b5b30465588074f3475fb37d7cbcdec3fa Mon Sep 17 00:00:00 2001 +From: Alexandru Matei +Date: Tue, 24 Oct 2023 22:17:42 +0300 +Subject: [PATCH] vsock/virtio: initialize the_virtio_vsock before using VQs + +Once VQs are filled with empty buffers and we kick the host, it can send +connection requests. If the_virtio_vsock is not initialized before, +replies are silently dropped and do not reach the host. + +virtio_transport_send_pkt() can queue packets once the_virtio_vsock is +set, but they won't be processed until vsock->tx_run is set to true. We +queue vsock->send_pkt_work when initialization finishes to send those +packets queued earlier. + +Fixes: 0deab087b16a ("vsock/virtio: use RCU to avoid use-after-free on the_virtio_vsock") +Signed-off-by: Alexandru Matei +Reviewed-by: Stefano Garzarella +Link: https://lore.kernel.org/r/20231024191742.14259-1-alexandru.matei@uipath.com +Signed-off-by: Jakub Kicinski +--- + net/vmw_vsock/virtio_transport.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index ad64f403536a..460e7fbb42da 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -590,6 +590,11 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) + + virtio_device_ready(vdev); + ++ return 0; ++} ++ ++static void virtio_vsock_vqs_start(struct virtio_vsock *vsock) ++{ + mutex_lock(&vsock->tx_lock); + vsock->tx_run = true; + mutex_unlock(&vsock->tx_lock); +@@ -604,7 +609,16 @@ static int virtio_vsock_vqs_init(struct virtio_vsock *vsock) + vsock->event_run = true; + mutex_unlock(&vsock->event_lock); + +- return 0; ++ /* virtio_transport_send_pkt() can queue packets once ++ * the_virtio_vsock is set, but they won't be processed until ++ * vsock->tx_run is set to true. We queue vsock->send_pkt_work ++ * when initialization finishes to send those packets queued ++ * earlier. ++ * We don't need to queue the other workers (rx, event) because ++ * as long as we don't fill the queues with empty buffers, the ++ * host can't send us any notification. ++ */ ++ queue_work(virtio_vsock_workqueue, &vsock->send_pkt_work); + } + + static void virtio_vsock_vqs_del(struct virtio_vsock *vsock) +@@ -707,6 +721,7 @@ static int virtio_vsock_probe(struct virtio_device *vdev) + goto out; + + rcu_assign_pointer(the_virtio_vsock, vsock); ++ virtio_vsock_vqs_start(vsock); + + mutex_unlock(&the_virtio_vsock_mutex); + +@@ -779,6 +794,7 @@ static int virtio_vsock_restore(struct virtio_device *vdev) + goto out; + + rcu_assign_pointer(the_virtio_vsock, vsock); ++ virtio_vsock_vqs_start(vsock); + + out: + mutex_unlock(&the_virtio_vsock_mutex); +-- +2.34.1 + diff --git a/tools/packaging/kernel/patches/6.2-TDX-v1.x/no_patches.txt b/tools/packaging/kernel/patches/6.2-TDX-v1.x/no_patches.txt deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/versions.yaml b/versions.yaml index 67a8cad27cf6..cf650b7adc6c 100644 --- a/versions.yaml +++ b/versions.yaml @@ -169,7 +169,7 @@ assets: kernel: description: "Linux kernel optimised for virtual machines" url: "https://cdn.kernel.org/pub/linux/kernel/v6.x/" - version: "v6.1.52" + version: "v6.1.62" sev: description: "Linux kernel that supports SEV and SNP" url: "https://cdn.kernel.org/pub/linux/kernel/v5.x/" @@ -182,7 +182,7 @@ assets: kernel-arm-experimental: description: "Linux kernel with cpu/mem hotplug support on arm64" url: "https://cdn.kernel.org/pub/linux/kernel/v5.x/" - version: "v5.15.7" + version: "v5.15.138" kernel-dragonball-experimental: description: "Linux kernel with Dragonball VMM optimizations like upcall"