On 2025/8/25 15:58, Peter Krempa wrote:
> On Thu, Aug 21, 2025 at 18:36:44 +0800, Bill Xiang wrote:
>>> From: "Peter Krempa"<[email protected]>
>>> Date: Wed, Aug 20, 2025, 16:08
>>> Subject: Re: [PATCH] qemu: support riscv-aia feature for RISC-V KVM
>>> To: "BillXiang"<[email protected]>
>>> Cc: <[email protected]>
>>> On Fri, Aug 15, 2025 at 19:44:15 +0800, BillXiang wrote:
>>>> 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 <[email protected]>
>>>> ---
>>>
>>> Note that in this review I'll note some common mistakes from this patch.
>>> I don't know what this feature is about so I'll not comment on that
>>>
>>
>> Hi Peter,
>> Thank you for your review. I've a few points I'd like to clarify,
>> could you please provide a bit more detail?
>>
>>>
>>>> NEWS.rst | 10 ++++++++
>>>
>>> We mandate that changes to NEWS.rst are always separated into a separate
>>> commit with no other changes. This is to avoid conflicts both when
>>> applying the code (which is the case with this patch which can't be
>>> applied due to a conflict in the news) and also for backports.
>>>
>>
>> I'll separate it into a separate patch.
>>
>>>> docs/formatdomain.rst | 2 ++
>>>> src/conf/domain_conf.c | 29 ++++++++++++++++++++++
>>>> src/conf/domain_conf.h | 2 ++
>>>> src/conf/schemas/domaincommon.rng | 12 +++++++++
>>>> src/qemu/qemu_command.c | 13 +++++++---
>>>> tests/qemuxmlconfdata/kvm-features-off.xml | 1 +
>>>> tests/qemuxmlconfdata/kvm-features.xml | 1 +
>>>
>>> You've modified test input files but apparently didn't run the test
>>> suite, because it now fails:
>>>
>>> Summary of Failures:
>>>
>>> 302/312 libvirt:syntax-check / trailing_blank
>>> FAIL 0.50s exit status 2
>>> 311/312 libvirt:bin / qemuxmlconftest
>>> FAIL 4.11s exit status 1
>>>
>>> See https://libvirt.org/advanced-tests.html namely
>>> VIR_TEST_REGENERATE_OUTPUT to avoid needing to do it manually.
>>>
>>
>> I've run the test suite but get lots of TIMEOUT. I'll try again.
>
> Weird. The testsuite works okay for me, also it works okay in the
> upstream CI.
>
> Let us know if you encounter any problems, but don't forget to mention
> the exact steps and setup needed to reproduce the issue (same way as
> when reporting a bug).
>
>>
>>>
>>>> 8 files changed, 67 insertions(+), 3 deletions(-)
>>>>
>
> [...]
>
>>>> @@ -21697,6 +21712,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'"),
>>>
>>>
>>> Is the 'mode' guest visible? I'd expect that it's checked here too if it
>>> is guest visible.
>>>
>>
>> The check here is for VM migration. But AFAIK,the RISC-V 'riscv_aia'
>> feature requires the 'aia' feature being set to 'aplic-imsic',
>> which currently lacks support for migration or snapshotting.
>
> It doesn't really matter that it's currently unsupported. Support can be
> added later in qemu. If it is a guest visible feature it must be handled
> in the ABI stability check. If the setting doesn't influence anything
> guest visible then it is okay.
>
> I noted this here because the feature has an additional setting and you
> didn't handle it here. If it is not guest visible you'll need to node in
> a comment stating that this particular config is not guest visible for
> anyone coming after you wanting to understand why it works this way.
>
Perhaps I’ve misinterpreted 'guest visible'. The mode is visible to
QEMU itself as described in the commit, not to the guest kernel.
>>
>>>> @@ -28752,6 +28768,19 @@ 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]));
>>>> + if (def->kvm_features->riscv_aia_mode != NULL) {
>>>> + virBufferAsprintf(&childBuf, " mode='%s'/>\n",
>>>> +
>>>> def->kvm_features->riscv_aia_mode);
>>>> + } else {
>>>> + virBufferAddLit(&childBuf, "/>\n");
>>>> + }
>>>> + }
>>>> + break;
>>>>
>>>> case VIR_DOMAIN_KVM_LAST:
>>>> break;
>>>> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
>>>> index eca820892e..0d749c0f3c 100644
>>>> --- a/src/conf/domain_conf.h
>>>> +++ b/src/conf/domain_conf.h
>>>> @@ -2270,6 +2270,7 @@ 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;
>>>> @@ -2476,6 +2477,7 @@ struct _virDomainFeatureKVM {
>>>> int features[VIR_DOMAIN_KVM_LAST];
>>>>
>>>> unsigned int dirty_ring_size; /* size of dirty ring for each vCPU,
>>>> no units */
>>>> + char *riscv_aia_mode;
>>>> };
>>>>
>>>> typedef struct _virDomainFeatureTCG virDomainFeatureTCG;
>>>> diff --git a/src/conf/schemas/domaincommon.rng
>>>> b/src/conf/schemas/domaincommon.rng
>>>> index e369fb6e81..3de5807b1e 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">(emul|hwaccel|auto)</param>
>>>> + </data>
>>>> + </attribute>
>>>> + </optional>
>>>> + </element>
>>>> + </optional>
>>>> </interleave>
>>>> </element>
>>>> </define>
>>>> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
>>>> index e8de386f30..6db283ef29 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",
>>>> def->kvm_features->riscv_aia_mode);
>>>
>>> The mode is declared as optional, here you use it unconditionally.
>>>
>>
>> I've mirrored the implementation of VIR_DOMAIN_KVM_DIRTY_RING and checked
>> VIR_DOMAIN_KVM_RISCV_AIA with VIR_TRISTATE_SWITCH_ON.
>> Could you let me know what additional condition I should introduce?
>
> I was pointing out the discrepancy between the docs + RNG schema, which
> declared it as optional and the code in the parser, which didn't handle
> the possibilty that it's missing (passed it to strcmp, which would
> crash) and the formatter, which didn't handle it being NULL and would
> pass NULL to the formatter (this wouldn't crash, but would create
> invalid config).
>
> As noted I'm not really interested in the feature so I don't know if
> mirroring existing code makes sense. I merely pointed out that the
> implementation as documented was wrong.
>