[PATCH v1 4/7] qemu: Implement the SBBC pSeries feature

Daniel Henrique Barboza danielhb413 at gmail.com
Thu Apr 16 21:25:01 UTC 2020


This patch adds the implementation of the SBBC pSeries feature,
using the QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC capability added
in the previous patch.

Like the previously added CPFC feature, SBBC can have the values
"broken", "workaround" or "fixed". Extra code is required to handle
it since it's not a regular tristate capability.

This is the XML format for the cap:

<features>
  <sbbc value='workaround'/>
</features>

Signed-off-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
---
 docs/formatdomain.html.in                     | 11 +++++
 docs/schemas/domaincommon.rng                 | 15 +++++++
 src/conf/domain_conf.c                        | 43 +++++++++++++++++++
 src/conf/domain_conf.h                        | 12 ++++++
 src/libvirt_private.syms                      |  1 +
 src/qemu/qemu_command.c                       |  5 +++
 src/qemu/qemu_validate.c                      | 11 +++++
 tests/qemuxml2argvdata/pseries-features.args  |  2 +-
 tests/qemuxml2argvdata/pseries-features.xml   |  1 +
 tests/qemuxml2argvtest.c                      | 21 ++++++++-
 tests/qemuxml2xmloutdata/pseries-features.xml |  1 +
 tests/qemuxml2xmltest.c                       |  3 +-
 12 files changed, 122 insertions(+), 4 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 607e815413..2146374475 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2075,6 +2075,7 @@
   <ccf-assist state='on'/>
   <msrs unknown='ignore'/>
   <cfpc value='workaround'/>
+  <sbbc value='workaround'/>
 </features>
 ...</pre>
 
@@ -2390,6 +2391,16 @@
           default will be used.
           <span class="since">Since 6.3.0</span> (QEMU/KVM only)
       </dd>
+      <dt><code>sbbc</code></dt>
+      <dd>Configure sbbc (Speculation Barrier Bounds Checking) availability for
+          pSeries guests.
+          Possible values for the <code>value</code> attribute
+          are <code>broken</code> (no protection), <code>workaround</code>
+          (software workaround available) and <code>fixed</code> (fixed in
+          hardware). If the attribute is not defined, the hypervisor
+          default will be used.
+          <span class="since">Since 6.3.0</span> (QEMU/KVM only)
+      </dd>
     </dl>
 
     <h3><a id="elementsTime">Time keeping</a></h3>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 40785752f7..72c281aa8f 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -5433,6 +5433,9 @@
           <optional>
             <ref name="cfpc"/>
           </optional>
+          <optional>
+            <ref name="sbbc"/>
+          </optional>
         </interleave>
       </element>
     </optional>
@@ -5704,6 +5707,18 @@
     </element>
   </define>
 
+  <define name="sbbc">
+    <element name="sbbc">
+      <attribute name="value">
+        <choice>
+          <value>broken</value>
+          <value>workaround</value>
+          <value>fixed</value>
+        </choice>
+      </attribute>
+    </element>
+  </define>
+
   <define name="address">
     <element name="address">
       <choice>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4bfb17b7c8..5373b29263 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -174,6 +174,7 @@ VIR_ENUM_IMPL(virDomainFeature,
               "msrs",
               "ccf-assist",
               "cfpc",
+              "sbbc",
 );
 
 VIR_ENUM_IMPL(virDomainCapabilitiesPolicy,
@@ -1260,6 +1261,14 @@ VIR_ENUM_IMPL(virDomainCFPC,
               "fixed",
 );
 
+VIR_ENUM_IMPL(virDomainSBBC,
+              VIR_DOMAIN_SBBC_LAST,
+              "none",
+              "broken",
+              "workaround",
+              "fixed",
+);
+
 /* Internal mapping: subset of block job types that can be present in
  * <mirror> XML (remaining types are not two-phase). */
 VIR_ENUM_DECL(virDomainBlockJob);
@@ -20985,6 +20994,20 @@ virDomainDefParseXML(xmlDocPtr xml,
             }
             break;
 
+        case VIR_DOMAIN_FEATURE_SBBC:
+            tmp = virXMLPropString(nodes[i], "value");
+            if (tmp) {
+                int value = virDomainSBBCTypeFromString(tmp);
+                if (value < 0 || value == VIR_DOMAIN_SBBC_NONE) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("Unknown value: %s"),
+                                   tmp);
+                    goto error;
+                }
+                def->features[val] = value;
+                VIR_FREE(tmp);
+            }
+            break;
 
         case VIR_DOMAIN_FEATURE_HTM:
         case VIR_DOMAIN_FEATURE_NESTED_HV:
@@ -23303,6 +23326,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
             }
             break;
 
+        case VIR_DOMAIN_FEATURE_SBBC:
+            if (src->features[i] != dst->features[i]) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("State of feature '%s' differs: "
+                                 "source: '%s=%s', destination: '%s=%s'"),
+                               featureName,
+                               "value", virDomainSBBCTypeToString(src->features[i]),
+                               "value", virDomainSBBCTypeToString(dst->features[i]));
+                return false;
+            }
+            break;
+
         case VIR_DOMAIN_FEATURE_MSRS:
             break;
 
@@ -29069,6 +29104,14 @@ virDomainDefFormatFeatures(virBufferPtr buf,
                               virDomainCFPCTypeToString(def->features[i]));
             break;
 
+        case VIR_DOMAIN_FEATURE_SBBC:
+            if (def->features[i] == VIR_DOMAIN_SBBC_NONE)
+                break;
+
+            virBufferAsprintf(&childBuf, "<sbbc value='%s'/>\n",
+                              virDomainSBBCTypeToString(def->features[i]));
+            break;
+
         /* coverity[dead_error_begin] */
         case VIR_DOMAIN_FEATURE_LAST:
             break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a59e3cd41a..c04441e587 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1815,6 +1815,7 @@ typedef enum {
     VIR_DOMAIN_FEATURE_MSRS,
     VIR_DOMAIN_FEATURE_CCF_ASSIST,
     VIR_DOMAIN_FEATURE_CFPC,
+    VIR_DOMAIN_FEATURE_SBBC,
 
     VIR_DOMAIN_FEATURE_LAST
 } virDomainFeature;
@@ -1982,6 +1983,17 @@ typedef enum {
 
 VIR_ENUM_DECL(virDomainCFPC);
 
+typedef enum {
+    VIR_DOMAIN_SBBC_NONE = 0,
+    VIR_DOMAIN_SBBC_BROKEN,
+    VIR_DOMAIN_SBBC_WORKAROUND,
+    VIR_DOMAIN_SBBC_FIXED,
+
+    VIR_DOMAIN_SBBC_LAST
+} virDomainSBBC;
+
+VIR_ENUM_DECL(virDomainSBBC);
+
 /* Operating system configuration data & machine / arch */
 struct _virDomainOSEnv {
     char *name;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index df48176e6a..99e74eee84 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -582,6 +582,7 @@ virDomainRNGModelTypeToString;
 virDomainRNGRemove;
 virDomainRunningReasonTypeFromString;
 virDomainRunningReasonTypeToString;
+virDomainSBBCTypeToString;
 virDomainSCSIDriveAddressIsUsed;
 virDomainSeclabelTypeFromString;
 virDomainSeclabelTypeToString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 302cee79ad..0c3b37760a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7168,6 +7168,11 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
         virBufferAsprintf(&buf, ",cap-cfpc=%s", str);
     }
 
+    if (def->features[VIR_DOMAIN_FEATURE_SBBC] != VIR_DOMAIN_SBBC_NONE) {
+        const char *str = virDomainSBBCTypeToString(def->features[VIR_DOMAIN_FEATURE_SBBC]);
+        virBufferAsprintf(&buf, ",cap-sbbc=%s", str);
+    }
+
     if (cpu && cpu->model &&
         cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
         qemuDomainIsPSeries(def) &&
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 11d310ed8f..f75cec93c2 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -146,6 +146,16 @@ qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
             return -1;
         }
 
+        break;
+
+    case VIR_DOMAIN_FEATURE_SBBC:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("sbbc configuration is not supported by "
+                             "this QEMU binary"));
+            return -1;
+        }
+
         break;
     }
 
