[PATCH v3 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> --- src/conf/domain_conf.c | 28 +++++++++++++++++++++++++++- src/conf/domain_conf.h | 11 +++++++++++ src/conf/schemas/domaincommon.rng | 12 ++++++++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_command.c | 13 ++++++++++--- 5 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7766e302ec..a9f1161133 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_TISCV_AIA_MODE_LAST, + "auto", + "emul", + "hwaccel", ); VIR_ENUM_IMPL(virDomainXen, @@ -17183,6 +17191,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; @@ -21697,6 +21714,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'"), @@ -28752,7 +28770,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 eca820892e..0250b3db49 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2270,10 +2270,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_TISCV_AIA_MODE_AUTO = 0, + VIR_DOMAIN_KVM_TISCV_AIA_MODE_EMUL, + VIR_DOMAIN_KVM_TISCV_AIA_MODE_HWACCEL, + + VIR_DOMAIN_KVM_TISCV_AIA_MODE_LAST +} virDomainKVMRiscvAIAMode; +VIR_ENUM_DECL(virDomainKVMRiscvAIAMode); + typedef enum { VIR_DOMAIN_MSRS_UNKNOWN = 0, @@ -2476,6 +2486,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 e369fb6e81..02771a6b7b 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -8192,6 +8192,18 @@ </optional> </element> </optional> + <optional> + <element name="riscv-aia"> + <ref name="featurestate"/> + <optional> + <attribute name="mode"> + <data type="string"> + <param name="pattern">(auto|emul|hwaccel)</param> + </data> + </attribute> + </optional> + </element> + </optional> </interleave> </element> </define> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b846011f0f..f540bdbd5b 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 e8de386f30..9f34b5a37d 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6679,6 +6679,9 @@ qemuBuildCpuCommandLine(virCommand *cmd, case VIR_DOMAIN_KVM_DIRTY_RING: break; + + case VIR_DOMAIN_KVM_RISCV_AIA: + break; case VIR_DOMAIN_KVM_LAST: break; @@ -7314,9 +7317,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
participants (1)
-
BillXiang