From: Greg Kroah-Hartman Date: Sat, 3 Oct 2020 14:44:00 +0000 (+0200) Subject: drop 2 patches from 4.9 X-Git-Tag: v4.19.150~49 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=045eda737550c446f99054eddb9177cf37bd555f;p=thirdparty%2Fkernel%2Fstable-queue.git drop 2 patches from 4.9 --- diff --git a/queue-4.9/net-virtio_vsock-enhance-connection-semantics.patch b/queue-4.9/net-virtio_vsock-enhance-connection-semantics.patch deleted file mode 100644 index a4287f7b796..00000000000 --- a/queue-4.9/net-virtio_vsock-enhance-connection-semantics.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 298b295d45688ac79bebe2e87efa96711e2e0bad Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Fri, 14 Feb 2020 12:48:01 +0100 -Subject: net: virtio_vsock: Enhance connection semantics - -From: Sebastien Boeuf - -[ Upstream commit df12eb6d6cd920ab2f0e0a43cd6e1c23a05cea91 ] - -Whenever the vsock backend on the host sends a packet through the RX -queue, it expects an answer on the TX queue. Unfortunately, there is one -case where the host side will hang waiting for the answer and might -effectively never recover if no timeout mechanism was implemented. - -This issue happens when the guest side starts binding to the socket, -which insert a new bound socket into the list of already bound sockets. -At this time, we expect the guest to also start listening, which will -trigger the sk_state to move from TCP_CLOSE to TCP_LISTEN. The problem -occurs if the host side queued a RX packet and triggered an interrupt -right between the end of the binding process and the beginning of the -listening process. In this specific case, the function processing the -packet virtio_transport_recv_pkt() will find a bound socket, which means -it will hit the switch statement checking for the sk_state, but the -state won't be changed into TCP_LISTEN yet, which leads the code to pick -the default statement. This default statement will only free the buffer, -while it should also respond to the host side, by sending a packet on -its TX queue. - -In order to simply fix this unfortunate chain of events, it is important -that in case the default statement is entered, and because at this stage -we know the host side is waiting for an answer, we must send back a -packet containing the operation VIRTIO_VSOCK_OP_RST. - -One could say that a proper timeout mechanism on the host side will be -enough to avoid the backend to hang. But the point of this patch is to -ensure the normal use case will be provided with proper responsiveness -when it comes to establishing the connection. - -Signed-off-by: Sebastien Boeuf -Signed-off-by: David S. Miller -Signed-off-by: Sasha Levin ---- - net/vmw_vsock/virtio_transport_common.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c -index d64285afe68f3..f66bd0510f138 100644 ---- a/net/vmw_vsock/virtio_transport_common.c -+++ b/net/vmw_vsock/virtio_transport_common.c -@@ -986,6 +986,7 @@ void virtio_transport_recv_pkt(struct virtio_transport *t, - virtio_transport_free_pkt(pkt); - break; - default: -+ (void)virtio_transport_reset_no_sock(t, pkt); - virtio_transport_free_pkt(pkt); - break; - } --- -2.25.1 - diff --git a/queue-4.9/series b/queue-4.9/series index 6727896ec49..bdae961aa13 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -1,4 +1,2 @@ vsock-virtio-use-rcu-to-avoid-use-after-free-on-the_.patch vsock-virtio-stop-workers-during-the-.remove.patch -vsock-virtio-add-transport-parameter-to-the-virtio_t.patch -net-virtio_vsock-enhance-connection-semantics.patch diff --git a/queue-4.9/vsock-virtio-add-transport-parameter-to-the-virtio_t.patch b/queue-4.9/vsock-virtio-add-transport-parameter-to-the-virtio_t.patch deleted file mode 100644 index f1d1499a031..00000000000 --- a/queue-4.9/vsock-virtio-add-transport-parameter-to-the-virtio_t.patch +++ /dev/null @@ -1,373 +0,0 @@ -From 00c0b1b3723f51d243538ace6661a31c4e279dc1 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 14 Nov 2019 10:57:40 +0100 -Subject: vsock/virtio: add transport parameter to the - virtio_transport_reset_no_sock() - -From: Stefano Garzarella - -[ Upstream commit 4c7246dc45e2706770d5233f7ce1597a07e069ba ] - -We are going to add 'struct vsock_sock *' parameter to -virtio_transport_get_ops(). - -In some cases, like in the virtio_transport_reset_no_sock(), -we don't have any socket assigned to the packet received, -so we can't use the virtio_transport_get_ops(). - -In order to allow virtio_transport_reset_no_sock() to use the -'.send_pkt' callback from the 'vhost_transport' or 'virtio_transport', -we add the 'struct virtio_transport *' to it and to its caller: -virtio_transport_recv_pkt(). - -We moved the 'vhost_transport' and 'virtio_transport' definition, -to pass their address to the virtio_transport_recv_pkt(). - -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Stefano Garzarella -Signed-off-by: David S. Miller -Signed-off-by: Sasha Levin ---- - drivers/vhost/vsock.c | 94 ++++++++--------- - include/linux/virtio_vsock.h | 3 +- - net/vmw_vsock/virtio_transport.c | 131 ++++++++++++++---------- - net/vmw_vsock/virtio_transport_common.c | 12 +-- - 4 files changed, 134 insertions(+), 106 deletions(-) - -diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c -index 2ac966400c428..554e131d17b3b 100644 ---- a/drivers/vhost/vsock.c -+++ b/drivers/vhost/vsock.c -@@ -349,6 +349,52 @@ static bool vhost_vsock_more_replies(struct vhost_vsock *vsock) - return val < vq->num; - } - -+static struct virtio_transport vhost_transport = { -+ .transport = { -+ .get_local_cid = vhost_transport_get_local_cid, -+ -+ .init = virtio_transport_do_socket_init, -+ .destruct = virtio_transport_destruct, -+ .release = virtio_transport_release, -+ .connect = virtio_transport_connect, -+ .shutdown = virtio_transport_shutdown, -+ .cancel_pkt = vhost_transport_cancel_pkt, -+ -+ .dgram_enqueue = virtio_transport_dgram_enqueue, -+ .dgram_dequeue = virtio_transport_dgram_dequeue, -+ .dgram_bind = virtio_transport_dgram_bind, -+ .dgram_allow = virtio_transport_dgram_allow, -+ -+ .stream_enqueue = virtio_transport_stream_enqueue, -+ .stream_dequeue = virtio_transport_stream_dequeue, -+ .stream_has_data = virtio_transport_stream_has_data, -+ .stream_has_space = virtio_transport_stream_has_space, -+ .stream_rcvhiwat = virtio_transport_stream_rcvhiwat, -+ .stream_is_active = virtio_transport_stream_is_active, -+ .stream_allow = virtio_transport_stream_allow, -+ -+ .notify_poll_in = virtio_transport_notify_poll_in, -+ .notify_poll_out = virtio_transport_notify_poll_out, -+ .notify_recv_init = virtio_transport_notify_recv_init, -+ .notify_recv_pre_block = virtio_transport_notify_recv_pre_block, -+ .notify_recv_pre_dequeue = virtio_transport_notify_recv_pre_dequeue, -+ .notify_recv_post_dequeue = virtio_transport_notify_recv_post_dequeue, -+ .notify_send_init = virtio_transport_notify_send_init, -+ .notify_send_pre_block = virtio_transport_notify_send_pre_block, -+ .notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue, -+ .notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue, -+ -+ .set_buffer_size = virtio_transport_set_buffer_size, -+ .set_min_buffer_size = virtio_transport_set_min_buffer_size, -+ .set_max_buffer_size = virtio_transport_set_max_buffer_size, -+ .get_buffer_size = virtio_transport_get_buffer_size, -+ .get_min_buffer_size = virtio_transport_get_min_buffer_size, -+ .get_max_buffer_size = virtio_transport_get_max_buffer_size, -+ }, -+ -+ .send_pkt = vhost_transport_send_pkt, -+}; -+ - static void vhost_vsock_handle_tx_kick(struct vhost_work *work) - { - struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue, -@@ -402,7 +448,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work) - if (le64_to_cpu(pkt->hdr.src_cid) == vsock->guest_cid && - le64_to_cpu(pkt->hdr.dst_cid) == - vhost_transport_get_local_cid()) -- virtio_transport_recv_pkt(pkt); -+ virtio_transport_recv_pkt(&vhost_transport, pkt); - else - virtio_transport_free_pkt(pkt); - -@@ -745,52 +791,6 @@ static struct miscdevice vhost_vsock_misc = { - .fops = &vhost_vsock_fops, - }; - --static struct virtio_transport vhost_transport = { -- .transport = { -- .get_local_cid = vhost_transport_get_local_cid, -- -- .init = virtio_transport_do_socket_init, -- .destruct = virtio_transport_destruct, -- .release = virtio_transport_release, -- .connect = virtio_transport_connect, -- .shutdown = virtio_transport_shutdown, -- .cancel_pkt = vhost_transport_cancel_pkt, -- -- .dgram_enqueue = virtio_transport_dgram_enqueue, -- .dgram_dequeue = virtio_transport_dgram_dequeue, -- .dgram_bind = virtio_transport_dgram_bind, -- .dgram_allow = virtio_transport_dgram_allow, -- -- .stream_enqueue = virtio_transport_stream_enqueue, -- .stream_dequeue = virtio_transport_stream_dequeue, -- .stream_has_data = virtio_transport_stream_has_data, -- .stream_has_space = virtio_transport_stream_has_space, -- .stream_rcvhiwat = virtio_transport_stream_rcvhiwat, -- .stream_is_active = virtio_transport_stream_is_active, -- .stream_allow = virtio_transport_stream_allow, -- -- .notify_poll_in = virtio_transport_notify_poll_in, -- .notify_poll_out = virtio_transport_notify_poll_out, -- .notify_recv_init = virtio_transport_notify_recv_init, -- .notify_recv_pre_block = virtio_transport_notify_recv_pre_block, -- .notify_recv_pre_dequeue = virtio_transport_notify_recv_pre_dequeue, -- .notify_recv_post_dequeue = virtio_transport_notify_recv_post_dequeue, -- .notify_send_init = virtio_transport_notify_send_init, -- .notify_send_pre_block = virtio_transport_notify_send_pre_block, -- .notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue, -- .notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue, -- -- .set_buffer_size = virtio_transport_set_buffer_size, -- .set_min_buffer_size = virtio_transport_set_min_buffer_size, -- .set_max_buffer_size = virtio_transport_set_max_buffer_size, -- .get_buffer_size = virtio_transport_get_buffer_size, -- .get_min_buffer_size = virtio_transport_get_min_buffer_size, -- .get_max_buffer_size = virtio_transport_get_max_buffer_size, -- }, -- -- .send_pkt = vhost_transport_send_pkt, --}; -- - static int __init vhost_vsock_init(void) - { - int ret; -diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h -index 584f9a647ad4a..0860cf4ae0461 100644 ---- a/include/linux/virtio_vsock.h -+++ b/include/linux/virtio_vsock.h -@@ -148,7 +148,8 @@ virtio_transport_dgram_enqueue(struct vsock_sock *vsk, - - void virtio_transport_destruct(struct vsock_sock *vsk); - --void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt); -+void virtio_transport_recv_pkt(struct virtio_transport *t, -+ struct virtio_vsock_pkt *pkt); - void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt); - void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vsock_pkt *pkt); - u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted); -diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c -index 67aba63b5c96d..43f6c4240b2a8 100644 ---- a/net/vmw_vsock/virtio_transport.c -+++ b/net/vmw_vsock/virtio_transport.c -@@ -271,58 +271,6 @@ static bool virtio_transport_more_replies(struct virtio_vsock *vsock) - return val < virtqueue_get_vring_size(vq); - } - --static void virtio_transport_rx_work(struct work_struct *work) --{ -- struct virtio_vsock *vsock = -- container_of(work, struct virtio_vsock, rx_work); -- struct virtqueue *vq; -- -- vq = vsock->vqs[VSOCK_VQ_RX]; -- -- mutex_lock(&vsock->rx_lock); -- -- if (!vsock->rx_run) -- goto out; -- -- do { -- virtqueue_disable_cb(vq); -- for (;;) { -- struct virtio_vsock_pkt *pkt; -- unsigned int len; -- -- if (!virtio_transport_more_replies(vsock)) { -- /* Stop rx until the device processes already -- * pending replies. Leave rx virtqueue -- * callbacks disabled. -- */ -- goto out; -- } -- -- pkt = virtqueue_get_buf(vq, &len); -- if (!pkt) { -- break; -- } -- -- vsock->rx_buf_nr--; -- -- /* Drop short/long packets */ -- if (unlikely(len < sizeof(pkt->hdr) || -- len > sizeof(pkt->hdr) + pkt->len)) { -- virtio_transport_free_pkt(pkt); -- continue; -- } -- -- pkt->len = len - sizeof(pkt->hdr); -- virtio_transport_recv_pkt(pkt); -- } -- } while (!virtqueue_enable_cb(vq)); -- --out: -- if (vsock->rx_buf_nr < vsock->rx_buf_max_nr / 2) -- virtio_vsock_rx_fill(vsock); -- mutex_unlock(&vsock->rx_lock); --} -- - /* event_lock must be held */ - static int virtio_vsock_event_fill_one(struct virtio_vsock *vsock, - struct virtio_vsock_event *event) -@@ -485,6 +433,85 @@ static struct virtio_transport virtio_transport = { - .send_pkt = virtio_transport_send_pkt, - }; - -+static void virtio_transport_loopback_work(struct work_struct *work) -+{ -+ struct virtio_vsock *vsock = -+ container_of(work, struct virtio_vsock, loopback_work); -+ LIST_HEAD(pkts); -+ -+ spin_lock_bh(&vsock->loopback_list_lock); -+ list_splice_init(&vsock->loopback_list, &pkts); -+ spin_unlock_bh(&vsock->loopback_list_lock); -+ -+ mutex_lock(&vsock->rx_lock); -+ -+ if (!vsock->rx_run) -+ goto out; -+ -+ while (!list_empty(&pkts)) { -+ struct virtio_vsock_pkt *pkt; -+ -+ pkt = list_first_entry(&pkts, struct virtio_vsock_pkt, list); -+ list_del_init(&pkt->list); -+ -+ virtio_transport_recv_pkt(&virtio_transport, pkt); -+ } -+out: -+ mutex_unlock(&vsock->rx_lock); -+} -+ -+static void virtio_transport_rx_work(struct work_struct *work) -+{ -+ struct virtio_vsock *vsock = -+ container_of(work, struct virtio_vsock, rx_work); -+ struct virtqueue *vq; -+ -+ vq = vsock->vqs[VSOCK_VQ_RX]; -+ -+ mutex_lock(&vsock->rx_lock); -+ -+ if (!vsock->rx_run) -+ goto out; -+ -+ do { -+ virtqueue_disable_cb(vq); -+ for (;;) { -+ struct virtio_vsock_pkt *pkt; -+ unsigned int len; -+ -+ if (!virtio_transport_more_replies(vsock)) { -+ /* Stop rx until the device processes already -+ * pending replies. Leave rx virtqueue -+ * callbacks disabled. -+ */ -+ goto out; -+ } -+ -+ pkt = virtqueue_get_buf(vq, &len); -+ if (!pkt) { -+ break; -+ } -+ -+ vsock->rx_buf_nr--; -+ -+ /* Drop short/long packets */ -+ if (unlikely(len < sizeof(pkt->hdr) || -+ len > sizeof(pkt->hdr) + pkt->len)) { -+ virtio_transport_free_pkt(pkt); -+ continue; -+ } -+ -+ pkt->len = len - sizeof(pkt->hdr); -+ virtio_transport_recv_pkt(&virtio_transport, pkt); -+ } -+ } while (!virtqueue_enable_cb(vq)); -+ -+out: -+ if (vsock->rx_buf_nr < vsock->rx_buf_max_nr / 2) -+ virtio_vsock_rx_fill(vsock); -+ mutex_unlock(&vsock->rx_lock); -+} -+ - static int virtio_vsock_probe(struct virtio_device *vdev) - { - vq_callback_t *callbacks[] = { -diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c -index aa9d1c7780c3d..d64285afe68f3 100644 ---- a/net/vmw_vsock/virtio_transport_common.c -+++ b/net/vmw_vsock/virtio_transport_common.c -@@ -599,9 +599,9 @@ static int virtio_transport_reset(struct vsock_sock *vsk, - /* Normally packets are associated with a socket. There may be no socket if an - * attempt was made to connect to a socket that does not exist. - */ --static int virtio_transport_reset_no_sock(struct virtio_vsock_pkt *pkt) -+static int virtio_transport_reset_no_sock(const struct virtio_transport *t, -+ struct virtio_vsock_pkt *pkt) - { -- const struct virtio_transport *t; - struct virtio_vsock_pkt *reply; - struct virtio_vsock_pkt_info info = { - .op = VIRTIO_VSOCK_OP_RST, -@@ -621,7 +621,6 @@ static int virtio_transport_reset_no_sock(struct virtio_vsock_pkt *pkt) - if (!reply) - return -ENOMEM; - -- t = virtio_transport_get_ops(); - if (!t) { - virtio_transport_free_pkt(reply); - return -ENOTCONN; -@@ -919,7 +918,8 @@ static bool virtio_transport_space_update(struct sock *sk, - /* We are under the virtio-vsock's vsock->rx_lock or vhost-vsock's vq->mutex - * lock. - */ --void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt) -+void virtio_transport_recv_pkt(struct virtio_transport *t, -+ struct virtio_vsock_pkt *pkt) - { - struct sockaddr_vm src, dst; - struct vsock_sock *vsk; -@@ -941,7 +941,7 @@ void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt) - le32_to_cpu(pkt->hdr.fwd_cnt)); - - if (le16_to_cpu(pkt->hdr.type) != VIRTIO_VSOCK_TYPE_STREAM) { -- (void)virtio_transport_reset_no_sock(pkt); -+ (void)virtio_transport_reset_no_sock(t, pkt); - goto free_pkt; - } - -@@ -952,7 +952,7 @@ void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt) - if (!sk) { - sk = vsock_find_bound_socket(&dst); - if (!sk) { -- (void)virtio_transport_reset_no_sock(pkt); -+ (void)virtio_transport_reset_no_sock(t, pkt); - goto free_pkt; - } - } --- -2.25.1 -