* [PATCH v4 0/9] vsock/virtio: SKB allocation improvements
@ 2025-07-17 9:01 Will Deacon
2025-07-17 9:01 ` [PATCH v4 1/9] vhost/vsock: Avoid allocating arbitrarily-sized SKBs Will Deacon
` (10 more replies)
0 siblings, 11 replies; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization
Hi all,
Here is version four of the patches I previously posted here:
v1: https://lore.kernel.org/r/20250625131543.5155-1-will@kernel.org
v2: https://lore.kernel.org/r/20250701164507.14883-1-will@kernel.org
v3: https://lore.kernel.org/r/20250714152103.6949-1-will@kernel.org
There are only two minor changes since v3:
* Use unlikely() in payload length check on the virtio rx path
* Add R-b tags from Stefano
Cheers,
Will
Cc: Keir Fraser <keirf@google.com>
Cc: Steven Moreland <smoreland@google.com>
Cc: Frederick Mayle <fmayle@google.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Stefano Garzarella <sgarzare@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: "Eugenio Pérez" <eperezma@redhat.com>
Cc: linux-kernel@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: virtualization@lists.linux.dev
--->8
Will Deacon (9):
vhost/vsock: Avoid allocating arbitrarily-sized SKBs
vsock/virtio: Validate length in packet header before skb_put()
vsock/virtio: Move length check to callers of
virtio_vsock_skb_rx_put()
vsock/virtio: Resize receive buffers so that each SKB fits in a 4K
page
vsock/virtio: Rename virtio_vsock_alloc_skb()
vsock/virtio: Move SKB allocation lower-bound check to callers
vhost/vsock: Allocate nonlinear SKBs for handling large receive
buffers
vsock/virtio: Rename virtio_vsock_skb_rx_put()
vsock/virtio: Allocate nonlinear SKBs for handling large transmit
buffers
drivers/vhost/vsock.c | 15 ++++----
include/linux/virtio_vsock.h | 46 +++++++++++++++++++------
net/vmw_vsock/virtio_transport.c | 20 ++++++++---
net/vmw_vsock/virtio_transport_common.c | 3 +-
4 files changed, 60 insertions(+), 24 deletions(-)
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v4 1/9] vhost/vsock: Avoid allocating arbitrarily-sized SKBs
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
@ 2025-07-17 9:01 ` Will Deacon
2025-07-17 9:10 ` Jason Wang
2025-07-17 9:01 ` [PATCH v4 2/9] vsock/virtio: Validate length in packet header before skb_put() Will Deacon
` (9 subsequent siblings)
10 siblings, 1 reply; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization, stable
vhost_vsock_alloc_skb() returns NULL for packets advertising a length
larger than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE in the packet header. However,
this is only checked once the SKB has been allocated and, if the length
in the packet header is zero, the SKB may not be freed immediately.
Hoist the size check before the SKB allocation so that an iovec larger
than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + the header size is rejected
outright. The subsequent check on the length field in the header can
then simply check that the allocated SKB is indeed large enough to hold
the packet.
Cc: <stable@vger.kernel.org>
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
drivers/vhost/vsock.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 802153e23073..66a0f060770e 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -344,6 +344,9 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
len = iov_length(vq->iov, out);
+ if (len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM)
+ return NULL;
+
/* len contains both payload and hdr */
skb = virtio_vsock_alloc_skb(len, GFP_KERNEL);
if (!skb)
@@ -367,8 +370,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
return skb;
/* The pkt is too big or the length in the header is invalid */
- if (payload_len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE ||
- payload_len + sizeof(*hdr) > len) {
+ if (payload_len + sizeof(*hdr) > len) {
kfree_skb(skb);
return NULL;
}
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 2/9] vsock/virtio: Validate length in packet header before skb_put()
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
2025-07-17 9:01 ` [PATCH v4 1/9] vhost/vsock: Avoid allocating arbitrarily-sized SKBs Will Deacon
@ 2025-07-17 9:01 ` Will Deacon
2025-07-17 9:39 ` Stefano Garzarella
2025-07-17 9:01 ` [PATCH v4 3/9] vsock/virtio: Move length check to callers of virtio_vsock_skb_rx_put() Will Deacon
` (8 subsequent siblings)
10 siblings, 1 reply; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization, stable
When receiving a vsock packet in the guest, only the virtqueue buffer
size is validated prior to virtio_vsock_skb_rx_put(). Unfortunately,
virtio_vsock_skb_rx_put() uses the length from the packet header as the
length argument to skb_put(), potentially resulting in SKB overflow if
the host has gone wonky.
Validate the length as advertised by the packet header before calling
virtio_vsock_skb_rx_put().
Cc: <stable@vger.kernel.org>
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
Signed-off-by: Will Deacon <will@kernel.org>
---
net/vmw_vsock/virtio_transport.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index f0e48e6911fc..eb08a393413d 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -624,8 +624,9 @@ static void virtio_transport_rx_work(struct work_struct *work)
do {
virtqueue_disable_cb(vq);
for (;;) {
+ unsigned int len, payload_len;
+ struct virtio_vsock_hdr *hdr;
struct sk_buff *skb;
- unsigned int len;
if (!virtio_transport_more_replies(vsock)) {
/* Stop rx until the device processes already
@@ -642,12 +643,19 @@ static void virtio_transport_rx_work(struct work_struct *work)
vsock->rx_buf_nr--;
/* Drop short/long packets */
- if (unlikely(len < sizeof(struct virtio_vsock_hdr) ||
+ if (unlikely(len < sizeof(*hdr) ||
len > virtio_vsock_skb_len(skb))) {
kfree_skb(skb);
continue;
}
+ hdr = virtio_vsock_hdr(skb);
+ payload_len = le32_to_cpu(hdr->len);
+ if (unlikely(payload_len > len - sizeof(*hdr))) {
+ kfree_skb(skb);
+ continue;
+ }
+
virtio_vsock_skb_rx_put(skb);
virtio_transport_deliver_tap_pkt(skb);
virtio_transport_recv_pkt(&virtio_transport, skb);
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 3/9] vsock/virtio: Move length check to callers of virtio_vsock_skb_rx_put()
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
2025-07-17 9:01 ` [PATCH v4 1/9] vhost/vsock: Avoid allocating arbitrarily-sized SKBs Will Deacon
2025-07-17 9:01 ` [PATCH v4 2/9] vsock/virtio: Validate length in packet header before skb_put() Will Deacon
@ 2025-07-17 9:01 ` Will Deacon
2025-07-17 9:01 ` [PATCH v4 4/9] vsock/virtio: Resize receive buffers so that each SKB fits in a 4K page Will Deacon
` (7 subsequent siblings)
10 siblings, 0 replies; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization
virtio_vsock_skb_rx_put() only calls skb_put() if the length in the
packet header is not zero even though skb_put() handles this case
gracefully.
Remove the functionally redundant check from virtio_vsock_skb_rx_put()
and, on the assumption that this is a worthwhile optimisation for
handling credit messages, augment the existing length checks in
virtio_transport_rx_work() to elide the call for zero-length payloads.
Since the callers all have the length, extend virtio_vsock_skb_rx_put()
to take it as an additional parameter rather than fish it back out of
the packet header.
Note that the vhost code already has similar logic in
vhost_vsock_alloc_skb().
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
drivers/vhost/vsock.c | 2 +-
include/linux/virtio_vsock.h | 9 ++-------
net/vmw_vsock/virtio_transport.c | 4 +++-
3 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 66a0f060770e..4c4a642945eb 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -375,7 +375,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
return NULL;
}
- virtio_vsock_skb_rx_put(skb);
+ virtio_vsock_skb_rx_put(skb, payload_len);
nbytes = copy_from_iter(skb->data, payload_len, &iov_iter);
if (nbytes != payload_len) {
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 36fb3edfa403..97465f378ade 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -47,14 +47,9 @@ static inline void virtio_vsock_skb_clear_tap_delivered(struct sk_buff *skb)
VIRTIO_VSOCK_SKB_CB(skb)->tap_delivered = false;
}
-static inline void virtio_vsock_skb_rx_put(struct sk_buff *skb)
+static inline void virtio_vsock_skb_rx_put(struct sk_buff *skb, u32 len)
{
- u32 len;
-
- len = le32_to_cpu(virtio_vsock_hdr(skb)->len);
-
- if (len > 0)
- skb_put(skb, len);
+ skb_put(skb, len);
}
static inline struct sk_buff *virtio_vsock_alloc_skb(unsigned int size, gfp_t mask)
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index eb08a393413d..0166919f8705 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -656,7 +656,9 @@ static void virtio_transport_rx_work(struct work_struct *work)
continue;
}
- virtio_vsock_skb_rx_put(skb);
+ if (payload_len)
+ virtio_vsock_skb_rx_put(skb, payload_len);
+
virtio_transport_deliver_tap_pkt(skb);
virtio_transport_recv_pkt(&virtio_transport, skb);
}
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 4/9] vsock/virtio: Resize receive buffers so that each SKB fits in a 4K page
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
` (2 preceding siblings ...)
2025-07-17 9:01 ` [PATCH v4 3/9] vsock/virtio: Move length check to callers of virtio_vsock_skb_rx_put() Will Deacon
@ 2025-07-17 9:01 ` Will Deacon
2025-07-17 9:01 ` [PATCH v4 5/9] vsock/virtio: Rename virtio_vsock_alloc_skb() Will Deacon
` (6 subsequent siblings)
10 siblings, 0 replies; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization
When allocating receive buffers for the vsock virtio RX virtqueue, an
SKB is allocated with a 4140 data payload (the 44-byte packet header +
VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE). Even when factoring in the SKB
overhead, the resulting 8KiB allocation thanks to the rounding in
kmalloc_reserve() is wasteful (~3700 unusable bytes) and results in a
higher-order page allocation on systems with 4KiB pages just for the
sake of a few hundred bytes of packet data.
Limit the vsock virtio RX buffers to 4KiB per SKB, resulting in much
better memory utilisation and removing the need to allocate higher-order
pages entirely.
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/virtio_vsock.h | 7 ++++++-
net/vmw_vsock/virtio_transport.c | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 97465f378ade..879f1dfa7d3a 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -106,7 +106,12 @@ static inline size_t virtio_vsock_skb_len(struct sk_buff *skb)
return (size_t)(skb_end_pointer(skb) - skb->head);
}
-#define VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE (1024 * 4)
+/* Dimension the RX SKB so that the entire thing fits exactly into
+ * a single 4KiB page. This avoids wasting memory due to alloc_skb()
+ * rounding up to the next page order and also means that we
+ * don't leave higher-order pages sitting around in the RX queue.
+ */
+#define VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE SKB_WITH_OVERHEAD(1024 * 4)
#define VIRTIO_VSOCK_MAX_BUF_SIZE 0xFFFFFFFFUL
#define VIRTIO_VSOCK_MAX_PKT_BUF_SIZE (1024 * 64)
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index 0166919f8705..39f346890f7f 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -307,7 +307,7 @@ virtio_transport_cancel_pkt(struct vsock_sock *vsk)
static void virtio_vsock_rx_fill(struct virtio_vsock *vsock)
{
- int total_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM;
+ int total_len = VIRTIO_VSOCK_DEFAULT_RX_BUF_SIZE;
struct scatterlist pkt, *p;
struct virtqueue *vq;
struct sk_buff *skb;
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 5/9] vsock/virtio: Rename virtio_vsock_alloc_skb()
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
` (3 preceding siblings ...)
2025-07-17 9:01 ` [PATCH v4 4/9] vsock/virtio: Resize receive buffers so that each SKB fits in a 4K page Will Deacon
@ 2025-07-17 9:01 ` Will Deacon
2025-07-17 9:01 ` [PATCH v4 6/9] vsock/virtio: Move SKB allocation lower-bound check to callers Will Deacon
` (5 subsequent siblings)
10 siblings, 0 replies; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization
In preparation for nonlinear allocations for large SKBs, rename
virtio_vsock_alloc_skb() to virtio_vsock_alloc_linear_skb() to indicate
that it returns linear SKBs unconditionally and switch all callers over
to this new interface for now.
No functional change.
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
drivers/vhost/vsock.c | 2 +-
include/linux/virtio_vsock.h | 3 ++-
net/vmw_vsock/virtio_transport.c | 2 +-
net/vmw_vsock/virtio_transport_common.c | 2 +-
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 4c4a642945eb..1ad96613680e 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -348,7 +348,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
return NULL;
/* len contains both payload and hdr */
- skb = virtio_vsock_alloc_skb(len, GFP_KERNEL);
+ skb = virtio_vsock_alloc_linear_skb(len, GFP_KERNEL);
if (!skb)
return NULL;
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 879f1dfa7d3a..4504ea29ff82 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -52,7 +52,8 @@ static inline void virtio_vsock_skb_rx_put(struct sk_buff *skb, u32 len)
skb_put(skb, len);
}
-static inline struct sk_buff *virtio_vsock_alloc_skb(unsigned int size, gfp_t mask)
+static inline struct sk_buff *
+virtio_vsock_alloc_linear_skb(unsigned int size, gfp_t mask)
{
struct sk_buff *skb;
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index 39f346890f7f..80dcf6ac1e72 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -316,7 +316,7 @@ static void virtio_vsock_rx_fill(struct virtio_vsock *vsock)
vq = vsock->vqs[VSOCK_VQ_RX];
do {
- skb = virtio_vsock_alloc_skb(total_len, GFP_KERNEL);
+ skb = virtio_vsock_alloc_linear_skb(total_len, GFP_KERNEL);
if (!skb)
break;
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index 1b5d9896edae..c9eb7f7ac00d 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -261,7 +261,7 @@ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *
if (!zcopy)
skb_len += payload_len;
- skb = virtio_vsock_alloc_skb(skb_len, GFP_KERNEL);
+ skb = virtio_vsock_alloc_linear_skb(skb_len, GFP_KERNEL);
if (!skb)
return NULL;
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 6/9] vsock/virtio: Move SKB allocation lower-bound check to callers
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
` (4 preceding siblings ...)
2025-07-17 9:01 ` [PATCH v4 5/9] vsock/virtio: Rename virtio_vsock_alloc_skb() Will Deacon
@ 2025-07-17 9:01 ` Will Deacon
2025-07-17 9:01 ` [PATCH v4 7/9] vhost/vsock: Allocate nonlinear SKBs for handling large receive buffers Will Deacon
` (4 subsequent siblings)
10 siblings, 0 replies; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization
virtio_vsock_alloc_linear_skb() checks that the requested size is at
least big enough for the packet header (VIRTIO_VSOCK_SKB_HEADROOM).
Of the three callers of virtio_vsock_alloc_linear_skb(), only
vhost_vsock_alloc_skb() can potentially pass a packet smaller than the
header size and, as it already has a check against the maximum packet
size, extend its bounds checking to consider the minimum packet size
and remove the check from virtio_vsock_alloc_linear_skb().
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
drivers/vhost/vsock.c | 3 ++-
include/linux/virtio_vsock.h | 3 ---
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 1ad96613680e..24b7547b05a6 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -344,7 +344,8 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
len = iov_length(vq->iov, out);
- if (len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM)
+ if (len < VIRTIO_VSOCK_SKB_HEADROOM ||
+ len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM)
return NULL;
/* len contains both payload and hdr */
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 4504ea29ff82..36dd0cd55368 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -57,9 +57,6 @@ virtio_vsock_alloc_linear_skb(unsigned int size, gfp_t mask)
{
struct sk_buff *skb;
- if (size < VIRTIO_VSOCK_SKB_HEADROOM)
- return NULL;
-
skb = alloc_skb(size, mask);
if (!skb)
return NULL;
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 7/9] vhost/vsock: Allocate nonlinear SKBs for handling large receive buffers
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
` (5 preceding siblings ...)
2025-07-17 9:01 ` [PATCH v4 6/9] vsock/virtio: Move SKB allocation lower-bound check to callers Will Deacon
@ 2025-07-17 9:01 ` Will Deacon
2025-07-17 9:01 ` [PATCH v4 8/9] vsock/virtio: Rename virtio_vsock_skb_rx_put() Will Deacon
` (3 subsequent siblings)
10 siblings, 0 replies; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization
When receiving a packet from a guest, vhost_vsock_handle_tx_kick()
calls vhost_vsock_alloc_linear_skb() to allocate and fill an SKB with
the receive data. Unfortunately, these are always linear allocations and
can therefore result in significant pressure on kmalloc() considering
that the maximum packet size (VIRTIO_VSOCK_MAX_PKT_BUF_SIZE +
VIRTIO_VSOCK_SKB_HEADROOM) is a little over 64KiB, resulting in a 128KiB
allocation for each packet.
Rework the vsock SKB allocation so that, for sizes with page order
greater than PAGE_ALLOC_COSTLY_ORDER, a nonlinear SKB is allocated
instead with the packet header in the SKB and the receive data in the
fragments. Finally, add a debug warning if virtio_vsock_skb_rx_put() is
ever called on an SKB with a non-zero length, as this would be
destructive for the nonlinear case.
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
drivers/vhost/vsock.c | 8 +++-----
include/linux/virtio_vsock.h | 40 +++++++++++++++++++++++++++++-------
2 files changed, 36 insertions(+), 12 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 24b7547b05a6..0679a706ebc0 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -349,7 +349,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
return NULL;
/* len contains both payload and hdr */
- skb = virtio_vsock_alloc_linear_skb(len, GFP_KERNEL);
+ skb = virtio_vsock_alloc_skb(len, GFP_KERNEL);
if (!skb)
return NULL;
@@ -378,10 +378,8 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
virtio_vsock_skb_rx_put(skb, payload_len);
- nbytes = copy_from_iter(skb->data, payload_len, &iov_iter);
- if (nbytes != payload_len) {
- vq_err(vq, "Expected %zu byte payload, got %zu bytes\n",
- payload_len, nbytes);
+ if (skb_copy_datagram_from_iter(skb, 0, &iov_iter, payload_len)) {
+ vq_err(vq, "Failed to copy %zu byte payload\n", payload_len);
kfree_skb(skb);
return NULL;
}
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index 36dd0cd55368..fa5934ea9c81 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -49,20 +49,46 @@ static inline void virtio_vsock_skb_clear_tap_delivered(struct sk_buff *skb)
static inline void virtio_vsock_skb_rx_put(struct sk_buff *skb, u32 len)
{
- skb_put(skb, len);
+ DEBUG_NET_WARN_ON_ONCE(skb->len);
+
+ if (skb_is_nonlinear(skb))
+ skb->len = len;
+ else
+ skb_put(skb, len);
+}
+
+static inline struct sk_buff *
+__virtio_vsock_alloc_skb_with_frags(unsigned int header_len,
+ unsigned int data_len,
+ gfp_t mask)
+{
+ struct sk_buff *skb;
+ int err;
+
+ skb = alloc_skb_with_frags(header_len, data_len,
+ PAGE_ALLOC_COSTLY_ORDER, &err, mask);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, VIRTIO_VSOCK_SKB_HEADROOM);
+ skb->data_len = data_len;
+ return skb;
}
static inline struct sk_buff *
virtio_vsock_alloc_linear_skb(unsigned int size, gfp_t mask)
{
- struct sk_buff *skb;
+ return __virtio_vsock_alloc_skb_with_frags(size, 0, mask);
+}
- skb = alloc_skb(size, mask);
- if (!skb)
- return NULL;
+static inline struct sk_buff *virtio_vsock_alloc_skb(unsigned int size, gfp_t mask)
+{
+ if (size <= SKB_WITH_OVERHEAD(PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER))
+ return virtio_vsock_alloc_linear_skb(size, mask);
- skb_reserve(skb, VIRTIO_VSOCK_SKB_HEADROOM);
- return skb;
+ size -= VIRTIO_VSOCK_SKB_HEADROOM;
+ return __virtio_vsock_alloc_skb_with_frags(VIRTIO_VSOCK_SKB_HEADROOM,
+ size, mask);
}
static inline void
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 8/9] vsock/virtio: Rename virtio_vsock_skb_rx_put()
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
` (6 preceding siblings ...)
2025-07-17 9:01 ` [PATCH v4 7/9] vhost/vsock: Allocate nonlinear SKBs for handling large receive buffers Will Deacon
@ 2025-07-17 9:01 ` Will Deacon
2025-07-17 9:01 ` [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers Will Deacon
` (2 subsequent siblings)
10 siblings, 0 replies; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization
In preparation for using virtio_vsock_skb_rx_put() when populating SKBs
on the vsock TX path, rename virtio_vsock_skb_rx_put() to
virtio_vsock_skb_put().
No functional change.
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
drivers/vhost/vsock.c | 2 +-
include/linux/virtio_vsock.h | 2 +-
net/vmw_vsock/virtio_transport.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 0679a706ebc0..ae01457ea2cd 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -376,7 +376,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
return NULL;
}
- virtio_vsock_skb_rx_put(skb, payload_len);
+ virtio_vsock_skb_put(skb, payload_len);
if (skb_copy_datagram_from_iter(skb, 0, &iov_iter, payload_len)) {
vq_err(vq, "Failed to copy %zu byte payload\n", payload_len);
diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h
index fa5934ea9c81..0c67543a45c8 100644
--- a/include/linux/virtio_vsock.h
+++ b/include/linux/virtio_vsock.h
@@ -47,7 +47,7 @@ static inline void virtio_vsock_skb_clear_tap_delivered(struct sk_buff *skb)
VIRTIO_VSOCK_SKB_CB(skb)->tap_delivered = false;
}
-static inline void virtio_vsock_skb_rx_put(struct sk_buff *skb, u32 len)
+static inline void virtio_vsock_skb_put(struct sk_buff *skb, u32 len)
{
DEBUG_NET_WARN_ON_ONCE(skb->len);
diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
index 80dcf6ac1e72..b6569b0ca2bb 100644
--- a/net/vmw_vsock/virtio_transport.c
+++ b/net/vmw_vsock/virtio_transport.c
@@ -657,7 +657,7 @@ static void virtio_transport_rx_work(struct work_struct *work)
}
if (payload_len)
- virtio_vsock_skb_rx_put(skb, payload_len);
+ virtio_vsock_skb_put(skb, payload_len);
virtio_transport_deliver_tap_pkt(skb);
virtio_transport_recv_pkt(&virtio_transport, skb);
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
` (7 preceding siblings ...)
2025-07-17 9:01 ` [PATCH v4 8/9] vsock/virtio: Rename virtio_vsock_skb_rx_put() Will Deacon
@ 2025-07-17 9:01 ` Will Deacon
2025-08-13 8:41 ` Michael S. Tsirkin
2025-07-17 12:31 ` [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Michael S. Tsirkin
2025-07-17 12:35 ` Michael S. Tsirkin
10 siblings, 1 reply; 21+ messages in thread
From: Will Deacon @ 2025-07-17 9:01 UTC (permalink / raw)
To: linux-kernel
Cc: Will Deacon, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Jason Wang, Eugenio Pérez, netdev, virtualization
When transmitting a vsock packet, virtio_transport_send_pkt_info() calls
virtio_transport_alloc_linear_skb() to allocate and fill SKBs with the
transmit data. Unfortunately, these are always linear allocations and
can therefore result in significant pressure on kmalloc() considering
that the maximum packet size (VIRTIO_VSOCK_MAX_PKT_BUF_SIZE +
VIRTIO_VSOCK_SKB_HEADROOM) is a little over 64KiB, resulting in a 128KiB
allocation for each packet.
Rework the vsock SKB allocation so that, for sizes with page order
greater than PAGE_ALLOC_COSTLY_ORDER, a nonlinear SKB is allocated
instead with the packet header in the SKB and the transmit data in the
fragments. Note that this affects both the vhost and virtio transports.
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
net/vmw_vsock/virtio_transport_common.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index c9eb7f7ac00d..fe92e5fa95b4 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -109,7 +109,8 @@ static int virtio_transport_fill_skb(struct sk_buff *skb,
return __zerocopy_sg_from_iter(info->msg, NULL, skb,
&info->msg->msg_iter, len, NULL);
- return memcpy_from_msg(skb_put(skb, len), info->msg, len);
+ virtio_vsock_skb_put(skb, len);
+ return skb_copy_datagram_from_iter(skb, 0, &info->msg->msg_iter, len);
}
static void virtio_transport_init_hdr(struct sk_buff *skb,
@@ -261,7 +262,7 @@ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *
if (!zcopy)
skb_len += payload_len;
- skb = virtio_vsock_alloc_linear_skb(skb_len, GFP_KERNEL);
+ skb = virtio_vsock_alloc_skb(skb_len, GFP_KERNEL);
if (!skb)
return NULL;
--
2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v4 1/9] vhost/vsock: Avoid allocating arbitrarily-sized SKBs
2025-07-17 9:01 ` [PATCH v4 1/9] vhost/vsock: Avoid allocating arbitrarily-sized SKBs Will Deacon
@ 2025-07-17 9:10 ` Jason Wang
2025-07-17 9:25 ` Stefano Garzarella
0 siblings, 1 reply; 21+ messages in thread
From: Jason Wang @ 2025-07-17 9:10 UTC (permalink / raw)
To: Will Deacon
Cc: linux-kernel, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Michael S. Tsirkin,
Eugenio Pérez, netdev, virtualization, stable
On Thu, Jul 17, 2025 at 5:01 PM Will Deacon <will@kernel.org> wrote:
>
> vhost_vsock_alloc_skb() returns NULL for packets advertising a length
> larger than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE in the packet header. However,
> this is only checked once the SKB has been allocated and, if the length
> in the packet header is zero, the SKB may not be freed immediately.
Can this be triggered from the guest? (I guess yes) Did we need to
consider it as a security issue?
>
> Hoist the size check before the SKB allocation so that an iovec larger
> than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + the header size is rejected
> outright. The subsequent check on the length field in the header can
> then simply check that the allocated SKB is indeed large enough to hold
> the packet.
>
> Cc: <stable@vger.kernel.org>
> Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> Signed-off-by: Will Deacon <will@kernel.org>
> ---
> drivers/vhost/vsock.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
> index 802153e23073..66a0f060770e 100644
> --- a/drivers/vhost/vsock.c
> +++ b/drivers/vhost/vsock.c
> @@ -344,6 +344,9 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
>
> len = iov_length(vq->iov, out);
>
> + if (len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM)
> + return NULL;
> +
> /* len contains both payload and hdr */
> skb = virtio_vsock_alloc_skb(len, GFP_KERNEL);
> if (!skb)
> @@ -367,8 +370,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
> return skb;
>
> /* The pkt is too big or the length in the header is invalid */
> - if (payload_len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE ||
> - payload_len + sizeof(*hdr) > len) {
> + if (payload_len + sizeof(*hdr) > len) {
> kfree_skb(skb);
> return NULL;
> }
> --
> 2.50.0.727.gbf7dc18ff4-goog
>
Thanks
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 1/9] vhost/vsock: Avoid allocating arbitrarily-sized SKBs
2025-07-17 9:10 ` Jason Wang
@ 2025-07-17 9:25 ` Stefano Garzarella
0 siblings, 0 replies; 21+ messages in thread
From: Stefano Garzarella @ 2025-07-17 9:25 UTC (permalink / raw)
To: Jason Wang
Cc: Will Deacon, linux-kernel, Keir Fraser, Steven Moreland,
Frederick Mayle, Stefan Hajnoczi, Michael S. Tsirkin,
Eugenio Pérez, netdev, virtualization, stable
On Thu, 17 Jul 2025 at 11:10, Jason Wang <jasowang@redhat.com> wrote:
>
> On Thu, Jul 17, 2025 at 5:01 PM Will Deacon <will@kernel.org> wrote:
> >
> > vhost_vsock_alloc_skb() returns NULL for packets advertising a length
> > larger than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE in the packet header. However,
> > this is only checked once the SKB has been allocated and, if the length
> > in the packet header is zero, the SKB may not be freed immediately.
>
> Can this be triggered from the guest? (I guess yes) Did we need to
> consider it as a security issue?
Yep, but then the packet would still be discarded later, and the
memory released, so it can only increase the pressure on allocation,
but the guest can still do so by sending packets for example on an
unopened port.
Stefano
>
> >
> > Hoist the size check before the SKB allocation so that an iovec larger
> > than VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + the header size is rejected
> > outright. The subsequent check on the length field in the header can
> > then simply check that the allocated SKB is indeed large enough to hold
> > the packet.
> >
> > Cc: <stable@vger.kernel.org>
> > Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
> > Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> > Signed-off-by: Will Deacon <will@kernel.org>
> > ---
> > drivers/vhost/vsock.c | 6 ++++--
> > 1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
> > index 802153e23073..66a0f060770e 100644
> > --- a/drivers/vhost/vsock.c
> > +++ b/drivers/vhost/vsock.c
> > @@ -344,6 +344,9 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
> >
> > len = iov_length(vq->iov, out);
> >
> > + if (len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM)
> > + return NULL;
> > +
> > /* len contains both payload and hdr */
> > skb = virtio_vsock_alloc_skb(len, GFP_KERNEL);
> > if (!skb)
> > @@ -367,8 +370,7 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
> > return skb;
> >
> > /* The pkt is too big or the length in the header is invalid */
> > - if (payload_len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE ||
> > - payload_len + sizeof(*hdr) > len) {
> > + if (payload_len + sizeof(*hdr) > len) {
> > kfree_skb(skb);
> > return NULL;
> > }
> > --
> > 2.50.0.727.gbf7dc18ff4-goog
> >
>
> Thanks
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 2/9] vsock/virtio: Validate length in packet header before skb_put()
2025-07-17 9:01 ` [PATCH v4 2/9] vsock/virtio: Validate length in packet header before skb_put() Will Deacon
@ 2025-07-17 9:39 ` Stefano Garzarella
0 siblings, 0 replies; 21+ messages in thread
From: Stefano Garzarella @ 2025-07-17 9:39 UTC (permalink / raw)
To: Will Deacon
Cc: linux-kernel, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Michael S. Tsirkin, Jason Wang,
Eugenio Pérez, netdev, virtualization, stable
On Thu, Jul 17, 2025 at 10:01:09AM +0100, Will Deacon wrote:
>When receiving a vsock packet in the guest, only the virtqueue buffer
>size is validated prior to virtio_vsock_skb_rx_put(). Unfortunately,
>virtio_vsock_skb_rx_put() uses the length from the packet header as the
>length argument to skb_put(), potentially resulting in SKB overflow if
>the host has gone wonky.
>
>Validate the length as advertised by the packet header before calling
>virtio_vsock_skb_rx_put().
>
>Cc: <stable@vger.kernel.org>
>Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
>Signed-off-by: Will Deacon <will@kernel.org>
>---
> net/vmw_vsock/virtio_transport.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
>
>diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c
>index f0e48e6911fc..eb08a393413d 100644
>--- a/net/vmw_vsock/virtio_transport.c
>+++ b/net/vmw_vsock/virtio_transport.c
>@@ -624,8 +624,9 @@ static void virtio_transport_rx_work(struct work_struct *work)
> do {
> virtqueue_disable_cb(vq);
> for (;;) {
>+ unsigned int len, payload_len;
>+ struct virtio_vsock_hdr *hdr;
> struct sk_buff *skb;
>- unsigned int len;
>
> if (!virtio_transport_more_replies(vsock)) {
> /* Stop rx until the device processes already
>@@ -642,12 +643,19 @@ static void virtio_transport_rx_work(struct work_struct *work)
> vsock->rx_buf_nr--;
>
> /* Drop short/long packets */
>- if (unlikely(len < sizeof(struct virtio_vsock_hdr) ||
>+ if (unlikely(len < sizeof(*hdr) ||
> len > virtio_vsock_skb_len(skb))) {
> kfree_skb(skb);
> continue;
> }
>
>+ hdr = virtio_vsock_hdr(skb);
>+ payload_len = le32_to_cpu(hdr->len);
>+ if (unlikely(payload_len > len - sizeof(*hdr))) {
>+ kfree_skb(skb);
>+ continue;
>+ }
>+
> virtio_vsock_skb_rx_put(skb);
> virtio_transport_deliver_tap_pkt(skb);
> virtio_transport_recv_pkt(&virtio_transport, skb);
>--
>2.50.0.727.gbf7dc18ff4-goog
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/9] vsock/virtio: SKB allocation improvements
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
` (8 preceding siblings ...)
2025-07-17 9:01 ` [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers Will Deacon
@ 2025-07-17 12:31 ` Michael S. Tsirkin
2025-07-17 12:36 ` Stefano Garzarella
2025-07-17 12:35 ` Michael S. Tsirkin
10 siblings, 1 reply; 21+ messages in thread
From: Michael S. Tsirkin @ 2025-07-17 12:31 UTC (permalink / raw)
To: Will Deacon
Cc: linux-kernel, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Jason Wang,
Eugenio Pérez, netdev, virtualization
On Thu, Jul 17, 2025 at 10:01:07AM +0100, Will Deacon wrote:
> Hi all,
>
> Here is version four of the patches I previously posted here:
>
> v1: https://lore.kernel.org/r/20250625131543.5155-1-will@kernel.org
> v2: https://lore.kernel.org/r/20250701164507.14883-1-will@kernel.org
> v3: https://lore.kernel.org/r/20250714152103.6949-1-will@kernel.org
>
> There are only two minor changes since v3:
>
> * Use unlikely() in payload length check on the virtio rx path
>
> * Add R-b tags from Stefano
>
> Cheers,
>
> Will
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Who's applying them, me?
> Cc: Keir Fraser <keirf@google.com>
> Cc: Steven Moreland <smoreland@google.com>
> Cc: Frederick Mayle <fmayle@google.com>
> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> Cc: Stefano Garzarella <sgarzare@redhat.com>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Jason Wang <jasowang@redhat.com>
> Cc: "Eugenio Pérez" <eperezma@redhat.com>
> Cc: linux-kernel@vger.kernel.org
> Cc: netdev@vger.kernel.org
> Cc: virtualization@lists.linux.dev
>
> --->8
>
> Will Deacon (9):
> vhost/vsock: Avoid allocating arbitrarily-sized SKBs
> vsock/virtio: Validate length in packet header before skb_put()
> vsock/virtio: Move length check to callers of
> virtio_vsock_skb_rx_put()
> vsock/virtio: Resize receive buffers so that each SKB fits in a 4K
> page
> vsock/virtio: Rename virtio_vsock_alloc_skb()
> vsock/virtio: Move SKB allocation lower-bound check to callers
> vhost/vsock: Allocate nonlinear SKBs for handling large receive
> buffers
> vsock/virtio: Rename virtio_vsock_skb_rx_put()
> vsock/virtio: Allocate nonlinear SKBs for handling large transmit
> buffers
>
> drivers/vhost/vsock.c | 15 ++++----
> include/linux/virtio_vsock.h | 46 +++++++++++++++++++------
> net/vmw_vsock/virtio_transport.c | 20 ++++++++---
> net/vmw_vsock/virtio_transport_common.c | 3 +-
> 4 files changed, 60 insertions(+), 24 deletions(-)
>
> --
> 2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/9] vsock/virtio: SKB allocation improvements
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
` (9 preceding siblings ...)
2025-07-17 12:31 ` [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Michael S. Tsirkin
@ 2025-07-17 12:35 ` Michael S. Tsirkin
10 siblings, 0 replies; 21+ messages in thread
From: Michael S. Tsirkin @ 2025-07-17 12:35 UTC (permalink / raw)
To: Will Deacon
Cc: linux-kernel, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Jason Wang,
Eugenio Pérez, netdev, virtualization
On Thu, Jul 17, 2025 at 10:01:07AM +0100, Will Deacon wrote:
> Hi all,
>
> Here is version four of the patches I previously posted here:
>
> v1: https://lore.kernel.org/r/20250625131543.5155-1-will@kernel.org
> v2: https://lore.kernel.org/r/20250701164507.14883-1-will@kernel.org
> v3: https://lore.kernel.org/r/20250714152103.6949-1-will@kernel.org
>
> There are only two minor changes since v3:
>
> * Use unlikely() in payload length check on the virtio rx path
>
> * Add R-b tags from Stefano
>
> Cheers,
>
> Will
in my tree now. Let's see how does it go.
> Cc: Keir Fraser <keirf@google.com>
> Cc: Steven Moreland <smoreland@google.com>
> Cc: Frederick Mayle <fmayle@google.com>
> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> Cc: Stefano Garzarella <sgarzare@redhat.com>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Jason Wang <jasowang@redhat.com>
> Cc: "Eugenio Pérez" <eperezma@redhat.com>
> Cc: linux-kernel@vger.kernel.org
> Cc: netdev@vger.kernel.org
> Cc: virtualization@lists.linux.dev
>
> --->8
>
> Will Deacon (9):
> vhost/vsock: Avoid allocating arbitrarily-sized SKBs
> vsock/virtio: Validate length in packet header before skb_put()
> vsock/virtio: Move length check to callers of
> virtio_vsock_skb_rx_put()
> vsock/virtio: Resize receive buffers so that each SKB fits in a 4K
> page
> vsock/virtio: Rename virtio_vsock_alloc_skb()
> vsock/virtio: Move SKB allocation lower-bound check to callers
> vhost/vsock: Allocate nonlinear SKBs for handling large receive
> buffers
> vsock/virtio: Rename virtio_vsock_skb_rx_put()
> vsock/virtio: Allocate nonlinear SKBs for handling large transmit
> buffers
>
> drivers/vhost/vsock.c | 15 ++++----
> include/linux/virtio_vsock.h | 46 +++++++++++++++++++------
> net/vmw_vsock/virtio_transport.c | 20 ++++++++---
> net/vmw_vsock/virtio_transport_common.c | 3 +-
> 4 files changed, 60 insertions(+), 24 deletions(-)
>
> --
> 2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 0/9] vsock/virtio: SKB allocation improvements
2025-07-17 12:31 ` [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Michael S. Tsirkin
@ 2025-07-17 12:36 ` Stefano Garzarella
0 siblings, 0 replies; 21+ messages in thread
From: Stefano Garzarella @ 2025-07-17 12:36 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Will Deacon, linux-kernel, Keir Fraser, Steven Moreland,
Frederick Mayle, Stefan Hajnoczi, Jason Wang, Eugenio Pérez,
netdev, virtualization
On Thu, 17 Jul 2025 at 14:31, Michael S. Tsirkin <mst@redhat.com> wrote:
>
> On Thu, Jul 17, 2025 at 10:01:07AM +0100, Will Deacon wrote:
> > Hi all,
> >
> > Here is version four of the patches I previously posted here:
> >
> > v1: https://lore.kernel.org/r/20250625131543.5155-1-will@kernel.org
> > v2: https://lore.kernel.org/r/20250701164507.14883-1-will@kernel.org
> > v3: https://lore.kernel.org/r/20250714152103.6949-1-will@kernel.org
> >
> > There are only two minor changes since v3:
> >
> > * Use unlikely() in payload length check on the virtio rx path
> >
> > * Add R-b tags from Stefano
> >
> > Cheers,
> >
> > Will
>
> Acked-by: Michael S. Tsirkin <mst@redhat.com>
>
>
> Who's applying them, me?
It's pretty much only about virtio/vhost, so I think yours is the right tree.
I completely reviewed it, so it can go for me.
Thanks,
Stefano
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers
2025-07-17 9:01 ` [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers Will Deacon
@ 2025-08-13 8:41 ` Michael S. Tsirkin
2025-08-13 13:25 ` Hillf Danton
0 siblings, 1 reply; 21+ messages in thread
From: Michael S. Tsirkin @ 2025-08-13 8:41 UTC (permalink / raw)
To: Will Deacon
Cc: linux-kernel, Keir Fraser, Steven Moreland, Frederick Mayle,
Stefan Hajnoczi, Stefano Garzarella, Jason Wang,
Eugenio Pérez, netdev, virtualization
On Thu, Jul 17, 2025 at 10:01:16AM +0100, Will Deacon wrote:
> When transmitting a vsock packet, virtio_transport_send_pkt_info() calls
> virtio_transport_alloc_linear_skb() to allocate and fill SKBs with the
> transmit data. Unfortunately, these are always linear allocations and
> can therefore result in significant pressure on kmalloc() considering
> that the maximum packet size (VIRTIO_VSOCK_MAX_PKT_BUF_SIZE +
> VIRTIO_VSOCK_SKB_HEADROOM) is a little over 64KiB, resulting in a 128KiB
> allocation for each packet.
>
> Rework the vsock SKB allocation so that, for sizes with page order
> greater than PAGE_ALLOC_COSTLY_ORDER, a nonlinear SKB is allocated
> instead with the packet header in the SKB and the transmit data in the
> fragments. Note that this affects both the vhost and virtio transports.
>
> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> Signed-off-by: Will Deacon <will@kernel.org>
So this caused a regression, see syzbot report:
https://lore.kernel.org/all/689a3d92.050a0220.7f033.00ff.GAE@google.com
I'm inclined to revert unless we have a fix quickly.
> ---
> net/vmw_vsock/virtio_transport_common.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
> index c9eb7f7ac00d..fe92e5fa95b4 100644
> --- a/net/vmw_vsock/virtio_transport_common.c
> +++ b/net/vmw_vsock/virtio_transport_common.c
> @@ -109,7 +109,8 @@ static int virtio_transport_fill_skb(struct sk_buff *skb,
> return __zerocopy_sg_from_iter(info->msg, NULL, skb,
> &info->msg->msg_iter, len, NULL);
>
> - return memcpy_from_msg(skb_put(skb, len), info->msg, len);
> + virtio_vsock_skb_put(skb, len);
> + return skb_copy_datagram_from_iter(skb, 0, &info->msg->msg_iter, len);
> }
>
> static void virtio_transport_init_hdr(struct sk_buff *skb,
> @@ -261,7 +262,7 @@ static struct sk_buff *virtio_transport_alloc_skb(struct virtio_vsock_pkt_info *
> if (!zcopy)
> skb_len += payload_len;
>
> - skb = virtio_vsock_alloc_linear_skb(skb_len, GFP_KERNEL);
> + skb = virtio_vsock_alloc_skb(skb_len, GFP_KERNEL);
> if (!skb)
> return NULL;
>
> --
> 2.50.0.727.gbf7dc18ff4-goog
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers
2025-08-13 8:41 ` Michael S. Tsirkin
@ 2025-08-13 13:25 ` Hillf Danton
2025-08-15 10:22 ` Michael S. Tsirkin
0 siblings, 1 reply; 21+ messages in thread
From: Hillf Danton @ 2025-08-13 13:25 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Will Deacon, linux-kernel, Stefano Garzarella, Jason Wang, netdev,
virtualization
On Wed, 13 Aug 2025 04:41:09 -0400 "Michael S. Tsirkin" wrote:
> On Thu, Jul 17, 2025 at 10:01:16AM +0100, Will Deacon wrote:
> > When transmitting a vsock packet, virtio_transport_send_pkt_info() calls
> > virtio_transport_alloc_linear_skb() to allocate and fill SKBs with the
> > transmit data. Unfortunately, these are always linear allocations and
> > can therefore result in significant pressure on kmalloc() considering
> > that the maximum packet size (VIRTIO_VSOCK_MAX_PKT_BUF_SIZE +
> > VIRTIO_VSOCK_SKB_HEADROOM) is a little over 64KiB, resulting in a 128KiB
> > allocation for each packet.
> >
> > Rework the vsock SKB allocation so that, for sizes with page order
> > greater than PAGE_ALLOC_COSTLY_ORDER, a nonlinear SKB is allocated
> > instead with the packet header in the SKB and the transmit data in the
> > fragments. Note that this affects both the vhost and virtio transports.
> >
> > Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> > Signed-off-by: Will Deacon <will@kernel.org>
>
> So this caused a regression, see syzbot report:
>
> https://lore.kernel.org/all/689a3d92.050a0220.7f033.00ff.GAE@google.com
>
> I'm inclined to revert unless we have a fix quickly.
>
Because recomputing skb len survived the syzbot test [1], Will looks innocent.
[1] https://lore.kernel.org/lkml/689c8d08.050a0220.7f033.014a.GAE@google.com/
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers
2025-08-13 13:25 ` Hillf Danton
@ 2025-08-15 10:22 ` Michael S. Tsirkin
2025-08-15 12:07 ` Hillf Danton
0 siblings, 1 reply; 21+ messages in thread
From: Michael S. Tsirkin @ 2025-08-15 10:22 UTC (permalink / raw)
To: Hillf Danton
Cc: Will Deacon, linux-kernel, Stefano Garzarella, Jason Wang, netdev,
virtualization
On Wed, Aug 13, 2025 at 09:25:53PM +0800, Hillf Danton wrote:
> On Wed, 13 Aug 2025 04:41:09 -0400 "Michael S. Tsirkin" wrote:
> > On Thu, Jul 17, 2025 at 10:01:16AM +0100, Will Deacon wrote:
> > > When transmitting a vsock packet, virtio_transport_send_pkt_info() calls
> > > virtio_transport_alloc_linear_skb() to allocate and fill SKBs with the
> > > transmit data. Unfortunately, these are always linear allocations and
> > > can therefore result in significant pressure on kmalloc() considering
> > > that the maximum packet size (VIRTIO_VSOCK_MAX_PKT_BUF_SIZE +
> > > VIRTIO_VSOCK_SKB_HEADROOM) is a little over 64KiB, resulting in a 128KiB
> > > allocation for each packet.
> > >
> > > Rework the vsock SKB allocation so that, for sizes with page order
> > > greater than PAGE_ALLOC_COSTLY_ORDER, a nonlinear SKB is allocated
> > > instead with the packet header in the SKB and the transmit data in the
> > > fragments. Note that this affects both the vhost and virtio transports.
> > >
> > > Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> > > Signed-off-by: Will Deacon <will@kernel.org>
> >
> > So this caused a regression, see syzbot report:
> >
> > https://lore.kernel.org/all/689a3d92.050a0220.7f033.00ff.GAE@google.com
> >
> > I'm inclined to revert unless we have a fix quickly.
> >
> Because recomputing skb len survived the syzbot test [1], Will looks innocent.
>
> [1] https://lore.kernel.org/lkml/689c8d08.050a0220.7f033.014a.GAE@google.com/
I'm not sure I follow that patch though. Do you mind submitting
with an explanation in the commit log?
--
MST
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers
2025-08-15 10:22 ` Michael S. Tsirkin
@ 2025-08-15 12:07 ` Hillf Danton
2025-08-16 10:38 ` Michael S. Tsirkin
0 siblings, 1 reply; 21+ messages in thread
From: Hillf Danton @ 2025-08-15 12:07 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Will Deacon, linux-kernel, Stefano Garzarella, Jason Wang, netdev,
virtualization
On Fri, 15 Aug 2025 06:22:56 -0400 "Michael S. Tsirkin" wrote:
> On Wed, Aug 13, 2025 at 09:25:53PM +0800, Hillf Danton wrote:
> > On Wed, 13 Aug 2025 04:41:09 -0400 "Michael S. Tsirkin" wrote:
> > > On Thu, Jul 17, 2025 at 10:01:16AM +0100, Will Deacon wrote:
> > > > When transmitting a vsock packet, virtio_transport_send_pkt_info() calls
> > > > virtio_transport_alloc_linear_skb() to allocate and fill SKBs with the
> > > > transmit data. Unfortunately, these are always linear allocations and
> > > > can therefore result in significant pressure on kmalloc() considering
> > > > that the maximum packet size (VIRTIO_VSOCK_MAX_PKT_BUF_SIZE +
> > > > VIRTIO_VSOCK_SKB_HEADROOM) is a little over 64KiB, resulting in a 128KiB
> > > > allocation for each packet.
> > > >
> > > > Rework the vsock SKB allocation so that, for sizes with page order
> > > > greater than PAGE_ALLOC_COSTLY_ORDER, a nonlinear SKB is allocated
> > > > instead with the packet header in the SKB and the transmit data in the
> > > > fragments. Note that this affects both the vhost and virtio transports.
> > > >
> > > > Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> > > > Signed-off-by: Will Deacon <will@kernel.org>
> > >
> > > So this caused a regression, see syzbot report:
> > >
> > > https://lore.kernel.org/all/689a3d92.050a0220.7f033.00ff.GAE@google.com
> > >
> > > I'm inclined to revert unless we have a fix quickly.
> > >
> > Because recomputing skb len survived the syzbot test [1], Will looks innocent.
> >
> > [1] https://lore.kernel.org/lkml/689c8d08.050a0220.7f033.014a.GAE@google.com/
>
> I'm not sure I follow that patch though. Do you mind submitting
> with an explanation in the commit log?
>
It is a simple debug patch to test if Will's work is good at least in the
syzbot scenario, but stil a couple miles away from a patch with the SOB tag.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers
2025-08-15 12:07 ` Hillf Danton
@ 2025-08-16 10:38 ` Michael S. Tsirkin
0 siblings, 0 replies; 21+ messages in thread
From: Michael S. Tsirkin @ 2025-08-16 10:38 UTC (permalink / raw)
To: Hillf Danton
Cc: Will Deacon, linux-kernel, Stefano Garzarella, Jason Wang, netdev,
virtualization
On Fri, Aug 15, 2025 at 08:07:46PM +0800, Hillf Danton wrote:
> On Fri, 15 Aug 2025 06:22:56 -0400 "Michael S. Tsirkin" wrote:
> > On Wed, Aug 13, 2025 at 09:25:53PM +0800, Hillf Danton wrote:
> > > On Wed, 13 Aug 2025 04:41:09 -0400 "Michael S. Tsirkin" wrote:
> > > > On Thu, Jul 17, 2025 at 10:01:16AM +0100, Will Deacon wrote:
> > > > > When transmitting a vsock packet, virtio_transport_send_pkt_info() calls
> > > > > virtio_transport_alloc_linear_skb() to allocate and fill SKBs with the
> > > > > transmit data. Unfortunately, these are always linear allocations and
> > > > > can therefore result in significant pressure on kmalloc() considering
> > > > > that the maximum packet size (VIRTIO_VSOCK_MAX_PKT_BUF_SIZE +
> > > > > VIRTIO_VSOCK_SKB_HEADROOM) is a little over 64KiB, resulting in a 128KiB
> > > > > allocation for each packet.
> > > > >
> > > > > Rework the vsock SKB allocation so that, for sizes with page order
> > > > > greater than PAGE_ALLOC_COSTLY_ORDER, a nonlinear SKB is allocated
> > > > > instead with the packet header in the SKB and the transmit data in the
> > > > > fragments. Note that this affects both the vhost and virtio transports.
> > > > >
> > > > > Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
> > > > > Signed-off-by: Will Deacon <will@kernel.org>
> > > >
> > > > So this caused a regression, see syzbot report:
> > > >
> > > > https://lore.kernel.org/all/689a3d92.050a0220.7f033.00ff.GAE@google.com
> > > >
> > > > I'm inclined to revert unless we have a fix quickly.
> > > >
> > > Because recomputing skb len survived the syzbot test [1], Will looks innocent.
> > >
> > > [1] https://lore.kernel.org/lkml/689c8d08.050a0220.7f033.014a.GAE@google.com/
> >
> > I'm not sure I follow that patch though. Do you mind submitting
> > with an explanation in the commit log?
> >
> It is a simple debug patch to test if Will's work is good at least in the
> syzbot scenario, but stil a couple miles away from a patch with the SOB tag.
Oh that makes sense then.
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2025-08-16 10:38 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-17 9:01 [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Will Deacon
2025-07-17 9:01 ` [PATCH v4 1/9] vhost/vsock: Avoid allocating arbitrarily-sized SKBs Will Deacon
2025-07-17 9:10 ` Jason Wang
2025-07-17 9:25 ` Stefano Garzarella
2025-07-17 9:01 ` [PATCH v4 2/9] vsock/virtio: Validate length in packet header before skb_put() Will Deacon
2025-07-17 9:39 ` Stefano Garzarella
2025-07-17 9:01 ` [PATCH v4 3/9] vsock/virtio: Move length check to callers of virtio_vsock_skb_rx_put() Will Deacon
2025-07-17 9:01 ` [PATCH v4 4/9] vsock/virtio: Resize receive buffers so that each SKB fits in a 4K page Will Deacon
2025-07-17 9:01 ` [PATCH v4 5/9] vsock/virtio: Rename virtio_vsock_alloc_skb() Will Deacon
2025-07-17 9:01 ` [PATCH v4 6/9] vsock/virtio: Move SKB allocation lower-bound check to callers Will Deacon
2025-07-17 9:01 ` [PATCH v4 7/9] vhost/vsock: Allocate nonlinear SKBs for handling large receive buffers Will Deacon
2025-07-17 9:01 ` [PATCH v4 8/9] vsock/virtio: Rename virtio_vsock_skb_rx_put() Will Deacon
2025-07-17 9:01 ` [PATCH v4 9/9] vsock/virtio: Allocate nonlinear SKBs for handling large transmit buffers Will Deacon
2025-08-13 8:41 ` Michael S. Tsirkin
2025-08-13 13:25 ` Hillf Danton
2025-08-15 10:22 ` Michael S. Tsirkin
2025-08-15 12:07 ` Hillf Danton
2025-08-16 10:38 ` Michael S. Tsirkin
2025-07-17 12:31 ` [PATCH v4 0/9] vsock/virtio: SKB allocation improvements Michael S. Tsirkin
2025-07-17 12:36 ` Stefano Garzarella
2025-07-17 12:35 ` Michael S. Tsirkin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).