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>
---
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/CGZIWV7GHPGSAFARWKXQ6YBBXHXWS6TW/
---
 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

Reply via email to