mirror of https://gitee.com/openkylin/libvirt.git
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:
parent
2e26d78c8b
commit
7068b56c85
|
@ -1460,6 +1460,11 @@
|
|||
<relaxed state='on'/>
|
||||
<vapic state='on'/>
|
||||
<spinlocks state='on' retries='4096'/>
|
||||
<vpindex state='on'/>
|
||||
<runtime state='on'/>
|
||||
<synic state='on'/>
|
||||
<reset state='on'/>
|
||||
<vendor_id state='on' value='KVM Hv'/>
|
||||
</hyperv>
|
||||
<kvm>
|
||||
<hidden state='on'/>
|
||||
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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'/>
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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'/>
|
||||
|
|
|
@ -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'/>
|
||||
|
|
|
@ -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'/>
|
||||
|
|
Loading…
Reference in New Issue