From nobody Sun May 5 10:03:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) client-ip=205.139.110.61; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1597776155; cv=none; d=zohomail.com; s=zohoarc; b=SebpfZYp9cp88mwmG1RbuAMSjMlL+U7Gi0PriWA8SGgbbkAhdjmtPj8eGsWvqWu2MboHj9m/TP71OktgzQAAWTVvlMNOAoque0TPy3J+RkunO5HiYpD2l6EWPJD4NTLDlrtrVdwkNNlwveQjaWmQqdB7zEtt1jkXGBsmF6WEB/o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1597776155; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=0pf/om8Sc+gT01buKz61IRAewhDJGi2zYZ9DIA+33bE=; b=IHh64M9t4VyG63ZjEAylXcYuD0RtxoP8dR5Q6HGAahOHQQgfTwAF0MCRT3kqltcNO5AMlw4JbFo+G/2Yxl+Lgi1szTeK/f/WqvrfPa+5/WmiVpyL8foJrDacB8I/m6TgJdFA1skYmKHlBRpwrveVW/OrhDtNrY+59M3qysDhcxA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 205.139.110.61 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) by mx.zohomail.com with SMTPS id 1597776155748820.2914941489533; Tue, 18 Aug 2020 11:42:35 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-576-JyPbiOOpOq2OlQQi6VisLA-1; Tue, 18 Aug 2020 14:42:31 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8B6B218686D0; Tue, 18 Aug 2020 18:42:24 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2E2FE59; Tue, 18 Aug 2020 18:42:23 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 280716034D; Tue, 18 Aug 2020 18:42:19 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 07IIbOS7031638 for ; Tue, 18 Aug 2020 14:37:24 -0400 Received: by smtp.corp.redhat.com (Postfix) id C9C0F100AE5E; Tue, 18 Aug 2020 18:37:24 +0000 (UTC) Received: from himantopus.redhat.com (ovpn-113-237.phx2.redhat.com [10.3.113.237]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7692810021AA; Tue, 18 Aug 2020 18:37:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1597776154; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=0pf/om8Sc+gT01buKz61IRAewhDJGi2zYZ9DIA+33bE=; b=BILAbNIZZ42nP2uSSgRk3Z6Q7e68mI6lWGy6vn/irWiv5YJs4X9tZ9kP2R5DeInuYl7NDV gokP8pE5yNYgNxhJDE1FUX2+JT5SX283KiBxe7CzWdxLs+EfIBgu4axbx0CuPTSZxx9/mX OIp76p8ReKzwRYnQi+WAYPBAN/MXm30= X-MC-Unique: JyPbiOOpOq2OlQQi6VisLA-1 From: Jonathon Jongsma To: libvir-list@redhat.com Subject: [libvirt PATCH] RFC: Add support for vDPA network devices Date: Tue, 18 Aug 2020 13:37:17 -0500 Message-Id: <20200818183717.165048-1-jjongsma@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com Cc: laine@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" vDPA network devices allow high-performance networking in a virtual machine by providing a wire-speed data path. These devices require a vendor-specific host driver but the data path follows the virtio specification. The support for vDPA devices was recently added to qemu. This allows libvirt to support these devices. It requires that the device is configured on the host with the appropriate vendor-specific driver. This will create a chardev on the host at e.g. /dev/vhost-vdpa-0. That chardev path can then be used to define a new interface with type=3D'vdpa'. --- docs/formatdomain.rst | 20 +++++++++ docs/schemas/domaincommon.rng | 15 +++++++ src/conf/domain_conf.c | 41 +++++++++++++++++++ src/conf/domain_conf.h | 4 ++ src/conf/netdev_bandwidth_conf.c | 1 + src/libxl/libxl_conf.c | 1 + src/libxl/xen_common.c | 1 + src/lxc/lxc_controller.c | 1 + src/lxc/lxc_driver.c | 3 ++ src/lxc/lxc_process.c | 1 + src/qemu/qemu_command.c | 29 ++++++++++++- src/qemu/qemu_command.h | 3 +- src/qemu/qemu_domain.c | 6 ++- src/qemu/qemu_hotplug.c | 15 ++++--- src/qemu/qemu_interface.c | 25 +++++++++++ src/qemu/qemu_interface.h | 2 + src/qemu/qemu_process.c | 1 + src/qemu/qemu_validate.c | 1 + src/vmx/vmx.c | 1 + .../net-vdpa.x86_64-latest.args | 37 +++++++++++++++++ tests/qemuxml2argvdata/net-vdpa.xml | 28 +++++++++++++ tests/qemuxml2argvmock.c | 11 ++++- tests/qemuxml2argvtest.c | 1 + tests/qemuxml2xmloutdata/net-vdpa.xml | 34 +++++++++++++++ tests/qemuxml2xmltest.c | 1 + tools/virsh-domain.c | 1 + 26 files changed, 274 insertions(+), 10 deletions(-) create mode 100644 tests/qemuxml2argvdata/net-vdpa.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/net-vdpa.xml create mode 100644 tests/qemuxml2xmloutdata/net-vdpa.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 8365fc8bbb..1356485504 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -4632,6 +4632,26 @@ or stopping the guest. ... =20 +:anchor:`` + +vDPA devices +^^^^^^^^^^^^ + +A vDPA device can be used to provide wire speed network performance within= a +domain. The host device must already be configured with the appropriate +device-specific vDPA driver. This creates a vDPA char device (e.g. +/dev/vhost-vdpa-0) that can be used to assign the device to a libvirt doma= in. + +:: + + ... + + + + + + ... + :anchor:`` =20 Teaming a virtio/hostdev NIC pair diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 0d0dcbc5ce..17f74490f4 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3108,6 +3108,21 @@ + + + + vdpa + + + + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8e7981bf25..74f2c2f3e3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -549,6 +549,7 @@ VIR_ENUM_IMPL(virDomainNet, "direct", "hostdev", "udp", + "vdpa", ); =20 VIR_ENUM_IMPL(virDomainNetModel, @@ -2495,6 +2496,10 @@ virDomainNetDefClear(virDomainNetDefPtr def) def->data.vhostuser =3D NULL; break; =20 + case VIR_DOMAIN_NET_TYPE_VDPA: + VIR_FREE(def->data.vdpa.devicepath); + break; + case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_CLIENT: case VIR_DOMAIN_NET_TYPE_MCAST: @@ -6489,6 +6494,15 @@ virDomainNetDefValidate(const virDomainNetDef *net) return -1; } =20 + if (net->type =3D=3D VIR_DOMAIN_NET_TYPE_VDPA && + net->model !=3D VIR_DOMAIN_NET_MODEL_VIRTIO) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid model for interface of type '%s': '%= s'"), + virDomainNetTypeToString(net->type), + virDomainNetModelTypeToString(net->model)); + return -1; + } + return 0; } =20 @@ -11982,6 +11996,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlop= t, g_autofree char *vhost_path =3D NULL; g_autofree char *teamingType =3D NULL; g_autofree char *teamingPersistent =3D NULL; + g_autofree char *vdpa_dev =3D NULL; const char *prefix =3D xmlopt ? xmlopt->config.netPrefix : NULL; =20 if (!(def =3D virDomainNetDefNew(xmlopt))) @@ -12075,6 +12090,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlo= pt, if (virDomainChrSourceReconnectDefParseXML(&reconnect, cur= , ctxt) < 0) goto error; =20 + } else if (!vdpa_dev + && def->type =3D=3D VIR_DOMAIN_NET_TYPE_VDPA + && virXMLNodeNameEqual(cur, "source")) { + vdpa_dev =3D virXMLPropString(cur, "dev"); } else if (!def->virtPortProfile && virXMLNodeNameEqual(cur, "virtualport")) { if (def->type =3D=3D VIR_DOMAIN_NET_TYPE_NETWORK) { @@ -12332,6 +12351,16 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlo= pt, } break; =20 + case VIR_DOMAIN_NET_TYPE_VDPA: + if (vdpa_dev =3D=3D NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("No 'dev' attribute " + "specified with ")); + goto error; + } + def->data.vdpa.devicepath =3D g_steal_pointer(&vdpa_dev); + break; + case VIR_DOMAIN_NET_TYPE_BRIDGE: if (bridge =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -12727,6 +12756,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlop= t, case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: break; case VIR_DOMAIN_NET_TYPE_LAST: default: @@ -26737,6 +26767,14 @@ virDomainNetDefFormat(virBufferPtr buf, } break; =20 + case VIR_DOMAIN_NET_TYPE_VDPA: + if (def->data.vdpa.devicepath) { + virBufferEscapeString(buf, "data.vdpa.devicepath); + sourceLines++; + } + break; + case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_LAST: break; @@ -30902,6 +30940,7 @@ virDomainNetGetActualVirtPortProfile(const virDomai= nNetDef *iface) case VIR_DOMAIN_NET_TYPE_MCAST: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: default: return NULL; @@ -31718,6 +31757,7 @@ virDomainNetTypeSharesHostView(const virDomainNetDe= f *net) case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: break; } @@ -31982,6 +32022,7 @@ virDomainNetDefActualToNetworkPort(virDomainDefPtr = dom, case VIR_DOMAIN_NET_TYPE_UDP: case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_VHOSTUSER: + case VIR_DOMAIN_NET_TYPE_VDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unexpected network port type %s"), virDomainNetTypeToString(virDomainNetGetActualType(= iface))); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 68be32614c..4f63a3eef4 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -872,6 +872,7 @@ typedef enum { VIR_DOMAIN_NET_TYPE_DIRECT, VIR_DOMAIN_NET_TYPE_HOSTDEV, VIR_DOMAIN_NET_TYPE_UDP, + VIR_DOMAIN_NET_TYPE_VDPA, =20 VIR_DOMAIN_NET_TYPE_LAST } virDomainNetType; @@ -1045,6 +1046,9 @@ struct _virDomainNetDef { */ virDomainActualNetDefPtr actual; } network; + struct { + char *devicepath; + } vdpa; struct { char *brname; } bridge; diff --git a/src/conf/netdev_bandwidth_conf.c b/src/conf/netdev_bandwidth_c= onf.c index 396ac62019..4eb12e2951 100644 --- a/src/conf/netdev_bandwidth_conf.c +++ b/src/conf/netdev_bandwidth_conf.c @@ -315,6 +315,7 @@ bool virNetDevSupportsBandwidth(virDomainNetType type) case VIR_DOMAIN_NET_TYPE_UDP: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: break; } diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 7c2c015015..709cdc8719 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1371,6 +1371,7 @@ libxlMakeNic(virDomainDefPtr def, case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_HOSTDEV: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unsupported interface type %s"), diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c index 75fe7e0644..b1ec34bf11 100644 --- a/src/libxl/xen_common.c +++ b/src/libxl/xen_common.c @@ -1776,6 +1776,7 @@ xenFormatNet(virConnectPtr conn, case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: case VIR_DOMAIN_NET_TYPE_USER: + case VIR_DOMAIN_NET_TYPE_VDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported net type= '%s'"), virDomainNetTypeToString(net->type)); return -1; diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index ae6b737b60..cb573d6c01 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -422,6 +422,7 @@ static int virLXCControllerGetNICIndexes(virLXCControll= erPtr ctrl) case VIR_DOMAIN_NET_TYPE_UDP: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: + case VIR_DOMAIN_NET_TYPE_VDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported net type %s"), virDomainNetTypeToString(actualType)); diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 1cdd6ee455..a36f83a588 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -3503,6 +3503,7 @@ lxcDomainAttachDeviceNetLive(virLXCDriverPtr driver, case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Network device type is not supported")); goto cleanup; @@ -3557,6 +3558,7 @@ lxcDomainAttachDeviceNetLive(virLXCDriverPtr driver, case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: default: /* no-op */ @@ -3998,6 +4000,7 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm, case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only bridged veth devices can be detached")); goto cleanup; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index fc59c2e5af..90e9790cea 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -606,6 +606,7 @@ virLXCProcessSetupInterfaces(virLXCDriverPtr driver, case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_LAST: case VIR_DOMAIN_NET_TYPE_HOSTDEV: + case VIR_DOMAIN_NET_TYPE_VDPA: virReportError(VIR_ERR_INTERNAL_ERROR, _("Unsupported network type %s"), virDomainNetTypeToString(type)); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 01812cd39b..9c5265ccdf 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3552,7 +3552,8 @@ qemuBuildHostNetStr(virDomainNetDefPtr net, size_t tapfdSize, char **vhostfd, size_t vhostfdSize, - const char *slirpfd) + const char *slirpfd, + const char *vdpafd) { bool is_tap =3D false; virDomainNetType netType =3D virDomainNetGetActualType(net); @@ -3690,6 +3691,13 @@ qemuBuildHostNetStr(virDomainNetDefPtr net, return NULL; break; =20 + case VIR_DOMAIN_NET_TYPE_VDPA: + /* Caller will pass the fd to qemu with add-fd */ + if (virJSONValueObjectCreate(&netprops, "s:type", "vhost-vdpa", NU= LL) < 0 || + virJSONValueObjectAppendString(netprops, "vhostdev", vdpafd) <= 0) + return NULL; + break; + case VIR_DOMAIN_NET_TYPE_HOSTDEV: /* Should have been handled earlier via PCI/USB hotplug code. */ case VIR_DOMAIN_NET_TYPE_LAST: @@ -8013,6 +8021,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, char **tapfdName =3D NULL; char **vhostfdName =3D NULL; g_autofree char *slirpfdName =3D NULL; + g_autofree char *vdpafdName =3D NULL; + int vdpafd =3D -1; virDomainNetType actualType =3D virDomainNetGetActualType(net); const virNetDevBandwidth *actualBandwidth; bool requireNicdev =3D false; @@ -8098,6 +8108,11 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr drive= r, =20 break; =20 + case VIR_DOMAIN_NET_TYPE_VDPA: + if ((vdpafd =3D qemuInterfaceVDPAConnect(net)) < 0) + goto cleanup; + break; + case VIR_DOMAIN_NET_TYPE_USER: case VIR_DOMAIN_NET_TYPE_SERVER: case VIR_DOMAIN_NET_TYPE_CLIENT: @@ -8140,6 +8155,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, case VIR_DOMAIN_NET_TYPE_UDP: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: /* These types don't use a network device on the host, but * instead use some other type of connection to the emulated @@ -8219,13 +8235,22 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driv= er, vhostfd[i] =3D -1; } =20 + if (vdpafd > 0) { + virCommandPassFD(cmd, vdpafd, VIR_COMMAND_PASS_FD_CLOSE_PARENT); + g_autofree char *fdset =3D qemuVirCommandGetFDSet(cmd, vdpafd); + if (!fdset) + goto cleanup; + virCommandAddArgList(cmd, "-add-fd", fdset, NULL); + vdpafdName =3D qemuVirCommandGetDevSet(cmd, vdpafd); + } + if (chardev) virCommandAddArgList(cmd, "-chardev", chardev, NULL); =20 if (!(hostnetprops =3D qemuBuildHostNetStr(net, tapfdName, tapfdSize, vhostfdName, vhostfdSize, - slirpfdName))) + slirpfdName, vdpafdName))) goto cleanup; =20 if (!(host =3D virQEMUBuildNetdevCommandlineFromJSON(hostnetprops, diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 89d99b111f..e8b4f4785a 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -99,7 +99,8 @@ virJSONValuePtr qemuBuildHostNetStr(virDomainNetDefPtr ne= t, size_t tapfdSize, char **vhostfd, size_t vhostfdSize, - const char *slirpfd); + const char *slirpfd, + const char *vdpafd); =20 /* Current, best practice */ char *qemuBuildNicDevStr(virDomainDefPtr def, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index c440c79e1d..daae5a1b03 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5027,7 +5027,10 @@ qemuDomainDeviceNetDefPostParse(virDomainNetDefPtr n= et, const virDomainDef *def, virQEMUCapsPtr qemuCaps) { - if (net->type !=3D VIR_DOMAIN_NET_TYPE_HOSTDEV && + if (net->type =3D=3D VIR_DOMAIN_NET_TYPE_VDPA && + !virDomainNetGetModelString(net)) + net->model =3D VIR_DOMAIN_NET_MODEL_VIRTIO; + else if (net->type !=3D VIR_DOMAIN_NET_TYPE_HOSTDEV && !virDomainNetGetModelString(net) && virDomainNetResolveActualType(net) !=3D VIR_DOMAIN_NET_TYPE_HOSTDE= V) net->model =3D qemuDomainDefaultNetModel(def, qemuCaps); @@ -9201,6 +9204,7 @@ qemuDomainNetSupportsMTU(virDomainNetType type) case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: break; } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 2c6c30ce03..23ae2310a2 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1340,6 +1340,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, case VIR_DOMAIN_NET_TYPE_MCAST: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("hotplug of interface type of %s is not implement= ed yet"), @@ -1388,7 +1389,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, if (!(netprops =3D qemuBuildHostNetStr(net, tapfdName, tapfdSize, vhostfdName, vhostfdSize, - slirpfdName))) + slirpfdName, NULL))) goto cleanup; =20 qemuDomainObjEnterMonitor(driver, vm); @@ -3390,6 +3391,7 @@ qemuDomainChangeNetFilter(virDomainObjPtr vm, case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("filters not supported on interfaces of type %s"), virDomainNetTypeToString(virDomainNetGetActualType(= newdev))); @@ -3483,8 +3485,9 @@ qemuDomainChangeNet(virQEMUDriverPtr driver, olddev =3D *devslot; =20 oldType =3D virDomainNetGetActualType(olddev); - if (oldType =3D=3D VIR_DOMAIN_NET_TYPE_HOSTDEV) { - /* no changes are possible to a type=3D'hostdev' interface */ + if (oldType =3D=3D VIR_DOMAIN_NET_TYPE_HOSTDEV || + oldType =3D=3D VIR_DOMAIN_NET_TYPE_VDPA) { + /* no changes are possible to a type=3D'hostdev' or type=3D'vdpa' = interface */ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("cannot change config of '%s' network type"), virDomainNetTypeToString(oldType)); @@ -3671,8 +3674,9 @@ qemuDomainChangeNet(virQEMUDriverPtr driver, =20 newType =3D virDomainNetGetActualType(newdev); =20 - if (newType =3D=3D VIR_DOMAIN_NET_TYPE_HOSTDEV) { - /* can't turn it into a type=3D'hostdev' interface */ + if (newType =3D=3D VIR_DOMAIN_NET_TYPE_HOSTDEV || + newType =3D=3D VIR_DOMAIN_NET_TYPE_VDPA) { + /* can't turn it into a type=3D'hostdev' or type=3D'vdpa' interfac= e */ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("cannot change network interface type to '%s'"), virDomainNetTypeToString(newType)); @@ -3726,6 +3730,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver, break; =20 case VIR_DOMAIN_NET_TYPE_VHOSTUSER: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_HOSTDEV: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("unable to change config on '%s' network type= "), diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c index ffec992596..676648ebab 100644 --- a/src/qemu/qemu_interface.c +++ b/src/qemu/qemu_interface.c @@ -118,6 +118,7 @@ qemuInterfaceStartDevice(virDomainNetDefPtr net) case VIR_DOMAIN_NET_TYPE_UDP: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: /* these types all require no action */ break; @@ -203,6 +204,7 @@ qemuInterfaceStopDevice(virDomainNetDefPtr net) case VIR_DOMAIN_NET_TYPE_UDP: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: /* these types all require no action */ break; @@ -630,6 +632,29 @@ qemuInterfaceBridgeConnect(virDomainDefPtr def, } =20 =20 +/* qemuInterfaceVDPAConnect: + * @net: pointer to the VM's interface description + * + * returns: file descriptor of the vdpa device + * + * Called *only* called if actualType is VIR_DOMAIN_NET_TYPE_VDPA + */ +int +qemuInterfaceVDPAConnect(virDomainNetDefPtr net) +{ + int fd; + + if ((fd =3D open(net->data.vdpa.devicepath, O_RDWR)) < 0) { + virReportSystemError(errno, + _("Unable to open '%s' for vdpa device"), + net->data.vdpa.devicepath); + return -1; + } + + return fd; +} + + qemuSlirpPtr qemuInterfacePrepareSlirp(virQEMUDriverPtr driver, virDomainNetDefPtr net) diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h index 3dcefc6a12..1ba24f0a6f 100644 --- a/src/qemu/qemu_interface.h +++ b/src/qemu/qemu_interface.h @@ -58,3 +58,5 @@ int qemuInterfaceOpenVhostNet(virDomainDefPtr def, =20 qemuSlirpPtr qemuInterfacePrepareSlirp(virQEMUDriverPtr driver, virDomainNetDefPtr net); + +int qemuInterfaceVDPAConnect(virDomainNetDefPtr net) G_GNUC_NO_INLINE; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 126fabf5ef..70c3b9b46d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7517,6 +7517,7 @@ void qemuProcessStop(virQEMUDriverPtr driver, case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: /* No special cleanup procedure for these types. */ break; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 488f258d00..623f998463 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -1130,6 +1130,7 @@ qemuValidateNetSupportsCoalesce(virDomainNetType type) case VIR_DOMAIN_NET_TYPE_MCAST: case VIR_DOMAIN_NET_TYPE_INTERNAL: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: break; } diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index a123a8807c..f6f6efb322 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -3833,6 +3833,7 @@ virVMXFormatEthernet(virDomainNetDefPtr def, int cont= roller, case VIR_DOMAIN_NET_TYPE_DIRECT: case VIR_DOMAIN_NET_TYPE_HOSTDEV: case VIR_DOMAIN_NET_TYPE_UDP: + case VIR_DOMAIN_NET_TYPE_VDPA: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unsupported net type= '%s'"), virDomainNetTypeToString(def->type)); return -1; diff --git a/tests/qemuxml2argvdata/net-vdpa.x86_64-latest.args b/tests/qem= uxml2argvdata/net-vdpa.x86_64-latest.args new file mode 100644 index 0000000000..8e76ac7794 --- /dev/null +++ b/tests/qemuxml2argvdata/net-vdpa.x86_64-latest.args @@ -0,0 +1,37 @@ +LC_ALL=3DC \ +PATH=3D/bin \ +HOME=3D/tmp/lib/domain--1-QEMUGuest1 \ +USER=3Dtest \ +LOGNAME=3Dtest \ +XDG_DATA_HOME=3D/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=3D/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=3D/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=3Dnone \ +/usr/bin/qemu-system-i386 \ +-name guest=3DQEMUGuest1,debug-threads=3Don \ +-S \ +-object secret,id=3DmasterKey0,format=3Draw,\ +file=3D/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pc,accel=3Dtcg,usb=3Doff,dump-guest-core=3Doff \ +-cpu qemu64 \ +-m 214 \ +-overcommit mem-lock=3Doff \ +-smp 1,sockets=3D1,cores=3D1,threads=3D1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=3Dcharmonitor,fd=3D1729,server,nowait \ +-mon chardev=3Dcharmonitor,id=3Dmonitor,mode=3Dcontrol \ +-rtc base=3Dutc \ +-no-shutdown \ +-no-acpi \ +-boot strict=3Don \ +-device piix3-usb-uhci,id=3Dusb,bus=3Dpci.0,addr=3D0x1.0x2 \ +-add-fd set=3D0,fd=3D1732 \ +-netdev vhost-vdpa,vhostdev=3D/dev/fdset/0,id=3Dhostnet0 \ +-device virtio-net-pci,netdev=3Dhostnet0,id=3Dnet0,mac=3D52:54:00:95:db:c0= ,bus=3Dpci.0,\ +addr=3D0x2 \ +-sandbox on,obsolete=3Ddeny,elevateprivileges=3Ddeny,spawn=3Ddeny,\ +resourcecontrol=3Ddeny \ +-msg timestamp=3Don diff --git a/tests/qemuxml2argvdata/net-vdpa.xml b/tests/qemuxml2argvdata/n= et-vdpa.xml new file mode 100644 index 0000000000..30cca7eb6e --- /dev/null +++ b/tests/qemuxml2argvdata/net-vdpa.xml @@ -0,0 +1,28 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-i386 + + + + + + + + + + + + diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c index e5841bc8e3..516776697f 100644 --- a/tests/qemuxml2argvmock.c +++ b/tests/qemuxml2argvmock.c @@ -205,7 +205,7 @@ virHostGetDRMRenderNode(void) =20 static void (*real_virCommandPassFD)(virCommandPtr cmd, int fd, unsigned i= nt flags); =20 -static const int testCommandPassSafeFDs[] =3D { 1730, 1731 }; +static const int testCommandPassSafeFDs[] =3D { 1730, 1731, 1732 }; =20 void virCommandPassFD(virCommandPtr cmd, @@ -283,3 +283,12 @@ qemuBuildTPMOpenBackendFDs(const char *tpmdev G_GNUC_U= NUSED, *cancelfd =3D 1731; return 0; } + + +int +qemuInterfaceVDPAConnect(virDomainNetDefPtr net G_GNUC_UNUSED) +{ + if (fcntl(1732, F_GETFD) !=3D -1) + abort(); + return 1732; +} diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 01839cb88c..9587e1f2f2 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1446,6 +1446,7 @@ mymain(void) QEMU_CAPS_DEVICE_VFIO_PCI); DO_TEST_FAILURE("net-hostdev-fail", QEMU_CAPS_DEVICE_VFIO_PCI); + DO_TEST_CAPS_LATEST("net-vdpa"); =20 DO_TEST("hostdev-pci-multifunction", QEMU_CAPS_KVM, diff --git a/tests/qemuxml2xmloutdata/net-vdpa.xml b/tests/qemuxml2xmloutda= ta/net-vdpa.xml new file mode 100644 index 0000000000..b362405c14 --- /dev/null +++ b/tests/qemuxml2xmloutdata/net-vdpa.xml @@ -0,0 +1,34 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-i386 + +
+ + +
+ + + + + + +
+ + + + + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index a07e2b7553..978babb110 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -494,6 +494,7 @@ mymain(void) DO_TEST("net-mtu", NONE); DO_TEST("net-coalesce", NONE); DO_TEST("net-many-models", NONE); + DO_TEST("net-vdpa", NONE); =20 DO_TEST("serial-tcp-tlsx509-chardev", NONE); DO_TEST("serial-tcp-tlsx509-chardev-notls", NONE); diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 286cf79671..10b396bcf0 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -1007,6 +1007,7 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd) case VIR_DOMAIN_NET_TYPE_MCAST: case VIR_DOMAIN_NET_TYPE_UDP: case VIR_DOMAIN_NET_TYPE_INTERNAL: + case VIR_DOMAIN_NET_TYPE_VDPA: case VIR_DOMAIN_NET_TYPE_LAST: vshError(ctl, _("No support for %s in command 'attach-interface'"), type); --=20 2.26.2