[PATCH 2/3] conf: Introduce support for virtio-sound devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds parsing of the virtio sound model, along with parsing
of virtio options and PCI/virtio-mmio address assignment.

A new 'streams' attribute is added for configuring number of PCM streams
(default is 2) in virtio sound devices. QEMU additionally has jacks and chmaps
parameters but these are currently stubbed, hence they are excluded in this
patch series.

Signed-off-by: Rayhan Faizel <rayhan.faizel@xxxxxxxxx>
---
 docs/formatdomain.rst             | 11 +++++++++--
 src/conf/domain_conf.c            | 25 +++++++++++++++++++++++++
 src/conf/domain_conf.h            |  4 ++++
 src/conf/domain_postparse.c       | 13 ++++++++++++-
 src/conf/schemas/domaincommon.rng | 11 +++++++++++
 src/libxl/libxl_domain.c          |  1 +
 src/qemu/qemu_command.c           |  1 +
 src/qemu/qemu_domain_address.c    |  9 +++++++++
 src/qemu/qemu_validate.c          |  8 ++++++++
 9 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index e2f66b982c..43d5928ffa 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -7390,8 +7390,9 @@ A virtual sound card can be attached to the host via the ``sound`` element.
    what real sound device is emulated. Valid values are specific to the
    underlying hypervisor, though typical choices are ``sb16``, ``es1370``,
    ``pcspk``, ``ac97`` (:since:`Since 0.6.0`), ``ich6`` (:since:`Since 0.8.8`),
-   ``ich9`` (:since:`Since 1.1.3`), ``usb`` (:since:`Since 1.2.8`) and ``ich7``
-   (:since:`Since 6.7.0`, bhyve only).
+   ``ich9`` (:since:`Since 1.1.3`), ``usb`` (:since:`Since 1.2.8`), ``ich7``
+   (:since:`Since 6.7.0`, bhyve only) and ``virtio``
+   (:since:`Since 10.3.0 and QEMU 8.2.0`).
 
 :since:`Since 0.9.13`, a sound element with ``ich6`` or ``ich9`` models can have
 optional sub-elements ``<codec>`` to attach various audio codecs to the audio
@@ -7419,6 +7420,12 @@ multi-channel mode by using the ``multichannel`` attribute::
 
   <sound model='usb' multichannel='yes'/>
 
+:since:`Since 10.3.0 and QEMU 8.2.0` the number of PCM streams in a ``virtio``
+sound device can be configured by using the ``streams`` attribute, which
+defaults to ``2`` if left unspecified::
+
+  <sound model='virtio' streams='2'/>
+
 Each ``sound`` element has an optional sub-element ``<address>`` which can tie
 the device to a particular PCI slot. See `Device Addresses`_.
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 48c5d546da..d63cb9bf64 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -778,6 +778,7 @@ VIR_ENUM_IMPL(virDomainSoundModel,
               "ich9",
               "usb",
               "ich7",
+              "virtio",
 );
 
 VIR_ENUM_IMPL(virDomainAudioType,
@@ -3211,6 +3212,7 @@ void virDomainSoundDefFree(virDomainSoundDef *def)
         virDomainSoundCodecDefFree(def->codecs[i]);
     g_free(def->codecs);
 
+    g_free(def->virtio);
     g_free(def);
 }
 
@@ -11881,6 +11883,13 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt,
             return NULL;
     }
 
+    if (def->model == VIR_DOMAIN_SOUND_MODEL_VIRTIO) {
+        if (virXMLPropUInt(node, "streams", 10,
+                           VIR_XML_PROP_NONZERO,
+                           &def->streams) < 0)
+            return NULL;
+    }
+
     audioNode = virXPathNode("./audio", ctxt);
     if (audioNode) {
         if (virXMLPropUInt(audioNode, "id", 10,
@@ -11892,6 +11901,10 @@ virDomainSoundDefParseXML(virDomainXMLOption *xmlopt,
     if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, &def->info, flags) < 0)
         return NULL;
 
+    if (virDomainVirtioOptionsParseXML(virXPathNode("./driver", ctxt),
+                                       &def->virtio) < 0)
+        return NULL;
+
     return g_steal_pointer(&def);
 }
 
@@ -11916,6 +11929,9 @@ virDomainSoundDefEquals(const virDomainSoundDef *a,
     if (a->multichannel != b->multichannel)
         return false;
 
+    if (a->streams != b->streams)
+        return false;
+
     if (a->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
         !virDomainDeviceInfoAddressIsEqual(&a->info, &b->info))
         return false;
@@ -24836,6 +24852,7 @@ virDomainSoundDefFormat(virBuffer *buf,
     const char *model = virDomainSoundModelTypeToString(def->model);
     g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
     g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+    g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER;
     size_t i;
 
     if (!model) {
@@ -24860,6 +24877,14 @@ virDomainSoundDefFormat(virBuffer *buf,
                           virTristateBoolTypeToString(def->multichannel));
     }
 
+    if (def->model == VIR_DOMAIN_SOUND_MODEL_VIRTIO) {
+        virBufferAsprintf(&attrBuf, " streams='%d'", def->streams);
+
+        virDomainVirtioOptionsFormat(&driverAttrBuf, def->virtio);
+
+        virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL);
+    }
+
     virXMLFormatElement(buf,  "sound", &attrBuf, &childBuf);
 
     return 0;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5925faaf1a..13ca722019 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1565,6 +1565,7 @@ typedef enum {
     VIR_DOMAIN_SOUND_MODEL_ICH9,
     VIR_DOMAIN_SOUND_MODEL_USB,
     VIR_DOMAIN_SOUND_MODEL_ICH7,
+    VIR_DOMAIN_SOUND_MODEL_VIRTIO,
 
     VIR_DOMAIN_SOUND_MODEL_LAST
 } virDomainSoundModel;
@@ -1586,6 +1587,9 @@ struct _virDomainSoundDef {
     virTristateBool multichannel;
 
     unsigned int audioId;
+
+    unsigned int streams;
+    virDomainVirtioOptions *virtio;
 };
 
 typedef enum {
diff --git a/src/conf/domain_postparse.c b/src/conf/domain_postparse.c
index cafa2d235d..112795ea65 100644
--- a/src/conf/domain_postparse.c
+++ b/src/conf/domain_postparse.c
@@ -677,6 +677,13 @@ virDomainInputDefPostParse(virDomainInputDef *input,
     }
 }
 
+static void
+virDomainSoundDefPostParse(virDomainSoundDef *sound)
+{
+    if (sound->model == VIR_DOMAIN_SOUND_MODEL_VIRTIO && sound->streams == 0)
+        sound->streams = 2;
+}
+
 static int
 virDomainDeviceDefPostParseCommon(virDomainDeviceDef *dev,
                                   const virDomainDef *def,
@@ -730,9 +737,13 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDef *dev,
         ret = 0;
         break;
 
+    case VIR_DOMAIN_DEVICE_SOUND:
+        virDomainSoundDefPostParse(dev->data.sound);
+        ret = 0;
+        break;
+
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_NET:
-    case VIR_DOMAIN_DEVICE_SOUND:
     case VIR_DOMAIN_DEVICE_WATCHDOG:
     case VIR_DOMAIN_DEVICE_GRAPHICS:
     case VIR_DOMAIN_DEVICE_HUB:
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index f386e46fae..5cdd8328b6 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -5057,6 +5057,7 @@
           <value>ich7</value>
           <value>ich9</value>
           <value>usb</value>
+          <value>virtio</value>
         </choice>
       </attribute>
       <optional>
@@ -5064,6 +5065,11 @@
           <ref name="virYesNo"/>
         </attribute>
       </optional>
+      <optional>
+        <attribute name="streams">
+          <ref name="uint32"/>
+        </attribute>
+      </optional>
       <interleave>
         <optional>
           <ref name="alias"/>
@@ -5084,6 +5090,11 @@
         <zeroOrMore>
           <ref name="codec"/>
         </zeroOrMore>
+        <optional>
+          <element name="driver">
+            <ref name="virtioOptions"/>
+          </element>
+        </optional>
       </interleave>
     </element>
   </define>
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 16c2ab973b..0f129ec69c 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -344,6 +344,7 @@ libxlDomainDefValidate(const virDomainDef *def,
             case VIR_DOMAIN_SOUND_MODEL_ICH7:
             case VIR_DOMAIN_SOUND_MODEL_USB:
             case VIR_DOMAIN_SOUND_MODEL_ICH9:
+            case VIR_DOMAIN_SOUND_MODEL_VIRTIO:
             case VIR_DOMAIN_SOUND_MODEL_LAST:
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                         _("unsupported audio model %1$s"),
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9d4563861f..5e69e71c6f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4479,6 +4479,7 @@ qemuBuildSoundDevCmd(virCommand *cmd,
     case VIR_DOMAIN_SOUND_MODEL_SB16:
         model = "sb16";
         break;
+    case VIR_DOMAIN_SOUND_MODEL_VIRTIO:
     case VIR_DOMAIN_SOUND_MODEL_PCSPK: /* pc-speaker is handled separately */
     case VIR_DOMAIN_SOUND_MODEL_ICH7:
     case VIR_DOMAIN_SOUND_MODEL_LAST:
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 7690021ca7..251f5b7e1a 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -324,6 +324,12 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDef *def,
         if (def->cryptos[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
             def->cryptos[i]->info.type = type;
     }
+
+    for (i = 0; i < def->nsounds; i++) {
+        if (def->sounds[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+            def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_VIRTIO)
+            def->sounds[i]->info.type = type;
+    }
 }
 
 
@@ -694,6 +700,9 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev,
         case VIR_DOMAIN_SOUND_MODEL_ICH9:
             return pciFlags;
 
+        case VIR_DOMAIN_SOUND_MODEL_VIRTIO:
+            return virtioFlags;
+
         case VIR_DOMAIN_SOUND_MODEL_SB16:
         case VIR_DOMAIN_SOUND_MODEL_PCSPK:
         case VIR_DOMAIN_SOUND_MODEL_USB:
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index de0867c4b1..9dea33bb53 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -4625,6 +4625,14 @@ qemuValidateDomainDeviceDefSound(virDomainSoundDef *sound,
         }
         break;
 
+    case VIR_DOMAIN_SOUND_MODEL_VIRTIO:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_SOUND)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("virtio-sound controller is not supported in this QEMU binary"));
+            return -1;
+        }
+        break;
+
     case VIR_DOMAIN_SOUND_MODEL_ES1370:
     case VIR_DOMAIN_SOUND_MODEL_AC97:
     case VIR_DOMAIN_SOUND_MODEL_ICH6:
-- 
2.34.1
_______________________________________________
Devel mailing list -- devel@xxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux