conf: qemu: Add support for more HyperV Enlightenment features

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>
This commit is contained in:
Maxim Nestratov 2016-03-10 15:43:49 +03:00 committed by John Ferlan
parent 2e26d78c8b
commit 7068b56c85
11 changed files with 210 additions and 2 deletions

View File

@ -1460,6 +1460,11 @@
&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;
@ -1537,6 +1542,42 @@
<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>

View File

@ -4902,6 +4902,43 @@
</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>

View 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;

View 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];

View 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;

View 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;
}

View File

@ -14,6 +14,12 @@
<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'/>

View 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 \

View File

@ -14,6 +14,12 @@
<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'/>

View File

@ -14,6 +14,12 @@
<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'/>

View File

@ -14,6 +14,12 @@
<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'/>