diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index aa9070107b..096e2a3f33 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1193,6 +1193,7 @@
<vapic state='on'/>
<spinlocks state='on' retries='4096'/>
</hyperv>
+ <pvspinlock/>
</features>
...
@@ -1264,6 +1265,13 @@
+
pvspinlock
+ Notify the guest that the host supports paravirtual spinlocks
+ for example by exposing the pvticketlocks mechanism. This feature
+ can be explicitly disabled by using state='off'
+ attribute.
+
+
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 1f30161837..80848d2054 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3561,7 +3561,7 @@
@@ -3607,6 +3607,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d23e72410b..c1e0ea736a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -142,7 +142,8 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST,
"hap",
"viridian",
"privnet",
- "hyperv")
+ "hyperv",
+ "pvspinlock")
VIR_ENUM_IMPL(virDomainFeatureState, VIR_DOMAIN_FEATURE_STATE_LAST,
"default",
@@ -11440,6 +11441,22 @@ virDomainDefParseXML(xmlDocPtr xml,
def->features[val] = VIR_DOMAIN_FEATURE_STATE_ON;
break;
+ case VIR_DOMAIN_FEATURE_PVSPINLOCK:
+ node = ctxt->node;
+ ctxt->node = nodes[i];
+ if ((tmp = virXPathString("string(./@state)", ctxt))) {
+ if ((def->features[val] = virDomainFeatureStateTypeFromString(tmp)) == -1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown state atribute '%s' of feature '%s'"),
+ tmp, virDomainFeatureTypeToString(val));
+ goto error;
+ }
+ } else {
+ def->features[val] = VIR_DOMAIN_FEATURE_STATE_ON;
+ }
+ ctxt->node = node;
+ break;
+
case VIR_DOMAIN_FEATURE_LAST:
break;
}
@@ -16807,6 +16824,23 @@ virDomainDefFormatInternal(virDomainDefPtr def,
break;
+ case VIR_DOMAIN_FEATURE_PVSPINLOCK:
+ switch ((enum virDomainFeatureState) def->features[i]) {
+ case VIR_DOMAIN_FEATURE_STATE_LAST:
+ case VIR_DOMAIN_FEATURE_STATE_DEFAULT:
+ break;
+
+ case VIR_DOMAIN_FEATURE_STATE_ON:
+ virBufferAsprintf(buf, " <%s state='on'/>\n", name);
+ break;
+
+ case VIR_DOMAIN_FEATURE_STATE_OFF:
+ virBufferAsprintf(buf, " <%s state='off'/>\n", name);
+ break;
+ }
+
+ break;
+
case VIR_DOMAIN_FEATURE_APIC:
if (def->features[i] == VIR_DOMAIN_FEATURE_STATE_ON) {
virBufferAddLit(buf, " features[VIR_DOMAIN_FEATURE_PVSPINLOCK]) {
+ char sign;
+ if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_DOMAIN_FEATURE_STATE_ON)
+ sign = '+';
+ else
+ sign = '-';
+
+ virBufferAsprintf(&buf, "%s,%ckvm_pv_unhalt",
+ have_cpu ? "" : default_model,
+ sign);
+ have_cpu = true;
+ }
+
if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_FEATURE_STATE_ON) {
if (!have_cpu) {
virBufferAdd(&buf, default_model, -1);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.args b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.args
new file mode 100644
index 0000000000..80047f9660
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.args
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M pc \
+-cpu qemu32,-kvm_pv_unhalt -m 214 -smp 6 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -boot n -usb -net none -serial \
+none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.xml b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.xml
new file mode 100644
index 0000000000..4820476b2b
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-disabled.xml
@@ -0,0 +1,26 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219100
+ 219100
+ 6
+
+ hvm
+
+
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu
+
+
+
+
+
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.args b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.args
new file mode 100644
index 0000000000..70db1730c5
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.args
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M pc \
+-cpu qemu32,+kvm_pv_unhalt -m 214 -smp 6 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -boot n -usb -net none -serial \
+none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.xml b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.xml
new file mode 100644
index 0000000000..ac8781b558
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-pv-spinlock-enabled.xml
@@ -0,0 +1,26 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219100
+ 219100
+ 6
+
+ hvm
+
+
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu
+
+
+
+
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index a74ac2a597..0629e310ef 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -448,6 +448,8 @@ mymain(void)
QEMU_CAPS_CHARDEV_SPICEVMC, QEMU_CAPS_SPICE, QEMU_CAPS_HDA_DUPLEX);
DO_TEST("eoi-disabled", NONE);
DO_TEST("eoi-enabled", NONE);
+ DO_TEST("pv-spinlock-disabled", NONE);
+ DO_TEST("pv-spinlock-enabled", NONE);
DO_TEST("kvmclock+eoi-disabled", QEMU_CAPS_ENABLE_KVM);
DO_TEST("hyperv", NONE);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 4e308b406b..ffff3b5569 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -159,6 +159,8 @@ mymain(void)
DO_TEST("cpu-eoi-enabled");
DO_TEST("eoi-disabled");
DO_TEST("eoi-enabled");
+ DO_TEST("pv-spinlock-disabled");
+ DO_TEST("pv-spinlock-enabled");
DO_TEST("hyperv");
DO_TEST("hyperv-off");