qemu: Introduce the 'ps2' feature

This introduces a new 'ps2' feature which, when disabled, results in
no implicit PS/2 bus input devices being automatically added to the
domain and addition of the 'i8042=off' machine option to the QEMU
command-line.

A notable side effect of disabling the i8042 controller in QEMU is that
the vmport device won't be created. For this reason we will not allow
setting the vmport feature if the ps2 feature is explicitly disabled.

Signed-off-by: Kamil Szczęk <kamil@szczek.dev>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Kamil Szczęk 2024-08-19 01:19:21 +00:00 committed by Michal Privoznik
parent 9eb3c28323
commit a9a5f8ef39
8 changed files with 70 additions and 2 deletions

View File

@ -2022,6 +2022,7 @@ Hypervisors may allow certain CPU / machine features to be toggled on/off.
</tcg>
<async-teardown enabled='yes'/>
<ras state='on'/>
<ps2 state='on'/>
</features>
...
@ -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
------------

View File

@ -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:

View File

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

View File

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

View File

@ -6917,6 +6917,11 @@
<ref name="featurestate"/>
</element>
</optional>
<optional>
<element name="ps2">
<ref name="featurestate"/>
</element>
</optional>
</interleave>
</element>
</optional>

View File

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

View File

@ -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)

View File

@ -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: