This adds copying to guest's virtio buffers from non-linear skbs. Such
skbs are created by protocol layer when MSG_ZEROCOPY flags is used.
Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
---
drivers/vhost/vsock.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
@@ -197,11 +197,20 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
break;
}
- nbytes = copy_to_iter(skb->data, payload_len, &iov_iter);
- if (nbytes != payload_len) {
- kfree_skb(skb);
- vq_err(vq, "Faulted on copying pkt buf\n");
- break;
+ if (skb_is_nonlinear(skb)) {
+ if (virtio_transport_nl_skb_to_iov(skb, &iov_iter,
+ payload_len,
+ false)) {
+ vq_err(vq, "Faulted on copying pkt buf from page\n");
+ break;
+ }
+ } else {
+ nbytes = copy_to_iter(skb->data, payload_len, &iov_iter);
+ if (nbytes != payload_len) {
+ kfree_skb(skb);
+ vq_err(vq, "Faulted on copying pkt buf\n");
+ break;
+ }
}
/* Deliver to monitoring devices all packets that we
@@ -212,7 +221,9 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
vhost_add_used(vq, head, sizeof(*hdr) + payload_len);
added = true;
- skb_pull(skb, payload_len);
+ if (!skb_is_nonlinear(skb))
+ skb_pull(skb, payload_len);
+
total_len += payload_len;
/* If we didn't send all the payload we can requeue the packet