@@ -205,6 +215,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
         case VIR_DOMAIN_FEATURE_NESTED_HV:
         case VIR_DOMAIN_FEATURE_CCF_ASSIST:
         case VIR_DOMAIN_FEATURE_CFPC:
+        case VIR_DOMAIN_FEATURE_SBBC:
             if (qemuValidateDomainDefPSeriesFeature(def, qemuCaps, i) < 0)
                 return -1;
             break;
diff --git a/tests/qemuxml2argvdata/pseries-features.args b/tests/qemuxml2argvdata/pseries-features.args
index 8540252c17..9a64df7593 100644
--- a/tests/qemuxml2argvdata/pseries-features.args
+++ b/tests/qemuxml2argvdata/pseries-features.args
@@ -12,7 +12,7 @@ QEMU_AUDIO_DRV=none \
 -S \
 -machine pseries,accel=tcg,usb=off,dump-guest-core=off,resize-hpt=required,\
 cap-hpt-max-page-size=1048576k,cap-htm=on,cap-nested-hv=off,cap-ccf-assist=on,\
-cap-cfpc=fixed \
+cap-cfpc=fixed,cap-sbbc=broken \
 -m 512 \
 -realtime mlock=off \
 -smp 1,sockets=1,cores=1,threads=1 \
diff --git a/tests/qemuxml2argvdata/pseries-features.xml b/tests/qemuxml2argvdata/pseries-features.xml
index f07a204cb7..ef431b0067 100644
--- a/tests/qemuxml2argvdata/pseries-features.xml
+++ b/tests/qemuxml2argvdata/pseries-features.xml
@@ -14,6 +14,7 @@
     <nested-hv state='off'/>
     <ccf-assist state='on'/>
     <cfpc value='fixed'/>
+    <sbbc value='broken'/>
   </features>
   <devices>
     <emulator>/usr/bin/qemu-system-ppc64</emulator>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 8cb53b2416..0b4dc0dec5 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1964,6 +1964,7 @@ mymain(void)
             QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
             QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
             QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
+            QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC,
             QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
 
     /* parse error: no QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT */
@@ -1973,7 +1974,8 @@ mymain(void)
                         QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
-                        QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC);
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC);
 
     /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE */
     DO_TEST_PARSE_ERROR("pseries-features",
@@ -1982,6 +1984,7 @@ mymain(void)
                         QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC,
                         QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
 
     /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_HTM */
@@ -1991,6 +1994,7 @@ mymain(void)
                         QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC,
                         QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
 
     /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV */
@@ -2000,6 +2004,7 @@ mymain(void)
                         QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC,
                         QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
 
     /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST */
@@ -2009,6 +2014,7 @@ mymain(void)
                         QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC,
                         QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
 
     /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CFPC */
@@ -2018,7 +2024,18 @@ mymain(void)
                         QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
                         QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
-                        QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST);
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC);
+
+    /* parse error: no QEMU_CAPS_MACHINE_PSERIES_SBBC */
+    DO_TEST_PARSE_ERROR("pseries-features",
+                        QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+                        QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
+                        QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC);
 
     DO_TEST_PARSE_ERROR("pseries-features-invalid-machine", NONE);
 
diff --git a/tests/qemuxml2xmloutdata/pseries-features.xml b/tests/qemuxml2xmloutdata/pseries-features.xml
index 1b5d78ce74..3700ffa195 100644
--- a/tests/qemuxml2xmloutdata/pseries-features.xml
+++ b/tests/qemuxml2xmloutdata/pseries-features.xml
@@ -16,6 +16,7 @@
     <nested-hv state='off'/>
     <ccf-assist state='on'/>
     <cfpc value='fixed'/>
+    <sbbc value='broken'/>
   </features>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 41510fd17a..9e1b5be13c 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -695,7 +695,8 @@ mymain(void)
             QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
             QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
             QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT,
-            QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC);
+            QEMU_CAPS_MACHINE_PSERIES_CAP_CFPC,
+            QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC);
 
     DO_TEST("pseries-serial-native",
             QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
-- 
2.25.2





More information about the libvir-list mailing list