Signed-off-by: Han Han <hhan@xxxxxxxxxx> --- docs/formatdomain.rst | 9 +++++++++ docs/schemas/domaincommon.rng | 5 +++++ src/conf/domain_conf.c | 16 ++++++++++++++++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 6 ++++++ 5 files changed, 37 insertions(+) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index a02802a954..289e7bf5f1 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -3548,6 +3548,15 @@ virtqueues are actually used depends on the feature negotiation between QEMU, vhost backends and guest drivers. Possible values are ``on`` or ``off``. :since:`Since 6.3.0 (QEMU and KVM only)` +This optional attribute ``page_per_vq`` controls the layout of the notification +capabilities exposed to the guest. When enabled, each virtio queue will have a +dedicated page on the device BAR exposed to the guest. It is recommended to be +used when vDPA is enabled on the hypervisor, as it enables mapping the +notification area to the physical device, which is only supported in page +granularity. The default is determined by QEMU. :since:`Since 7.8.0` +Note: In general you should leave this option alone, unless you are very certain +you know what you are doing. + :anchor:`<a id="elementsVirtioTransitional"/>` Virtio transitional devices diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index ec5bd91740..f71e375a33 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -6810,6 +6810,11 @@ <ref name="virOnOff"/> </attribute> </optional> + <optional> + <attribute name="page_per_vq"> + <ref name="virOnOff"/> + </attribute> + </optional> </define> <define name="usbmaster"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b8370f6950..04bdd110b6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1630,6 +1630,10 @@ virDomainVirtioOptionsParseXML(xmlNodePtr driver, &(*virtio)->packed) < 0) return -1; + if (virXMLPropTristateSwitch(driver, "page_per_vq", VIR_XML_PROP_NONE, + &(*virtio)->page_per_vq) < 0) + return -1; + return 0; } @@ -6314,6 +6318,10 @@ virDomainVirtioOptionsFormat(virBuffer *buf, virBufferAsprintf(buf, " packed='%s'", virTristateSwitchTypeToString(virtio->packed)); } + if (virtio->page_per_vq != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(buf, " page_per_vq='%s'", + virTristateSwitchTypeToString(virtio->page_per_vq)); + } } @@ -20784,6 +20792,14 @@ virDomainVirtioOptionsCheckABIStability(virDomainVirtioOptions *src, virTristateSwitchTypeToString(src->packed)); return false; } + if (src->page_per_vq != dst->page_per_vq) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target device page_per_vq option '%s' does not " + "match source '%s'"), + virTristateSwitchTypeToString(dst->page_per_vq), + virTristateSwitchTypeToString(src->page_per_vq)); + return false; + } return true; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c23c233184..d6bc3dd0d2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2733,6 +2733,7 @@ struct _virDomainVirtioOptions { virTristateSwitch iommu; virTristateSwitch ats; virTristateSwitch packed; + virTristateSwitch page_per_vq; }; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index f023d22f23..80401cf8c7 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -135,6 +135,12 @@ virDomainCheckVirtioOptionsAreAbsent(virDomainVirtioOptions *virtio) "for virtio devices")); return -1; } + + if (virtio->page_per_vq != VIR_TRISTATE_SWITCH_ABSENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("page_per_vq option is only supported for virtio devices")); + return -1; + } return 0; } -- 2.31.1