提交 7068b56c 编写于 作者: M Maxim Nestratov 提交者: John Ferlan

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: NNikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Signed-off-by: NJohn Ferlan <jferlan@redhat.com>
上级 2e26d78c
...@@ -1460,6 +1460,11 @@ ...@@ -1460,6 +1460,11 @@
&lt;relaxed state='on'/&gt; &lt;relaxed state='on'/&gt;
&lt;vapic state='on'/&gt; &lt;vapic state='on'/&gt;
&lt;spinlocks state='on' retries='4096'/&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;/hyperv&gt;
&lt;kvm&gt; &lt;kvm&gt;
&lt;hidden state='on'/&gt; &lt;hidden state='on'/&gt;
...@@ -1537,6 +1542,42 @@ ...@@ -1537,6 +1542,42 @@
<td>on, off; retries - at least 4095</td> <td>on, off; retries - at least 4095</td>
<td><span class="since">1.1.0 (QEMU only)</span></td> <td><span class="since">1.1.0 (QEMU only)</span></td>
</tr> </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> </table>
</dd> </dd>
<dt><code>pvspinlock</code></dt> <dt><code>pvspinlock</code></dt>
......
...@@ -4902,6 +4902,43 @@ ...@@ -4902,6 +4902,43 @@
</optional> </optional>
</element> </element>
</optional> </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> </interleave>
</element> </element>
</define> </define>
......
...@@ -145,7 +145,13 @@ VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST, ...@@ -145,7 +145,13 @@ VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST,
VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST, VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST,
"relaxed", "relaxed",
"vapic", "vapic",
"spinlocks") "spinlocks",
"vpindex",
"runtime",
"synic",
"stimer",
"reset",
"vendor_id")
VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST, VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST,
"hidden") "hidden")
...@@ -2599,6 +2605,7 @@ void virDomainDefFree(virDomainDefPtr def) ...@@ -2599,6 +2605,7 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->emulator); VIR_FREE(def->emulator);
VIR_FREE(def->description); VIR_FREE(def->description);
VIR_FREE(def->title); VIR_FREE(def->title);
VIR_FREE(def->hyperv_vendor_id);
virBlkioDeviceArrayClear(def->blkio.devices, virBlkioDeviceArrayClear(def->blkio.devices,
def->blkio.ndevices); def->blkio.ndevices);
...@@ -15605,6 +15612,11 @@ virDomainDefParseXML(xmlDocPtr xml, ...@@ -15605,6 +15612,11 @@ virDomainDefParseXML(xmlDocPtr xml,
switch ((virDomainHyperv) feature) { switch ((virDomainHyperv) feature) {
case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC: 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; break;
case VIR_DOMAIN_HYPERV_SPINLOCKS: case VIR_DOMAIN_HYPERV_SPINLOCKS:
...@@ -15626,6 +15638,33 @@ virDomainDefParseXML(xmlDocPtr xml, ...@@ -15626,6 +15638,33 @@ virDomainDefParseXML(xmlDocPtr xml,
} }
break; 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] */ /* coverity[dead_error_begin] */
case VIR_DOMAIN_HYPERV_LAST: case VIR_DOMAIN_HYPERV_LAST:
break; break;
...@@ -17628,6 +17667,11 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, ...@@ -17628,6 +17667,11 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
switch ((virDomainHyperv) i) { switch ((virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC: 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]) { if (src->hyperv_features[i] != dst->hyperv_features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of HyperV enlightenment " _("State of HyperV enlightenment "
...@@ -17653,6 +17697,17 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, ...@@ -17653,6 +17697,17 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
} }
break; 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] */ /* coverity[dead_error_begin] */
case VIR_DOMAIN_HYPERV_LAST: case VIR_DOMAIN_HYPERV_LAST:
break; break;
...@@ -22342,6 +22397,11 @@ virDomainDefFormatInternal(virDomainDefPtr def, ...@@ -22342,6 +22397,11 @@ virDomainDefFormatInternal(virDomainDefPtr def,
switch ((virDomainHyperv) j) { switch ((virDomainHyperv) j) {
case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC: 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; break;
case VIR_DOMAIN_HYPERV_SPINLOCKS: case VIR_DOMAIN_HYPERV_SPINLOCKS:
...@@ -22351,6 +22411,13 @@ virDomainDefFormatInternal(virDomainDefPtr def, ...@@ -22351,6 +22411,13 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def->hyperv_spinlocks); def->hyperv_spinlocks);
break; 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] */ /* coverity[dead_error_begin] */
case VIR_DOMAIN_HYPERV_LAST: case VIR_DOMAIN_HYPERV_LAST:
break; break;
......
...@@ -1701,10 +1701,18 @@ typedef enum { ...@@ -1701,10 +1701,18 @@ typedef enum {
VIR_DOMAIN_FEATURE_LAST VIR_DOMAIN_FEATURE_LAST
} virDomainFeature; } virDomainFeature;
# define VIR_DOMAIN_HYPERV_VENDOR_ID_MAX 12
typedef enum { typedef enum {
VIR_DOMAIN_HYPERV_RELAXED = 0, VIR_DOMAIN_HYPERV_RELAXED = 0,
VIR_DOMAIN_HYPERV_VAPIC, VIR_DOMAIN_HYPERV_VAPIC,
VIR_DOMAIN_HYPERV_SPINLOCKS, 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 VIR_DOMAIN_HYPERV_LAST
} virDomainHyperv; } virDomainHyperv;
...@@ -2240,6 +2248,7 @@ struct _virDomainDef { ...@@ -2240,6 +2248,7 @@ struct _virDomainDef {
int kvm_features[VIR_DOMAIN_KVM_LAST]; int kvm_features[VIR_DOMAIN_KVM_LAST];
unsigned int hyperv_spinlocks; unsigned int hyperv_spinlocks;
virGICVersion gic_version; virGICVersion gic_version;
char *hyperv_vendor_id;
/* These options are of type virTristateSwitch: ON = keep, OFF = drop */ /* These options are of type virTristateSwitch: ON = keep, OFF = drop */
int caps_features[VIR_DOMAIN_CAPS_FEATURE_LAST]; int caps_features[VIR_DOMAIN_CAPS_FEATURE_LAST];
......
...@@ -6505,6 +6505,11 @@ qemuBuildCpuCommandLine(virCommandPtr cmd, ...@@ -6505,6 +6505,11 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
switch ((virDomainHyperv) i) { switch ((virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC: 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) if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
virBufferAsprintf(&buf, ",hv_%s", virBufferAsprintf(&buf, ",hv_%s",
virDomainHypervTypeToString(i)); virDomainHypervTypeToString(i));
...@@ -6516,6 +6521,12 @@ qemuBuildCpuCommandLine(virCommandPtr cmd, ...@@ -6516,6 +6521,12 @@ qemuBuildCpuCommandLine(virCommandPtr cmd,
def->hyperv_spinlocks); def->hyperv_spinlocks);
break; 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] */ /* coverity[dead_error_begin] */
case VIR_DOMAIN_HYPERV_LAST: case VIR_DOMAIN_HYPERV_LAST:
break; break;
......
...@@ -1539,6 +1539,11 @@ qemuParseCommandLineCPU(virDomainDefPtr dom, ...@@ -1539,6 +1539,11 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
switch ((virDomainHyperv) f) { switch ((virDomainHyperv) f) {
case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC: 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) { if (value) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("HyperV feature '%s' should not " _("HyperV feature '%s' should not "
...@@ -1566,6 +1571,19 @@ qemuParseCommandLineCPU(virDomainDefPtr dom, ...@@ -1566,6 +1571,19 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
dom->hyperv_spinlocks = 0xFFF; dom->hyperv_spinlocks = 0xFFF;
break; 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: case VIR_DOMAIN_HYPERV_LAST:
break; break;
} }
......
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
<relaxed state='off'/> <relaxed state='off'/>
<vapic state='off'/> <vapic state='off'/>
<spinlocks 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> </hyperv>
</features> </features>
<clock offset='utc'/> <clock offset='utc'/>
......
...@@ -8,7 +8,8 @@ QEMU_AUDIO_DRV=none \ ...@@ -8,7 +8,8 @@ QEMU_AUDIO_DRV=none \
-name QEMUGuest1 \ -name QEMUGuest1 \
-S \ -S \
-M pc \ -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 \ -m 214 \
-smp 6 \ -smp 6 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
......
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
<relaxed state='on'/> <relaxed state='on'/>
<vapic state='on'/> <vapic state='on'/>
<spinlocks state='on' retries='12287'/> <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> </hyperv>
</features> </features>
<clock offset='utc'/> <clock offset='utc'/>
......
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
<relaxed state='off'/> <relaxed state='off'/>
<vapic state='off'/> <vapic state='off'/>
<spinlocks 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> </hyperv>
</features> </features>
<clock offset='utc'/> <clock offset='utc'/>
......
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
<relaxed state='on'/> <relaxed state='on'/>
<vapic state='on'/> <vapic state='on'/>
<spinlocks state='on' retries='12287'/> <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> </hyperv>
</features> </features>
<clock offset='utc'/> <clock offset='utc'/>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册