]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: qemu: Add support for more HyperV Enlightenment features
authorMaxim Nestratov <mnestratov@virtuozzo.com>
Thu, 10 Mar 2016 12:43:49 +0000 (15:43 +0300)
committerJohn Ferlan <jferlan@redhat.com>
Mon, 28 Mar 2016 17:10:18 +0000 (13:10 -0400)
This patch adds support for "vpindex", "runtime", "synic",
"stimer", and "vendor_id" features available in qemu 2.5+.

- When Hyper-V "vpindex" is on, guest can use MSR HV_X64_MSR_VP_INDEX
to get virtual processor ID.

- Hyper-V "runtime" enlightement feature allows to use MSR
HV_X64_MSR_VP_RUNTIME to get the time the virtual processor consumes
running guest code, as well as the time the hypervisor spends running
code on behalf of that guest.

- Hyper-V "synic" stands for Synthetic Interrupt Controller, which is
lapic extension controlled via MSRs.

- Hyper-V "stimer" switches on Hyper-V SynIC timers MSR's support.
Guest can setup and use fired by host events (SynIC interrupt and
appropriate timer expiration message) as guest clock events

- Hyper-V "reset" allows guest to reset VM.

- Hyper-V "vendor_id" exposes hypervisor vendor id to guest.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Signed-off-by: John Ferlan <jferlan@redhat.com>
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_command.c
src/qemu/qemu_parse_command.c
tests/qemuxml2argvdata/qemuxml2argv-hyperv-off.xml
tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv-off.xml
tests/qemuxml2xmloutdata/qemuxml2xmlout-hyperv.xml

index 71ffe750452eb77020689a8bdde16190be6c384f..630c682a6f25975a8ebe9015e20ece9b754abcf7 100644 (file)
       &lt;relaxed state='on'/&gt;
       &lt;vapic state='on'/&gt;
       &lt;spinlocks state='on' retries='4096'/&gt;
+      &lt;vpindex state='on'/&gt;
+      &lt;runtime state='on'/&gt;
+      &lt;synic state='on'/&gt;
+      &lt;reset state='on'/&gt;
+      &lt;vendor_id state='on' value='KVM Hv'/&gt;
     &lt;/hyperv&gt;
     &lt;kvm&gt;
       &lt;hidden state='on'/&gt;
           <td>on, off; retries - at least 4095</td>
           <td><span class="since">1.1.0 (QEMU only)</span></td>
         </tr>
+        <tr>
+          <td>vpindex</td>
+          <td>Virtual processor index</td>
+          <td> on, off</td>
+          <td><span class="since">1.3.3 (QEMU 2.5)</span></td>
+        </tr>
+        <tr>
+          <td>runtime</td>
+          <td>Processor time spent on running guest code and on behalf of guest code</td>
+          <td> on, off</td>
+          <td><span class="since">1.3.3 (QEMU 2.5)</span></td>
+        </tr>
+        <tr>
+          <td>synic</td>
+          <td>Enable Synthetic Interrupt Controller (SyNIC)</td>
+          <td> on, off</td>
+          <td><span class="since">1.3.3 (QEMU 2.5)</span></td>
+        </tr>
+        <tr>
+          <td>stimer</td>
+          <td>Enable SyNIC timers</td>
+          <td> on, off</td>
+          <td><span class="since">1.3.3 (QEMU 2.5)</span></td>
+        </tr>
+        <tr>
+          <td>reset</td>
+          <td>Enable hypervisor reset</td>
+          <td> on, off</td>
+          <td><span class="since">1.3.3 (QEMU 2.5)</span></td>
+        </tr>
+        <tr>
+          <td>vendor_id</td>
+          <td>Set hypervisor vendor id</td>
+          <td>on, off; value - string, up to 12 characters</td>
+          <td><span class="since">1.3.3 (QEMU 2.5)</span></td>
+        </tr>
       </table>
       </dd>
       <dt><code>pvspinlock</code></dt>
index da6de40f87640cbff2e0cc46b265d1ed0a59b9a7..46137ec4caec4223f20062723738203488893386 100644 (file)
             </optional>
           </element>
         </optional>
