[PATCH v4 1/3] qemu: support riscv-aia feature for RISC-V KVM
From: xiangwencheng <xiangwencheng@lanxincomputing.com> riscv-aia feature was introduced in qemu-8.2 to specify the KVM AIA mode. The "riscv-aia" parameter is passed along with -accel in QEMU command-line. 1) "riscv-aia=emul": IMSIC is emulated by hypervisor 2) "riscv-aia=hwaccel": use hardware guest IMSIC 3) "riscv-aia=auto": use the hardware guest IMSICs whenever available otherwise we fallback to software emulation. This patch add the corresponding feature named 'riscv-aia'. Signed-off-by: BillXiang <xiangwencheng@lanxincomputing.com> --- v3[1] -> v4: - Add XML tests. - Fix broken indentations. - Remove optional mark of 'mode' in XML schema. [1] https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/CGZIW... --- docs/formatdomain.rst | 7 +++++++ src/conf/domain_conf.c | 28 +++++++++++++++++++++++++++- src/conf/domain_conf.h | 11 +++++++++++ src/conf/schemas/domaincommon.rng | 10 ++++++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_command.c | 13 ++++++++++--- 6 files changed, 67 insertions(+), 4 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index f50dce477f..3ac8c315db 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -2085,6 +2085,7 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off. <poll-control state='on'/> <pv-ipi state='off'/> <dirty-ring state='on' size='4096'/> + <riscv-aia state='on' mode='auto'/> </kvm> <xen> <e820_host state='on'/> @@ -2206,6 +2207,12 @@ are: poll-control Decrease IO completion latency by introducing a grace period of busy waiting on, off :since:`6.10.0 (QEMU 4.2)` pv-ipi Paravirtualized send IPIs on, off :since:`7.10.0 (QEMU 3.1)` dirty-ring Enable dirty ring feature on, off; size - must be power of 2, range [1024,65536] :since:`8.0.0 (QEMU 6.1)` + riscv-aia Set riscv KVM AIA mode. Defaults to 'auto'. on, off; mode - must be emul, hwaccel or auto :since:`11.8.0 (QEMU 8.2)` + The "riscv-aia" parameter is passed along with --accel in QEMU command-line. + 1) "riscv-aia=emul": IMSIC is emulated by hypervisor + 2) "riscv-aia=hwaccel": use hardware guest IMSIC + 3) "riscv-aia=auto": use the hardware guest IMSICs whenever available + otherwise we fallback to software emulation. ============== ============================================================================ ====================================================== ============================ ``xen`` diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 281846dfbe..bd52429881 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -224,6 +224,14 @@ VIR_ENUM_IMPL(virDomainKVM, "poll-control", "pv-ipi", "dirty-ring", + "riscv-aia", +); + +VIR_ENUM_IMPL(virDomainKVMRiscvAIAMode, + VIR_DOMAIN_KVM_RISCV_AIA_MODE_LAST, + "auto", + "emul", + "hwaccel", ); VIR_ENUM_IMPL(virDomainXen, @@ -17213,6 +17221,15 @@ virDomainFeaturesKVMDefParse(virDomainDef *def, return -1; } } + + if (feature == VIR_DOMAIN_KVM_RISCV_AIA && + value == VIR_TRISTATE_SWITCH_ON) { + if (virXMLPropEnum(feat, "mode", + virDomainKVMRiscvAIAModeTypeFromString, + VIR_XML_PROP_REQUIRED, + &def->kvm_features->kvm_riscv_aia_mode) < 0) + return -1; + } } def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON; @@ -21729,6 +21746,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src, case VIR_DOMAIN_KVM_POLLCONTROL: case VIR_DOMAIN_KVM_PVIPI: case VIR_DOMAIN_KVM_DIRTY_RING: + case VIR_DOMAIN_KVM_RISCV_AIA: if (src->kvm_features->features[i] != dst->kvm_features->features[i]) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("State of KVM feature '%1$s' differs: source: '%2$s', destination: '%3$s'"), @@ -28786,7 +28804,15 @@ virDomainDefFormatFeatures(virBuffer *buf, } } break; - + case VIR_DOMAIN_KVM_RISCV_AIA: + if (def->kvm_features->features[j] != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(&childBuf, "<%s state='%s'", + virDomainKVMTypeToString(j), + virTristateSwitchTypeToString(def->kvm_features->features[j])); + virBufferAsprintf(&childBuf, " mode='%s'/>\n", + virDomainKVMRiscvAIAModeTypeToString(def->kvm_features->kvm_riscv_aia_mode)); + } + break; case VIR_DOMAIN_KVM_LAST: break; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 39807b5fe3..457dcce039 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2272,10 +2272,20 @@ typedef enum { VIR_DOMAIN_KVM_POLLCONTROL, VIR_DOMAIN_KVM_PVIPI, VIR_DOMAIN_KVM_DIRTY_RING, + VIR_DOMAIN_KVM_RISCV_AIA, VIR_DOMAIN_KVM_LAST } virDomainKVM; +typedef enum { + VIR_DOMAIN_KVM_RISCV_AIA_MODE_AUTO = 0, + VIR_DOMAIN_KVM_RISCV_AIA_MODE_EMUL, + VIR_DOMAIN_KVM_RISCV_AIA_MODE_HWACCEL, + + VIR_DOMAIN_KVM_RISCV_AIA_MODE_LAST +} virDomainKVMRiscvAIAMode; +VIR_ENUM_DECL(virDomainKVMRiscvAIAMode); + typedef enum { VIR_DOMAIN_MSRS_UNKNOWN = 0, @@ -2478,6 +2488,7 @@ struct _virDomainFeatureKVM { int features[VIR_DOMAIN_KVM_LAST]; unsigned int dirty_ring_size; /* size of dirty ring for each vCPU, no units */ + virDomainKVMRiscvAIAMode kvm_riscv_aia_mode; }; typedef struct _virDomainFeatureTCG virDomainFeatureTCG; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index b9230a35b4..888477acc9 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -8207,6 +8207,16 @@ </optional> </element> </optional> + <optional> + <element name="riscv-aia"> + <ref name="featurestate"/> + <attribute name="mode"> + <data type="string"> + <param name="pattern">(auto|emul|hwaccel)</param> + </data> + </attribute> + </element> + </optional> </interleave> </element> </define> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fe72402527..dfa54c2d68 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -501,6 +501,8 @@ virDomainIOThreadIDDel; virDomainIOThreadIDFind; virDomainKeyWrapCipherNameTypeFromString; virDomainKeyWrapCipherNameTypeToString; +virDomainKVMRiscvAIAModeTypeFromString; +virDomainKVMRiscvAIAModeTypeToString; virDomainLaunchSecurityTypeFromString; virDomainLaunchSecurityTypeToString; virDomainLeaseDefFree; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 031f09b7a5..ff07c1d95f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6720,6 +6720,9 @@ qemuBuildCpuCommandLine(virCommand *cmd, case VIR_DOMAIN_KVM_DIRTY_RING: break; + + case VIR_DOMAIN_KVM_RISCV_AIA: + break; case VIR_DOMAIN_KVM_LAST: break; @@ -7355,9 +7358,13 @@ qemuBuildAccelCommandLine(virCommand *cmd, * not that either kvm or tcg can be specified by libvirt * so do not worry about the conflict of specifying both * */ - if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON && - def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) { - virBufferAsprintf(&buf, ",dirty-ring-size=%d", def->kvm_features->dirty_ring_size); + if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) { + if (def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(&buf, ",dirty-ring-size=%d", def->kvm_features->dirty_ring_size); + } + if (def->kvm_features->features[VIR_DOMAIN_KVM_RISCV_AIA] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(&buf, ",riscv-aia=%s", virDomainKVMRiscvAIAModeTypeToString(def->kvm_features->kvm_riscv_aia_mode)); + } } break; -- 2.34.1
On 9/18/2025 1:44 PM, BillXiang wrote:
From: xiangwencheng <xiangwencheng@lanxincomputing.com>
riscv-aia feature was introduced in qemu-8.2 to specify the KVM AIA mode. The "riscv-aia" parameter is passed along with -accel in QEMU command-line. 1) "riscv-aia=emul": IMSIC is emulated by hypervisor 2) "riscv-aia=hwaccel": use hardware guest IMSIC 3) "riscv-aia=auto": use the hardware guest IMSICs whenever available otherwise we fallback to software emulation.
This patch add the corresponding feature named 'riscv-aia'.
Signed-off-by: BillXiang <xiangwencheng@lanxincomputing.com> --- v3[1] -> v4: - Add XML tests. - Fix broken indentations. - Remove optional mark of 'mode' in XML schema. [1] https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/CGZIW...
Gentle ping.
--- docs/formatdomain.rst | 7 +++++++ src/conf/domain_conf.c | 28 +++++++++++++++++++++++++++- src/conf/domain_conf.h | 11 +++++++++++ src/conf/schemas/domaincommon.rng | 10 ++++++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_command.c | 13 ++++++++++--- 6 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index f50dce477f..3ac8c315db 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -2085,6 +2085,7 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off. <poll-control state='on'/> <pv-ipi state='off'/> <dirty-ring state='on' size='4096'/> + <riscv-aia state='on' mode='auto'/> </kvm> <xen> <e820_host state='on'/> @@ -2206,6 +2207,12 @@ are: poll-control Decrease IO completion latency by introducing a grace period of busy waiting on, off :since:`6.10.0 (QEMU 4.2)` pv-ipi Paravirtualized send IPIs on, off :since:`7.10.0 (QEMU 3.1)` dirty-ring Enable dirty ring feature on, off; size - must be power of 2, range [1024,65536] :since:`8.0.0 (QEMU 6.1)` + riscv-aia Set riscv KVM AIA mode. Defaults to 'auto'. on, off; mode - must be emul, hwaccel or auto :since:`11.8.0 (QEMU 8.2)` + The "riscv-aia" parameter is passed along with --accel in QEMU command-line. + 1) "riscv-aia=emul": IMSIC is emulated by hypervisor + 2) "riscv-aia=hwaccel": use hardware guest IMSIC + 3) "riscv-aia=auto": use the hardware guest IMSICs whenever available + otherwise we fallback to software emulation. ============== ============================================================================ ====================================================== ============================
``xen`` diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 281846dfbe..bd52429881 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -224,6 +224,14 @@ VIR_ENUM_IMPL(virDomainKVM, "poll-control", "pv-ipi", "dirty-ring", + "riscv-aia", +); + +VIR_ENUM_IMPL(virDomainKVMRiscvAIAMode, + VIR_DOMAIN_KVM_RISCV_AIA_MODE_LAST, + "auto", + "emul", + "hwaccel", );
VIR_ENUM_IMPL(virDomainXen, @@ -17213,6 +17221,15 @@ virDomainFeaturesKVMDefParse(virDomainDef *def, return -1; } } + + if (feature == VIR_DOMAIN_KVM_RISCV_AIA && + value == VIR_TRISTATE_SWITCH_ON) { + if (virXMLPropEnum(feat, "mode", + virDomainKVMRiscvAIAModeTypeFromString, + VIR_XML_PROP_REQUIRED, + &def->kvm_features->kvm_riscv_aia_mode) < 0) + return -1; + } }
def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON; @@ -21729,6 +21746,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src, case VIR_DOMAIN_KVM_POLLCONTROL: case VIR_DOMAIN_KVM_PVIPI: case VIR_DOMAIN_KVM_DIRTY_RING: + case VIR_DOMAIN_KVM_RISCV_AIA: if (src->kvm_features->features[i] != dst->kvm_features->features[i]) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("State of KVM feature '%1$s' differs: source: '%2$s', destination: '%3$s'"), @@ -28786,7 +28804,15 @@ virDomainDefFormatFeatures(virBuffer *buf, } } break; - + case VIR_DOMAIN_KVM_RISCV_AIA: + if (def->kvm_features->features[j] != VIR_TRISTATE_SWITCH_ABSENT) { + virBufferAsprintf(&childBuf, "<%s state='%s'", + virDomainKVMTypeToString(j), + virTristateSwitchTypeToString(def->kvm_features->features[j])); + virBufferAsprintf(&childBuf, " mode='%s'/>\n", + virDomainKVMRiscvAIAModeTypeToString(def->kvm_features->kvm_riscv_aia_mode)); + } + break; case VIR_DOMAIN_KVM_LAST: break; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 39807b5fe3..457dcce039 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2272,10 +2272,20 @@ typedef enum { VIR_DOMAIN_KVM_POLLCONTROL, VIR_DOMAIN_KVM_PVIPI, VIR_DOMAIN_KVM_DIRTY_RING, + VIR_DOMAIN_KVM_RISCV_AIA,
VIR_DOMAIN_KVM_LAST } virDomainKVM;
+typedef enum { + VIR_DOMAIN_KVM_RISCV_AIA_MODE_AUTO = 0, + VIR_DOMAIN_KVM_RISCV_AIA_MODE_EMUL, + VIR_DOMAIN_KVM_RISCV_AIA_MODE_HWACCEL, + + VIR_DOMAIN_KVM_RISCV_AIA_MODE_LAST +} virDomainKVMRiscvAIAMode; +VIR_ENUM_DECL(virDomainKVMRiscvAIAMode); + typedef enum { VIR_DOMAIN_MSRS_UNKNOWN = 0,
@@ -2478,6 +2488,7 @@ struct _virDomainFeatureKVM { int features[VIR_DOMAIN_KVM_LAST];
unsigned int dirty_ring_size; /* size of dirty ring for each vCPU, no units */ + virDomainKVMRiscvAIAMode kvm_riscv_aia_mode; };
typedef struct _virDomainFeatureTCG virDomainFeatureTCG; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index b9230a35b4..888477acc9 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -8207,6 +8207,16 @@ </optional> </element> </optional> + <optional> + <element name="riscv-aia"> + <ref name="featurestate"/> + <attribute name="mode"> + <data type="string"> + <param name="pattern">(auto|emul|hwaccel)</param> + </data> + </attribute> + </element> + </optional> </interleave> </element> </define> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fe72402527..dfa54c2d68 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -501,6 +501,8 @@ virDomainIOThreadIDDel; virDomainIOThreadIDFind; virDomainKeyWrapCipherNameTypeFromString; virDomainKeyWrapCipherNameTypeToString; +virDomainKVMRiscvAIAModeTypeFromString; +virDomainKVMRiscvAIAModeTypeToString; virDomainLaunchSecurityTypeFromString; virDomainLaunchSecurityTypeToString; virDomainLeaseDefFree; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 031f09b7a5..ff07c1d95f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6720,6 +6720,9 @@ qemuBuildCpuCommandLine(virCommand *cmd,
case VIR_DOMAIN_KVM_DIRTY_RING: break; + + case VIR_DOMAIN_KVM_RISCV_AIA: + break;
case VIR_DOMAIN_KVM_LAST: break; @@ -7355,9 +7358,13 @@ qemuBuildAccelCommandLine(virCommand *cmd, * not that either kvm or tcg can be specified by libvirt * so do not worry about the conflict of specifying both * */ - if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON && - def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) { - virBufferAsprintf(&buf, ",dirty-ring-size=%d", def->kvm_features->dirty_ring_size); + if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) { + if (def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(&buf, ",dirty-ring-size=%d", def->kvm_features->dirty_ring_size); + } + if (def->kvm_features->features[VIR_DOMAIN_KVM_RISCV_AIA] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(&buf, ",riscv-aia=%s", virDomainKVMRiscvAIAModeTypeToString(def->kvm_features->kvm_riscv_aia_mode)); + } } break;
On Thu, Sep 18, 2025 at 01:44:05PM +0800, BillXiang wrote:
+++ b/docs/formatdomain.rst @@ -2206,6 +2207,12 @@ are: poll-control Decrease IO completion latency by introducing a grace period of busy waiting on, off :since:`6.10.0 (QEMU 4.2)` pv-ipi Paravirtualized send IPIs on, off :since:`7.10.0 (QEMU 3.1)` dirty-ring Enable dirty ring feature on, off; size - must be power of 2, range [1024,65536] :since:`8.0.0 (QEMU 6.1)` + riscv-aia Set riscv KVM AIA mode. Defaults to 'auto'. on, off; mode - must be emul, hwaccel or auto :since:`11.8.0 (QEMU 8.2)` + The "riscv-aia" parameter is passed along with --accel in QEMU command-line. + 1) "riscv-aia=emul": IMSIC is emulated by hypervisor + 2) "riscv-aia=hwaccel": use hardware guest IMSIC + 3) "riscv-aia=auto": use the hardware guest IMSICs whenever available + otherwise we fallback to software emulation.
This doesn't build: [377/617] Generating 'docs/formatdomain.html.p/formatdomain.html.in' (wrapped by meson to capture output) FAILED: [code=1] docs/formatdomain.html.p/formatdomain.html.in /usr/bin/meson --internal exe --capture docs/formatdomain.html.p/formatdomain.html.in -- /sbin/rst2html5 --exit-status=1 --stylesheet= --strict ../docs/formatdomain.rst --- stderr --- ../docs/formatdomain.rst:2224: (ERROR/3) Unexpected indentation. Exiting due to level-3 (ERROR) system message. Please make sure that libvirt builds *and* the test suite passes after each patch of your series. This bit of documentation appears to have been lifted verbatim from https://gitlab.com/qemu-project/qemu/-/commit/9634ef7eda5f5b57f03924351a213b... Please rewrite it so that it's less redundant (no need to repeat the name of the feature so many times) and only information that is relevant to libvirt users is included (mentioning QEMU's --accel option is not useful). As a last note, this missed the 11.8.0 release and will not make it into the upcoming 11.9.0 release either, so the :since: information will need to be updated to reflect reality.
+++ b/src/conf/schemas/domaincommon.rng @@ -8207,6 +8207,16 @@ </optional> </element> </optional> + <optional> + <element name="riscv-aia"> + <ref name="featurestate"/> + <attribute name="mode"> + <data type="string"> + <param name="pattern">(auto|emul|hwaccel)</param> + </data> + </attribute>
I believe this could be <attribute name="mode"> <choice> <value>auto</value> <value>emul</value> <value>hwaccel</value> </choice> </attribute>
+++ b/src/qemu/qemu_command.c @@ -6720,6 +6720,9 @@ qemuBuildCpuCommandLine(virCommand *cmd,
case VIR_DOMAIN_KVM_DIRTY_RING: break; + + case VIR_DOMAIN_KVM_RISCV_AIA: + break;
There's some spurious whitespace in this hunk. Please get rid of it.
@@ -7355,9 +7358,13 @@ qemuBuildAccelCommandLine(virCommand *cmd, * not that either kvm or tcg can be specified by libvirt * so do not worry about the conflict of specifying both * */ - if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON && - def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) { - virBufferAsprintf(&buf, ",dirty-ring-size=%d", def->kvm_features->dirty_ring_size); + if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) { + if (def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(&buf, ",dirty-ring-size=%d", def->kvm_features->dirty_ring_size); + } + if (def->kvm_features->features[VIR_DOMAIN_KVM_RISCV_AIA] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(&buf, ",riscv-aia=%s", virDomainKVMRiscvAIAModeTypeToString(def->kvm_features->kvm_riscv_aia_mode)); + }
I'm not sure we need to have riscv-aia=auto on the command line. Isn't that the default? In fact, I'm not convinced we need it in the enum either. Is there a situation in which the user can request the riscv-aia feature to be on but QEMU will not be able to comply with that? Is there a way to make the device *not* appear? I'm also wondering how the riscv-aia KVM feature you're introducing will interact with the existing aia feature. The latter is documented somewhat extensively in https://gitlab.com/qemu-project/qemu/-/blob/master/docs/specs/riscv-aia.rst but AFAICT there barely is any documentation at all for the former at the QEMU level. Maybe Daniel (CC'd), who introduced the other feature into libvirt, knows more. Finally, I would expect more validation to be performed. For example, that the QEMU binary supports the necessary option and that this KVM-only feature is not being used for a TCG domain. Admittedly the latter issue is pre-existing. -- Andrea Bolognani / Red Hat / Virtualization
On 10/27/25 4:49 PM, Andrea Bolognani wrote:
On Thu, Sep 18, 2025 at 01:44:05PM +0800, BillXiang wrote:
+++ b/docs/formatdomain.rst @@ -2206,6 +2207,12 @@ are: poll-control Decrease IO completion latency by introducing a grace period of busy waiting on, off :since:`6.10.0 (QEMU 4.2)` pv-ipi Paravirtualized send IPIs on, off :since:`7.10.0 (QEMU 3.1)` dirty-ring Enable dirty ring feature on, off; size - must be power of 2, range [1024,65536] :since:`8.0.0 (QEMU 6.1)` + riscv-aia Set riscv KVM AIA mode. Defaults to 'auto'. on, off; mode - must be emul, hwaccel or auto :since:`11.8.0 (QEMU 8.2)` + The "riscv-aia" parameter is passed along with --accel in QEMU command-line. + 1) "riscv-aia=emul": IMSIC is emulated by hypervisor + 2) "riscv-aia=hwaccel": use hardware guest IMSIC + 3) "riscv-aia=auto": use the hardware guest IMSICs whenever available + otherwise we fallback to software emulation.
This doesn't build:
[377/617] Generating 'docs/formatdomain.html.p/formatdomain.html.in' (wrapped by meson to capture output) FAILED: [code=1] docs/formatdomain.html.p/formatdomain.html.in /usr/bin/meson --internal exe --capture docs/formatdomain.html.p/formatdomain.html.in -- /sbin/rst2html5 --exit-status=1 --stylesheet= --strict ../docs/formatdomain.rst --- stderr --- ../docs/formatdomain.rst:2224: (ERROR/3) Unexpected indentation. Exiting due to level-3 (ERROR) system message.
Please make sure that libvirt builds *and* the test suite passes after each patch of your series.
This bit of documentation appears to have been lifted verbatim from
https://gitlab.com/qemu-project/qemu/-/commit/9634ef7eda5f5b57f03924351a213b...
Please rewrite it so that it's less redundant (no need to repeat the name of the feature so many times) and only information that is relevant to libvirt users is included (mentioning QEMU's --accel option is not useful).
As a last note, this missed the 11.8.0 release and will not make it into the upcoming 11.9.0 release either, so the :since: information will need to be updated to reflect reality.
+++ b/src/conf/schemas/domaincommon.rng @@ -8207,6 +8207,16 @@ </optional> </element> </optional> + <optional> + <element name="riscv-aia"> + <ref name="featurestate"/> + <attribute name="mode"> + <data type="string"> + <param name="pattern">(auto|emul|hwaccel)</param> + </data> + </attribute>
I believe this could be
<attribute name="mode"> <choice> <value>auto</value> <value>emul</value> <value>hwaccel</value> </choice> </attribute>
+++ b/src/qemu/qemu_command.c @@ -6720,6 +6720,9 @@ qemuBuildCpuCommandLine(virCommand *cmd,
case VIR_DOMAIN_KVM_DIRTY_RING: break; + + case VIR_DOMAIN_KVM_RISCV_AIA: + break;
There's some spurious whitespace in this hunk. Please get rid of it.
@@ -7355,9 +7358,13 @@ qemuBuildAccelCommandLine(virCommand *cmd, * not that either kvm or tcg can be specified by libvirt * so do not worry about the conflict of specifying both * */ - if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON && - def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) { - virBufferAsprintf(&buf, ",dirty-ring-size=%d", def->kvm_features->dirty_ring_size); + if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) { + if (def->kvm_features->features[VIR_DOMAIN_KVM_DIRTY_RING] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(&buf, ",dirty-ring-size=%d", def->kvm_features->dirty_ring_size); + } + if (def->kvm_features->features[VIR_DOMAIN_KVM_RISCV_AIA] == VIR_TRISTATE_SWITCH_ON) { + virBufferAsprintf(&buf, ",riscv-aia=%s", virDomainKVMRiscvAIAModeTypeToString(def->kvm_features->kvm_riscv_aia_mode)); + }
I'm not sure we need to have riscv-aia=auto on the command line. Isn't that the default? In fact, I'm not convinced we need it in the enum either.
Is there a situation in which the user can request the riscv-aia feature to be on but QEMU will not be able to comply with that? Is there a way to make the device *not* appear?
I'm also wondering how the riscv-aia KVM feature you're introducing will interact with the existing aia feature. The latter is documented somewhat extensively in
https://gitlab.com/qemu-project/qemu/-/blob/master/docs/specs/riscv-aia.rst
but AFAICT there barely is any documentation at all for the former at the QEMU level. Maybe Daniel (CC'd), who introduced the other feature into libvirt, knows more.
Having a 'riscv-aia' KVM accel prop and an 'aia' board property is confusing indeed ... What we added in libvirt is the 'virt' board AIA support (aplic and aplic-imsic). It interacts with the current accelerator capabilities (kvm, tcg) like the QEMU doc above describes. The 'riscv-aia' accelerator property attempts to configure the capabilities of the in-kernel KVM AIA chip, if present. I'll just copy/paste the commit msg that introduced it in QEMU: ------------ target/riscv: Create an KVM AIA irqchip We create a vAIA chip by using the KVM_DEV_TYPE_RISCV_AIA and then set up the chip with the KVM_DEV_RISCV_AIA_GRP_* APIs. We also extend KVM accelerator to specify the KVM AIA mode. The "riscv-aia" parameter is passed along with --accel in QEMU command-line. 1) "riscv-aia=emul": IMSIC is emulated by hypervisor 2) "riscv-aia=hwaccel": use hardware guest IMSIC 3) "riscv-aia=auto": use the hardware guest IMSICs whenever available otherwise we fallback to software emulation. ------------ Note that these are properties implemented by the KVM module, not QEMU, e.g. they depend on host KVM support. They interact with the table in that doc in the IMSIC s-mode column, in the "in-kernel" category: accel | accel properties | IMSIC s-mode kvm | none | in-kernel, riscv-aia = auto kvm | riscv-aia=auto | in-kernel, riscv-aia = auto kvm | riscv-aia=hwaccel | in-kernel, use the IMSIC controller from the guest HW kvm | riscv-aia=emul | in-kernel, KVM will emulate the IMSIC controller As far as libvirt goes I wouldn't add 'auto' support. Not only it is already the QEMU default value but it also means "give me either hwaccel or emul". Might as well just leave the option alone then. Hope this helps. I'll send a patch adding the riscv-aia info to the QEMU docs. Thanks, Daniel
Finally, I would expect more validation to be performed. For example, that the QEMU binary supports the necessary option and that this KVM-only feature is not being used for a TCG domain. Admittedly the latter issue is pre-existing.
On Mon, Oct 27, 2025 at 06:23:55PM -0300, Daniel Henrique Barboza wrote:
On 10/27/25 4:49 PM, Andrea Bolognani wrote:
I'm also wondering how the riscv-aia KVM feature you're introducing will interact with the existing aia feature. The latter is documented somewhat extensively in
https://gitlab.com/qemu-project/qemu/-/blob/master/docs/specs/riscv-aia.rst
but AFAICT there barely is any documentation at all for the former at the QEMU level. Maybe Daniel (CC'd), who introduced the other feature into libvirt, knows more.
Having a 'riscv-aia' KVM accel prop and an 'aia' board property is confusing indeed ...
What we added in libvirt is the 'virt' board AIA support (aplic and aplic-imsic). It interacts with the current accelerator capabilities (kvm, tcg) like the QEMU doc above describes.
The 'riscv-aia' accelerator property attempts to configure the capabilities of the in-kernel KVM AIA chip, if present.
[...]
Note that these are properties implemented by the KVM module, not QEMU, e.g. they depend on host KVM support.
[...]
As far as libvirt goes I wouldn't add 'auto' support. Not only it is already the QEMU default value but it also means "give me either hwaccel or emul". Might as well just leave the option alone then.
I am also under the impression that modeling that value explicitly is probably not useful.
Hope this helps. I'll send a patch adding the riscv-aia info to the QEMU docs.
Thanks. Having better documentation on the QEMU side will not only guide our decisions on the libvirt side, but obviously also benefit people who run QEMU directly. If you have any opinion on what the libvirt interface should look like, please do share. You clearly understand the problem space much better than I do :) -- Andrea Bolognani / Red Hat / Virtualization
On 10/27/25 7:34 PM, Andrea Bolognani wrote:
On Mon, Oct 27, 2025 at 06:23:55PM -0300, Daniel Henrique Barboza wrote:
On 10/27/25 4:49 PM, Andrea Bolognani wrote:
I'm also wondering how the riscv-aia KVM feature you're introducing will interact with the existing aia feature. The latter is documented somewhat extensively in
https://gitlab.com/qemu-project/qemu/-/blob/master/docs/specs/riscv-aia.rst
but AFAICT there barely is any documentation at all for the former at the QEMU level. Maybe Daniel (CC'd), who introduced the other feature into libvirt, knows more.
Having a 'riscv-aia' KVM accel prop and an 'aia' board property is confusing indeed ...
What we added in libvirt is the 'virt' board AIA support (aplic and aplic-imsic). It interacts with the current accelerator capabilities (kvm, tcg) like the QEMU doc above describes.
The 'riscv-aia' accelerator property attempts to configure the capabilities of the in-kernel KVM AIA chip, if present.
[...]
Note that these are properties implemented by the KVM module, not QEMU, e.g. they depend on host KVM support.
[...]
As far as libvirt goes I wouldn't add 'auto' support. Not only it is already the QEMU default value but it also means "give me either hwaccel or emul". Might as well just leave the option alone then.
I am also under the impression that modeling that value explicitly is probably not useful.
Hope this helps. I'll send a patch adding the riscv-aia info to the QEMU docs.
Thanks. Having better documentation on the QEMU side will not only guide our decisions on the libvirt side, but obviously also benefit people who run QEMU directly.
All true. Btw just posted it in the QEMU ML.
If you have any opinion on what the libvirt interface should look like, please do share. You clearly understand the problem space much better than I do :)
As far as this series goes, aside from my comment w.r.t the 'auto' setting I think these patches are on the right direction. 'riscv-aia' should be handled like any other accel property that libvirt already supports (e.g. dirty-ring-size). With proper documentation stating that riscv-aia is a RISC-V only property, of course. As libvirt + risc-v in general I'm happy with how libvirt is faring. libvirt is way ahead of the curve w.r.t features (device plug/unplug, migration management, device assignment, etc) in comparison with what the current risc-v ecosystem. The caveat is extension management, a.k.a how do we disable extensions in libvirt. QEMU supports 142 extensions at this moment. The right thing to do would be to add each single one of them in libvirt (we can't just create a XML element that receives any user input as "extensions to be disabled" and roll with it). But the more I think about it the more I believe that we shouldn't add any generic extension disable support in libvirt ... disabling extensions is a debug feature more than anything, an advanced feature that most users will misuse and then nag about their stuff not working. If there's real RISC-V HW that needs extensions to be disabled to work properly, then so be it - add support to disable the required extensions only. Do it on demand. Thanks, Daniel
On Tue, Oct 28, 2025 at 08:11:02AM -0300, Daniel Henrique Barboza wrote:
On 10/27/25 7:34 PM, Andrea Bolognani wrote:
On Mon, Oct 27, 2025 at 06:23:55PM -0300, Daniel Henrique Barboza wrote:
Hope this helps. I'll send a patch adding the riscv-aia info to the QEMU docs.
Thanks. Having better documentation on the QEMU side will not only guide our decisions on the libvirt side, but obviously also benefit people who run QEMU directly.
All true. Btw just posted it in the QEMU ML.
https://mail.gnu.org/archive/html/qemu-devel/2025-10/msg07285.html
If you have any opinion on what the libvirt interface should look like, please do share. You clearly understand the problem space much better than I do :)
As far as this series goes, aside from my comment w.r.t the 'auto' setting I think these patches are on the right direction. 'riscv-aia' should be handled like any other accel property that libvirt already supports (e.g. dirty-ring-size). With proper documentation stating that riscv-aia is a RISC-V only property, of course.
The QEMU documentation is making my head spin - so many different acronyms and the number of possible combinations is just staggering. If I understand things correctly, the riscv-aia accel property is only really relevant in combination with the aia=aplic-imsic machine type property. So we should probably validate that it's not used without it. Other than that, and the comments that I had made previously, I agree that overall the patch looks reasonable.
As libvirt + risc-v in general I'm happy with how libvirt is faring. libvirt is way ahead of the curve w.r.t features (device plug/unplug, migration management, device assignment, etc) in comparison with what the current risc-v ecosystem.
The caveat is extension management, a.k.a how do we disable extensions in libvirt. QEMU supports 142 extensions at this moment. The right thing to do would be to add each single one of them in libvirt (we can't just create a XML element that receives any user input as "extensions to be disabled" and roll with it). But the more I think about it the more I believe that we shouldn't add any generic extension disable support in libvirt ... disabling extensions is a debug feature more than anything, an advanced feature that most users will misuse and then nag about their stuff not working. If there's real RISC-V HW that needs extensions to be disabled to work properly, then so be it - add support to disable the required extensions only. Do it on demand.
That's a different topic. For another day ;) -- Andrea Bolognani / Red Hat / Virtualization
On Thu, Sep 18, 2025 at 13:44:05 +0800, BillXiang wrote:
From: xiangwencheng <xiangwencheng@lanxincomputing.com>
riscv-aia feature was introduced in qemu-8.2 to specify the KVM AIA mode. The "riscv-aia" parameter is passed along with -accel in QEMU command-line. 1) "riscv-aia=emul": IMSIC is emulated by hypervisor 2) "riscv-aia=hwaccel": use hardware guest IMSIC 3) "riscv-aia=auto": use the hardware guest IMSICs whenever available otherwise we fallback to software emulation.
This patch add the corresponding feature named 'riscv-aia'.
Signed-off-by: BillXiang <xiangwencheng@lanxincomputing.com> --- v3[1] -> v4: - Add XML tests. - Fix broken indentations. - Remove optional mark of 'mode' in XML schema. [1] https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/CGZIW... --- docs/formatdomain.rst | 7 +++++++ src/conf/domain_conf.c | 28 +++++++++++++++++++++++++++- src/conf/domain_conf.h | 11 +++++++++++ src/conf/schemas/domaincommon.rng | 10 ++++++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_command.c | 13 ++++++++++--- 6 files changed, 67 insertions(+), 4 deletions(-)
The patches look good to me code wise. Andrea (cc'd) can you have a look if it makes sense to you?
participants (4)
-
Andrea Bolognani -
BillXiang -
Daniel Henrique Barboza -
Peter Krempa