All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Andrew Melnychenko <andrew@daynix.com>
Cc: jasowang@redhat.com, mst@redhat.com, armbru@redhat.com,
	eblake@redhat.com, qemu-devel@nongnu.org,
	yuri.benditovich@daynix.com, yan@daynix.com
Subject: Re: [PATCH 2/5] virtio-net: Added property to load eBPF RSS with fds.
Date: Wed, 3 May 2023 12:03:12 +0100	[thread overview]
Message-ID: <ZFI/cIIf6DKRwvCq@redhat.com> (raw)
In-Reply-To: <20230501072101.22890-3-andrew@daynix.com>

On Mon, May 01, 2023 at 10:20:58AM +0300, Andrew Melnychenko wrote:
> eBPF RSS program and maps may now be passed during initialization.
> Initially was implemented for libvirt to launch qemu without permissions,
> and initialized eBPF program through the helper.
> 
> Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
> ---
>  hw/net/virtio-net.c            | 96 +++++++++++++++++++++++++++++++---
>  include/hw/virtio/virtio-net.h |  1 +
>  2 files changed, 91 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index 53e1c326433..9b3a997d872 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -42,6 +42,7 @@
>  #include "sysemu/sysemu.h"
>  #include "trace.h"
>  #include "monitor/qdev.h"
> +#include "monitor/monitor.h"
>  #include "hw/pci/pci_device.h"
>  #include "net_rx_pkt.h"
>  #include "hw/virtio/vhost.h"
> @@ -1305,14 +1306,96 @@ static void virtio_net_detach_epbf_rss(VirtIONet *n)
>      virtio_net_attach_ebpf_to_backend(n->nic, -1);
>  }
>  
> -static bool virtio_net_load_ebpf(VirtIONet *n)
> +static int virtio_net_get_ebpf_rss_fds(char *str, char *fds[], int nfds,
> +                                       Error **errp)
>  {
> -    if (!virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
> -        /* backend does't support steering ebpf */
> -        return false;
> +    char *ptr = str;
> +    char *cur = NULL;
> +    size_t len = strlen(str);
> +    int i = 0;
> +
> +    for (; i < nfds && ptr < str + len;) {
> +        cur = strchr(ptr, ':');
> +
> +        if (cur == NULL) {
> +            fds[i] = g_strdup(ptr);
> +        } else {
> +            fds[i] = g_strndup(ptr, cur - ptr);
> +        }
> +
> +        i++;
> +        if (cur == NULL) {
> +            break;
> +        } else {
> +            ptr = cur + 1;
> +        }
> +    }
> +
> +    if (cur != NULL) {
> +        /* the string contains more arguments */
> +        error_setg(errp,
> +                   "Too many eBPF file descriptors for RSS provided.");
> +    } else if (i < nfds) {
> +        error_setg(errp,
> +                   "Not enough eBPF file descriptors for RSS were provided.");
> +    }
> +
> +    return i;
> +}

This whole method could be replaced by a call to g_strsplit in
the caller....
 

> +
> +static bool virtio_net_load_ebpf_fds(VirtIONet *n, Error **errp)
> +{
> +    char *fds_strs[EBPF_RSS_MAX_FDS];

   g_autoptr(GStrv) fds_strs = g_strsplit(n->ebpf_rss_fds, ",", 0);

> +    int fds[EBPF_RSS_MAX_FDS];

Left as uninitialized stack memory.

> +    int nfds;
> +    int ret = true;
> +    int i = 0;
> +
> +    ERRP_GUARD();
> +
> +    nfds = virtio_net_get_ebpf_rss_fds(n->ebpf_rss_fds,
> +                                       fds_strs, EBPF_RSS_MAX_FDS, errp);
> +    if (*errp) {
> +        ret = false;
> +        goto exit;
>      }

Replace with 

   if (g_strv_length(fds_strs) != EBPF_RSS_MAX_FDS) {
       error_setg(errp,
                  "Expected %d file descriptors but got %d",
		  EBPF_RSS_MAX_FDS, g_strv_length(fds_strs));
       return false;
   }

>  
> -    return ebpf_rss_load(&n->ebpf_rss);
> +    for (i = 0; i < nfds; i++) {
> +        fds[i] = monitor_fd_param(monitor_cur(), fds_strs[i], errp);
> +        if (*errp) {
> +            ret = false;
> +            goto exit;

This can break out of the loop before all elements in 'fds' are
initialized.

> +        }
> +    }
> +
> +    ret = ebpf_rss_load_fds(&n->ebpf_rss, fds[0], fds[1], fds[2], fds[3]);
> +
> +exit:
> +    if (!ret || *errp) {
> +        for (i = 0; i < nfds; i++) {
> +            close(fds[i]);
> +        }
> +    }

This now calls close() on uninitialized memory, killing
arbitary FDs QEMU has open elsewhere.

> +
> +    for (i = 0; i < nfds; i++) {
> +        g_free(fds_strs[i]);
> +    }

Not required if we use g_autoptr(GStrv)

> +
> +    return ret;
> +}
> +
> +static bool virtio_net_load_ebpf(VirtIONet *n, Error **errp)
> +{
> +    bool ret = false;
> +
> +    if (virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
> +        if (!(n->ebpf_rss_fds
> +                && virtio_net_load_ebpf_fds(n, errp))) {
> +            ret = ebpf_rss_load(&n->ebpf_rss);
> +        }
> +    }
> +
> +    return ret;
>  }
>  
>  static void virtio_net_unload_ebpf(VirtIONet *n)
> @@ -3738,7 +3821,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
>      net_rx_pkt_init(&n->rx_pkt);
>  
>      if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
> -        virtio_net_load_ebpf(n);
> +        virtio_net_load_ebpf(n, errp);
>      }
>  }
>  
> @@ -3900,6 +3983,7 @@ static Property virtio_net_properties[] = {
>                      VIRTIO_NET_F_RSS, false),
>      DEFINE_PROP_BIT64("hash", VirtIONet, host_features,
>                      VIRTIO_NET_F_HASH_REPORT, false),
> +    DEFINE_PROP_STRING("ebpf_rss_fds", VirtIONet, ebpf_rss_fds),
>      DEFINE_PROP_BIT64("guest_rsc_ext", VirtIONet, host_features,
>                      VIRTIO_NET_F_RSC_EXT, false),
>      DEFINE_PROP_UINT32("rsc_interval", VirtIONet, rsc_timeout,
> diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
> index ef234ffe7ef..e10ce88f918 100644
> --- a/include/hw/virtio/virtio-net.h
> +++ b/include/hw/virtio/virtio-net.h
> @@ -219,6 +219,7 @@ struct VirtIONet {
>      VirtioNetRssData rss_data;
>      struct NetRxPkt *rx_pkt;
>      struct EBPFRSSContext ebpf_rss;
> +    char *ebpf_rss_fds;
>  };
>  
>  size_t virtio_net_handle_ctrl_iov(VirtIODevice *vdev,
> -- 
> 2.39.1
> 

With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



  reply	other threads:[~2023-05-03 11:04 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-01  7:20 [PATCH 0/5] eBPF RSS through QMP support Andrew Melnychenko
2023-05-01  7:20 ` [PATCH 1/5] ebpf: Added eBPF initialization by fds and map update Andrew Melnychenko
2023-05-03 11:07   ` Daniel P. Berrangé
2023-05-07 21:39     ` Andrew Melnichenko
2023-05-01  7:20 ` [PATCH 2/5] virtio-net: Added property to load eBPF RSS with fds Andrew Melnychenko
2023-05-03 11:03   ` Daniel P. Berrangé [this message]
2023-05-07 21:35     ` Andrew Melnichenko
2023-05-01  7:20 ` [PATCH 3/5] ebpf: Added declaration/initialization routines Andrew Melnychenko
2023-05-01  7:21 ` [PATCH 4/5] qmp: Added new command to retrieve eBPF blob Andrew Melnychenko
2023-05-03 11:09   ` Daniel P. Berrangé
2023-05-07 22:05     ` Andrew Melnichenko
2023-05-01  7:21 ` [PATCH 5/5] ebpf: Updated eBPF program and skeleton Andrew Melnychenko
2023-05-03  8:22 ` [PATCH 0/5] eBPF RSS through QMP support Daniel P. Berrangé
2023-05-07 21:34   ` Andrew Melnichenko
  -- strict thread matches above, loose matches on Subject: below --
2023-02-19 16:20 [PATCH 0/5] eBPF RSS Helper support Andrew Melnychenko
2023-02-19 16:20 ` [PATCH 2/5] virtio-net: Added property to load eBPF RSS with fds Andrew Melnychenko
2021-07-13 15:37 [PATCH 0/5] ebpf: Added ebpf helper for libvirtd Andrew Melnychenko
2021-07-13 15:37 ` [PATCH 2/5] virtio-net: Added property to load eBPF RSS with fds Andrew Melnychenko
2021-08-20  3:36   ` Jason Wang
2021-08-25 18:18     ` Andrew Melnichenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZFI/cIIf6DKRwvCq@redhat.com \
    --to=berrange@redhat.com \
    --cc=andrew@daynix.com \
    --cc=armbru@redhat.com \
    --cc=eblake@redhat.com \
    --cc=jasowang@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=yan@daynix.com \
    --cc=yuri.benditovich@daynix.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.