+        <optional>
+          <element name="vpindex">
+            <ref name="featurestate"/>
+          </element>
+        </optional>
+        <optional>
+          <element name="runtime">
+            <ref name="featurestate"/>
+          </element>
+        </optional>
+        <optional>
+          <element name="synic">
+            <ref name="featurestate"/>
+          </element>
+        </optional>
+        <optional>
+          <element name="stimer">
+            <ref name="featurestate"/>
+          </element>
+        </optional>
+        <optional>
+          <element name="reset">
+            <ref name="featurestate"/>
+          </element>
+        </optional>
+        <optional>
+          <element name="vendor_id">
+            <ref name="featurestate"/>
+            <optional>
+              <attribute name="value">
+                <data type="string">
+                  <param name='pattern'>[^,]{0,12}</param>
+                </data>
+              </attribute>
+            </optional>
+          </element>
+        </optional>
       </interleave>
     </element>
   </define>
index 797570a42f9b433e90ced5e91e856bbe02d580af..771ab4568e1d719d5f4a2b6557a11e0679340780 100644 (file)
@@ -145,7 +145,13 @@ VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST,
 VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST,
               "relaxed",
               "vapic",
-              "spinlocks")
+              "spinlocks",
+              "vpindex",
+              "runtime",
+              "synic",
+              "stimer",
+              "reset",
+              "vendor_id")
 
 VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST,
               "hidden")
@@ -2599,6 +2605,7 @@ void virDomainDefFree(virDomainDefPtr def)
     VIR_FREE(def->emulator);
     VIR_FREE(def->description);
     VIR_FREE(def->title);
+    VIR_FREE(def->hyperv_vendor_id);
 
     virBlkioDeviceArrayClear(def->blkio.devices,
                              def->blkio.ndevices);
@@ -15605,6 +15612,11 @@ virDomainDefParseXML(xmlDocPtr xml,
             switch ((virDomainHyperv) feature) {
             case VIR_DOMAIN_HYPERV_RELAXED:
             case VIR_DOMAIN_HYPERV_VAPIC:
+            case VIR_DOMAIN_HYPERV_VPINDEX:
+            case VIR_DOMAIN_HYPERV_RUNTIME:
+            case VIR_DOMAIN_HYPERV_SYNIC:
+            case VIR_DOMAIN_HYPERV_STIMER:
+            case VIR_DOMAIN_HYPERV_RESET:
                 break;
 
             case VIR_DOMAIN_HYPERV_SPINLOCKS:
@@ -15626,6 +15638,33 @@ virDomainDefParseXML(xmlDocPtr xml,
                 }
                 break;
 
+            case VIR_DOMAIN_HYPERV_VENDOR_ID:
+                if (value != VIR_TRISTATE_SWITCH_ON)
+                    break;
+
+                if (!(def->hyperv_vendor_id = virXPathString("string(./@value)",
+                                                             ctxt))) {
+                    virReportError(VIR_ERR_XML_ERROR, "%s",
+                                   _("missing 'value' attribute for "
+                                     "HyperV feature 'vendor_id'"));
+                    goto error;
+                }
+
+                if (strlen(def->hyperv_vendor_id) > VIR_DOMAIN_HYPERV_VENDOR_ID_MAX) {
+                    virReportError(VIR_ERR_XML_ERROR,
+                                   _("HyperV vendor_id value must not be more "
+                                     "than %d characters."),
+                                   VIR_DOMAIN_HYPERV_VENDOR_ID_MAX);
+                    goto error;
+                }
+
+                /* ensure that the string can be passed to qemu */
+                if (strchr(def->hyperv_vendor_id, ',')) {
+                    virReportError(VIR_ERR_XML_ERROR, "%s",
+                                   _("HyperV vendor_id value is invalid"));
+                    goto error;
+                }
+
             /* coverity[dead_error_begin] */
             case VIR_DOMAIN_HYPERV_LAST:
                 break;
@@ -17628,6 +17667,11 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
             switch ((virDomainHyperv) i) {
             case VIR_DOMAIN_HYPERV_RELAXED:
             case VIR_DOMAIN_HYPERV_VAPIC:
+            case VIR_DOMAIN_HYPERV_VPINDEX:
+            case VIR_DOMAIN_HYPERV_RUNTIME:
+            case VIR_DOMAIN_HYPERV_SYNIC:
+            case VIR_DOMAIN_HYPERV_STIMER:
+            case VIR_DOMAIN_HYPERV_RESET:
                 if (src->hyperv_features[i] != dst->hyperv_features[i]) {
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                    _("State of HyperV enlightenment "
@@ -17653,6 +17697,17 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
                 }
                 break;
 
+            case VIR_DOMAIN_HYPERV_VENDOR_ID:
+                if (STRNEQ_NULLABLE(src->hyperv_vendor_id, dst->hyperv_vendor_id)) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("HyperV vendor_id differs: "
+                                     "source: '%s', destination: '%s'"),
+                                   src->hyperv_vendor_id,
+                                   dst->hyperv_vendor_id);
+                    return false;
+                }
+                break;
+
             /* coverity[dead_error_begin] */
             case VIR_DOMAIN_HYPERV_LAST:
                 break;
@@ -22342,6 +22397,11 @@ virDomainDefFormatInternal(virDomainDefPtr def,
                     switch ((virDomainHyperv) j) {
                     case VIR_DOMAIN_HYPERV_RELAXED:
                     case VIR_DOMAIN_HYPERV_VAPIC:
+                    case VIR_DOMAIN_HYPERV_VPINDEX:
+                    case VIR_DOMAIN_HYPERV_RUNTIME:
+                    case VIR_DOMAIN_HYPERV_SYNIC:
+                    case VIR_DOMAIN_HYPERV_STIMER:
+                    case VIR_DOMAIN_HYPERV_RESET:
                         break;
 
                     case VIR_DOMAIN_HYPERV_SPINLOCKS:
@@ -22351,6 +22411,13 @@ virDomainDefFormatInternal(virDomainDefPtr def,
                                           def->hyperv_spinlocks);
                         break;
 
+                    case VIR_DOMAIN_HYPERV_VENDOR_ID:
+                        if (def->hyperv_features[j] != VIR_TRISTATE_SWITCH_ON)
+                            break;
+                        virBufferEscapeString(buf, " value='%s'",
+                                              def->hyperv_vendor_id);
+                        break;
+
                     /* coverity[dead_error_begin] */
                     case VIR_DOMAIN_HYPERV_LAST:
                         break;
index 83bdd67dec4531f3043711d5e2a77db09d63e959..639fac5376c2d4466a8d3657d689b7024507688f 100644 (file)
@@ -1701,10 +1701,18 @@ typedef enum {
     VIR_DOMAIN_FEATURE_LAST
 } virDomainFeature;
 
+# define VIR_DOMAIN_HYPERV_VENDOR_ID_MAX 12
+
 typedef enum {
     VIR_DOMAIN_HYPERV_RELAXED = 0,
     VIR_DOMAIN_HYPERV_VAPIC,
     VIR_DOMAIN_HYPERV_SPINLOCKS,
+    VIR_DOMAIN_HYPERV_VPINDEX,
+    VIR_DOMAIN_HYPERV_RUNTIME,
+    VIR_DOMAIN_HYPERV_SYNIC,
+    VIR_DOMAIN_HYPERV_STIMER,
+    VIR_DOMAIN_HYPERV_RESET,
+    VIR_DOMAIN_HYPERV_VENDOR_ID,
 
     VIR_DOMAIN_HYPERV_LAST
 } virDomainHyperv;
@@ -2240,6 +2248,7 @@ struct _virDomainDef {
     int kvm_features[VIR_DOMAIN_KVM_LAST];
     unsigned int hyperv_spinlocks;
     virGICVersion gic_version;
+    char *hyperv_vendor_id;
 
     /* These options are of type virTristateSwitch: ON = keep, OFF = drop */
     int caps_features[VIR_DOMAIN_CAPS_FEATURE_LAST];
index 0331789b6b598e470594a6e5d616ba3080677980..45c5398ad8b9e4e8f3ee6861d368c4f2ae898c6f 100644 (file)
@@ -6505,6 +6505,11 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
             switch ((virDomainHyperv) i) {
             case VIR_DOMAIN_HYPERV_RELAXED:
             case VIR_DOMAIN_HYPERV_VAPIC:
+            case VIR_DOMAIN_HYPERV_VPINDEX:
+            case VIR_DOMAIN_HYPERV_RUNTIME:
+            case VIR_DOMAIN_HYPERV_SYNIC:
+            case VIR_DOMAIN_HYPERV_STIMER:
+            case VIR_DOMAIN_HYPERV_RESET:
                 if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
                     virBufferAsprintf(&buf, ",hv_%s",
                                       virDomainHypervTypeToString(i));
@@ -6516,6 +6521,12 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
                                       def->hyperv_spinlocks);
                 break;
 
+            case VIR_DOMAIN_HYPERV_VENDOR_ID:
+                if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
+                    virBufferAsprintf(&buf, ",hv_vendor_id=%s",
+                                      def->hyperv_vendor_id);
+                break;
+
             /* coverity[dead_error_begin] */
             case VIR_DOMAIN_HYPERV_LAST:
                 break;
index 60e3d6916205eb768d7edd2c1afebef86a30f37b..8b294a7df02a93ee219498ada51db61c3f3ac44d 100644 (file)
@@ -1539,6 +1539,11 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
             switch ((virDomainHyperv) f) {
             case VIR_DOMAIN_HYPERV_RELAXED:
             case VIR_DOMAIN_HYPERV_VAPIC:
+            case VIR_DOMAIN_HYPERV_VPINDEX:
+            case VIR_DOMAIN_HYPERV_RUNTIME:
+            case VIR_DOMAIN_HYPERV_SYNIC:
+            case VIR_DOMAIN_HYPERV_STIMER:
+            case VIR_DOMAIN_HYPERV_RESET:
                 if (value) {
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                    _("HyperV feature '%s' should not "
@@ -1566,6 +1571,19 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
                     dom->hyperv_spinlocks = 0xFFF;
                 break;
 
+            case VIR_DOMAIN_HYPERV_VENDOR_ID:
+                dom->hyperv_features[f] = VIR_TRISTATE_SWITCH_ON;
+                if (!value) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("missing HyperV vendor_id value"));
+                    goto cleanup;
+                }
+
+                if (VIR_STRDUP(dom->hyperv_vendor_id, value) < 0)
+                    goto cleanup;
+
+                break;
+
             case VIR_DOMAIN_HYPERV_LAST:
                 break;
             }
index 1067f64e80977e04e89353d801458e227f9643b4..fe084636fd8784804f5b9764cd32a10d4f2b93e4 100644 (file)
       <relaxed state='off'/>
       <vapic state='off'/>
       <spinlocks state='off'/>
+      <vpindex state='off'/>
+      <runtime state='off'/>
+      <synic state='off'/>
+      <stimer state='off'/>
+      <reset state='off'/>
+      <vendor_id state='off'/>
     </hyperv>
   </features>
   <clock offset='utc'/>
index 141844a4b7f5b379438a08a31d4ec82a33daf077..32846a27074f5bdf9ae381dbfa248ce80c9cfe19 100644 (file)
@@ -8,7 +8,8 @@ QEMU_AUDIO_DRV=none \
 -name QEMUGuest1 \
 -S \
 -M pc \
--cpu qemu32,hv_relaxed,hv_vapic,hv_spinlocks=0x2fff \
+-cpu 'qemu32,hv_relaxed,hv_vapic,hv_spinlocks=0x2fff,hv_vpindex,hv_runtime,\
+hv_synic,hv_stimer,hv_reset,hv_vendor_id=KVM Hv' \
 -m 214 \
 -smp 6 \
 -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
index 2b8f332a6b853f5bdadee2832568f50b966eb812..a47013bc243d921beb46727b89fdc968d9dad210 100644 (file)
       <relaxed state='on'/>
       <vapic state='on'/>
       <spinlocks state='on' retries='12287'/>
+      <vpindex state='on'/>
+      <runtime state='on'/>
+      <synic state='on'/>
+      <stimer state='on'/>
+      <reset state='on'/>
+      <vendor_id state='on' value='KVM Hv'/>
     </hyperv>
   </features>
   <clock offset='utc'/>
index b09c447869c28291d6edad34557f36fabe1b70ca..6163a5d6d99baea6036afe073a18c3c7035c2c9c 100644 (file)
       <relaxed state='off'/>
       <vapic state='off'/>
       <spinlocks state='off'/>
+      <vpindex state='off'/>
+      <runtime state='off'/>
+      <synic state='off'/>
+      <stimer state='off'/>
+      <reset state='off'/>
+      <vendor_id state='off'/>
     </hyperv>
   </features>
   <clock offset='utc'/>
index a79115ceb99f63272c0cf0ce67a0f2f24bbc7b77..c11c27393ba7466be67563d813a998edd205f6e5 100644 (file)
       <relaxed state='on'/>
       <vapic state='on'/>
       <spinlocks state='on' retries='12287'/>
+      <vpindex state='on'/>
+      <runtime state='on'/>
+      <synic state='on'/>
+      <stimer state='on'/>
+      <reset state='on'/>
+      <vendor_id state='on' value='KVM Hv'/>
     </hyperv>
   </features>
   <clock offset='utc'/>