diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index e1e219bcb5..741405ec12 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -2022,6 +2022,7 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off.
+
...
@@ -2262,6 +2263,11 @@ are:
exceptions when enabled (``on``). If the attribute is not defined, the
hypervisor default will be used.
:since:`Since 10.4.0` (QEMU/KVM and ARM virt guests only)
+``ps2``
+ Depending on the ``state`` attribute (values ``on``, ``off``) enable or
+ disable the emulation of a PS/2 controller used by ``ps2`` bus input devices.
+ If the attribute is not defined, the hypervisor default will be used.
+ :since:`Since 10.7.0` (QEMU only)
Time keeping
------------
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d950921667..a897b0b727 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -185,6 +185,7 @@ VIR_ENUM_IMPL(virDomainFeature,
"tcg",
"async-teardown",
"ras",
+ "ps2",
);
VIR_ENUM_IMPL(virDomainCapabilitiesPolicy,
@@ -17019,7 +17020,8 @@ virDomainFeaturesDefParse(virDomainDef *def,
case VIR_DOMAIN_FEATURE_HTM:
case VIR_DOMAIN_FEATURE_NESTED_HV:
case VIR_DOMAIN_FEATURE_CCF_ASSIST:
- case VIR_DOMAIN_FEATURE_RAS: {
+ case VIR_DOMAIN_FEATURE_RAS:
+ case VIR_DOMAIN_FEATURE_PS2: {
virTristateSwitch state;
if (virXMLPropTristateSwitch(nodes[i], "state",
@@ -20883,6 +20885,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDef *src,
case VIR_DOMAIN_FEATURE_NESTED_HV:
case VIR_DOMAIN_FEATURE_CCF_ASSIST:
case VIR_DOMAIN_FEATURE_RAS:
+ case VIR_DOMAIN_FEATURE_PS2:
if (src->features[i] != dst->features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of feature '%1$s' differs: source: '%2$s', destination: '%3$s'"),
@@ -27685,6 +27688,7 @@ virDomainDefFormatFeatures(virBuffer *buf,
case VIR_DOMAIN_FEATURE_NESTED_HV:
case VIR_DOMAIN_FEATURE_CCF_ASSIST:
case VIR_DOMAIN_FEATURE_RAS:
+ case VIR_DOMAIN_FEATURE_PS2:
switch ((virTristateSwitch) def->features[i]) {
case VIR_TRISTATE_SWITCH_LAST:
case VIR_TRISTATE_SWITCH_ABSENT:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index eae621f900..f65cdd87b6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2181,6 +2181,7 @@ typedef enum {
VIR_DOMAIN_FEATURE_TCG,
VIR_DOMAIN_FEATURE_ASYNC_TEARDOWN,
VIR_DOMAIN_FEATURE_RAS,
+ VIR_DOMAIN_FEATURE_PS2,
VIR_DOMAIN_FEATURE_LAST
} virDomainFeature;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index ab1caadc7a..eddb4a5e74 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -2753,6 +2753,29 @@ virDomainInputDefValidate(const virDomainInputDef *input,
return -1;
}
+ switch ((virDomainInputBus) input->bus) {
+ case VIR_DOMAIN_INPUT_BUS_PS2:
+ if (def->features[VIR_DOMAIN_FEATURE_PS2] == VIR_TRISTATE_SWITCH_OFF) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("ps2 bus inputs require the ps2 feature not to be disabled"));
+ return -1;
+ }
+ break;
+
+ case VIR_DOMAIN_INPUT_BUS_DEFAULT:
+ case VIR_DOMAIN_INPUT_BUS_USB:
+ case VIR_DOMAIN_INPUT_BUS_XEN:
+ case VIR_DOMAIN_INPUT_BUS_PARALLELS:
+ case VIR_DOMAIN_INPUT_BUS_VIRTIO:
+ case VIR_DOMAIN_INPUT_BUS_NONE:
+ break;
+
+ case VIR_DOMAIN_INPUT_BUS_LAST:
+ default:
+ virReportEnumRangeError(virDomainInputBus, input->bus);
+ return -1;
+ }
+
return 0;
}
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 05ba697924..a71f1d97b9 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -6917,6 +6917,11 @@
+
+
+
+
+
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 28914c9c34..bb6fee4bfd 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6888,6 +6888,11 @@ qemuAppendDomainFeaturesMachineParam(virBuffer *buf,
virBufferAsprintf(buf, ",ras=%s", str);
}
+ if (def->features[VIR_DOMAIN_FEATURE_PS2] != VIR_TRISTATE_SWITCH_ABSENT) {
+ const char *str = virTristateSwitchTypeToString(def->features[VIR_DOMAIN_FEATURE_PS2]);
+ virBufferAsprintf(buf, ",i8042=%s", str);
+ }
+
return 0;
}
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2b4bb54efc..d1767c326d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3928,7 +3928,8 @@ static int
qemuDomainDefAddImplicitInputDevice(virDomainDef *def,
virQEMUCaps *qemuCaps)
{
- if (virQEMUCapsSupportsI8042(qemuCaps, def)) {
+ if (virQEMUCapsSupportsI8042(qemuCaps, def) &&
+ def->features[VIR_DOMAIN_FEATURE_PS2] != VIR_TRISTATE_SWITCH_OFF) {
if (virDomainDefMaybeAddInput(def,
VIR_DOMAIN_INPUT_TYPE_MOUSE,
VIR_DOMAIN_INPUT_BUS_PS2) < 0)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index bcb2803130..f74c538efe 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -143,6 +143,13 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
_("vmport is not available with this QEMU binary"));
return -1;
}
+
+ if (def->features[i] == VIR_TRISTATE_SWITCH_ON &&
+ def->features[VIR_DOMAIN_FEATURE_PS2] == VIR_TRISTATE_SWITCH_OFF) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("vmport feature requires the ps2 feature not to be disabled"));
+ return -1;
+ }
break;
case VIR_DOMAIN_FEATURE_VMCOREINFO:
@@ -242,6 +249,22 @@ qemuValidateDomainDefFeatures(const virDomainDef *def,
}
break;
+ case VIR_DOMAIN_FEATURE_PS2:
+ if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+ !virQEMUCapsSupportsI8042(qemuCaps, def)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("ps2 feature is not available with this QEMU binary"));
+ return -1;
+ }
+
+ if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+ !virQEMUCapsSupportsI8042Toggle(qemuCaps, def)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("ps2 feature state cannot be controlled with this QEMU binary"));
+ return -1;
+ }
+ break;
+
case VIR_DOMAIN_FEATURE_SMM:
case VIR_DOMAIN_FEATURE_KVM:
case VIR_DOMAIN_FEATURE_XEN: