On Fri, Aug 22, 2025 at 17:53:28 +0800, BillXiang wrote:
> From: xiangwencheng <xiangwench...@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 <xiangwench...@lanxincomputing.com>
> ---
> v1[1] -> v2:
>  - Separate changes to NEWS.rst into a separate commit.
>  - Remove changes to qemuxmlconfdata files that are used by x86.
>  - Store riscv-aia mode as enum.
>  - Remove VIR_DOMAIN_KVM_RISCV_AIA from virDomainDefFeaturesCheckABIStability
>    beacuse it doesn't support migration currently.
> 
> [1] 
> https://lists.libvirt.org/archives/list/devel@lists.libvirt.org/thread/XBDTP6C5T2RIVHGEI3X7WTDMHSXZMGKL
> ---
>  docs/formatdomain.rst             |  2 ++
>  src/conf/domain_conf.c            | 33 ++++++++++++++++++++++++++++++-
>  src/conf/domain_conf.h            | 10 ++++++++++
>  src/conf/schemas/domaincommon.rng | 12 +++++++++++
>  src/libvirt_private.syms          |  2 ++
>  src/qemu/qemu_command.c           | 13 +++++++++---
>  6 files changed, 68 insertions(+), 4 deletions(-)

Fails to compile:

In file included from ../../../libvirt/src/util/virxml.h:31,
                 from ../../../libvirt/src/conf/cpu_conf.h:24,
                 from ../../../libvirt/src/conf/capabilities.h:26,
                 from ../../../libvirt/src/conf/domain_conf.h:31,
                 from ../../../libvirt/src/conf/checkpoint_conf.h:26,
                 from ../../../libvirt/src/conf/domain_conf.c:32:
../../../libvirt/src/conf/domain_conf.c:230:15: error: no previous prototype 
for ‘virDomainKVMRiscvAIAModeTypeToString’ [-Werror=missing-prototypes]
  230 | VIR_ENUM_IMPL(virDomainKVMRiscvAIAMode,
      |               ^~~~~~~~~~~~~~~~~~~~~~~~
../../../libvirt/src/util/virenum.h:35:17: note: in definition of macro 
‘VIR_ENUM_IMPL’
   35 |     const char *name ## TypeToString(int type) { \
      |                 ^~~~
../../../libvirt/src/conf/domain_conf.c:230:15: error: no previous prototype 
for ‘virDomainKVMRiscvAIAModeTypeFromString’ [-Werror=missing-prototypes]
  230 | VIR_ENUM_IMPL(virDomainKVMRiscvAIAMode,
      |               ^~~~~~~~~~~~~~~~~~~~~~~~
../../../libvirt/src/util/virenum.h:40:9: note: in definition of macro 
‘VIR_ENUM_IMPL’
   40 |     int name ## TypeFromString(const char *type) { \
      |         ^~~~
../../../libvirt/src/conf/domain_conf.c: In function 
‘virDomainDefFeaturesCheckABIStability’:
../../../libvirt/src/conf/domain_conf.c:21712:13: error: enumeration value 
‘VIR_DOMAIN_KVM_RISCV_AIA’ not handled in switch [-Werror=switch]
21712 |             switch ((virDomainKVM) i) {
      |             ^~~~~~
cc1: all warnings being treated as errors
ninja: build stopped: subcommand failed.

Looks like you're missing some VIR_ENUM_DECL()

Couple more points inline. I'll re-arrange some hunks for clarity.


> 
> diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
> index 9f7311b6d5..2ccbb1bfb9 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,7 @@ 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 - optional string emul, hwaccel or auto  
> :since:`11.7.0 (QEMU 8.2)`
>     ============== 
> ============================================================================ 
> ====================================================== 
> ============================
>  
>  ``xen``

Stating that default is auto ...


> @@ -17142,6 +17150,7 @@ virDomainFeaturesKVMDefParse(virDomainDef *def,
>  {
>      g_autoptr(GPtrArray) feats = virXMLNodeGetSubelementList(node, NULL);
>      size_t i;
> +    g_autofree char *ptval = NULL;

Unused variable. Compiler will catch this.

>  
>      if (!def->kvm_features)
>          def->kvm_features = g_new0(virDomainFeatureKVM, 1);

The enum is defined as:

> +typedef enum {
> +    VIR_DOMAIN_KVM_TISCV_AIA_MODE_EMUL = 0,
> +    VIR_DOMAIN_KVM_TISCV_AIA_MODE_HWACCEL,
> +    VIR_DOMAIN_KVM_TISCV_AIA_MODE_AUTO,
> +
> +    VIR_DOMAIN_KVM_TISCV_AIA_MODE_LAST
> +} virDomainKVMRiscvAIAMode;
> +



> @@ -17183,6 +17192,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_NONZERO,

Here you:
1) allow the "mode" property to be missing, in which case the value will
be kept '0' thus VIR_DOMAIN_KVM_TISCV_AIA_MODE_EMUL
2) you explicitly refuse VIR_DOMAIN_KVM_TISCV_AIA_MODE_EMUL case when
xml contains 'mode="emul"'

> +                            &def->kvm_features->kvm_riscv_aia_mode) < 0)
> +                return -1;
> +        }
>      }
>  
>      def->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
> @@ -28752,7 +28770,20 @@ 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->kvm_riscv_aia_mode >= 0 &&


Here you accept 0

> +                            def->kvm_features->kvm_riscv_aia_mode < 
> VIR_DOMAIN_KVM_TISCV_AIA_MODE_LAST) {

This shouldn't be needed.

> +                            virBufferAsprintf(&childBuf, " mode='%s'/>\n",
> +                                               
> virDomainKVMRiscvAIAModeTypeToString(def->kvm_features->kvm_riscv_aia_mode));
> +                        } else {
> +                            virBufferAddLit(&childBuf, "/>\n");
> +                        }
> +                    }
> +                    break;
>                  case VIR_DOMAIN_KVM_LAST:
>                      break;
>                  }
>  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/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));
> +            }

This still doesn't handle the situation where the setting is missing
from the XML correctly.

If qemu requires a mode, make it mandatory, do not declare deafults in
libvirt.


>          }
>          break;
>  
> -- 
> 2.34.1
> 

Reply via email to