This is the first pSeries-specific optional feature that is used to represent a hardware bug and to control how it will be exposed to the guest. Signed-off-by: Andrea Bolognani <abologna@xxxxxxxxxx> --- docs/schemas/domaincommon.rng | 15 +++++++ src/conf/domain_conf.c | 47 ++++++++++++++++++++++ src/conf/domain_conf.h | 12 ++++++ src/libvirt_private.syms | 2 + src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 13 ++++++ src/qemu/qemu_domain.c | 10 +++++ tests/qemuxml2argvdata/pseries-features-sbbc.args | 19 +++++++++ tests/qemuxml2argvdata/pseries-features-sbbc.xml | 28 +++++++++++++ tests/qemuxml2argvtest.c | 5 +++ tests/qemuxml2xmloutdata/pseries-features-sbbc.xml | 1 + tests/qemuxml2xmltest.c | 3 ++ 13 files changed, 158 insertions(+) create mode 100644 tests/qemuxml2argvdata/pseries-features-sbbc.args create mode 100644 tests/qemuxml2argvdata/pseries-features-sbbc.xml create mode 120000 tests/qemuxml2xmloutdata/pseries-features-sbbc.xml diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 262f83ad7..8e19a687a 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -4802,6 +4802,11 @@ <ref name="featurestate"/> </element> </optional> + <optional> + <element name="sbbc"> + <ref name="hwbugstate"/> + </element> + </optional> <optional> <ref name="vmcoreinfo"/> </optional> @@ -5802,6 +5807,16 @@ </attribute> </define> + <define name="hwbugstate"> + <attribute name="state"> + <choice> + <value>broken</value> + <value>workaround</value> + <value>fixed</value> + </choice> + </attribute> + </define> + <!-- Optional hypervisor extensions in their own namespace: QEmu diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ea3930c5d..fcc84dc95 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -153,6 +153,7 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST, "hpt", "vmcoreinfo", "htm", + "sbbc", ); VIR_ENUM_IMPL(virDomainCapabilitiesPolicy, VIR_DOMAIN_CAPABILITIES_POLICY_LAST, @@ -913,6 +914,14 @@ VIR_ENUM_IMPL(virDomainHPTResizing, "required", ); +VIR_ENUM_IMPL(virDomainHWBug, + VIR_DOMAIN_HWBUG_LAST, + "none", + "broken", + "workaround", + "fixed", +); + /* Internal mapping: subset of block job types that can be present in * <mirror> XML (remaining types are not two-phase). */ VIR_ENUM_DECL(virDomainBlockJob) @@ -19268,6 +19277,23 @@ virDomainDefParseXML(xmlDocPtr xml, VIR_FREE(tmp); break; + case VIR_DOMAIN_FEATURE_SBBC: + if (!(tmp = virXMLPropString(nodes[i], "state"))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing state attribute '%s' of feature '%s'"), + tmp, virDomainFeatureTypeToString(val)); + goto error; + } + if ((def->features[val] = virDomainHWBugTypeFromString(tmp)) < 0 || + def->features[val] == VIR_DOMAIN_HWBUG_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown state attribute '%s' of feature '%s'"), + tmp, virDomainFeatureTypeToString(val)); + goto error; + } + VIR_FREE(tmp); + break; + /* coverity[dead_error_begin] */ case VIR_DOMAIN_FEATURE_LAST: break; @@ -21433,6 +21459,18 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src, } break; + case VIR_DOMAIN_FEATURE_SBBC: + if (src->features[i] != dst->features[i]) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("State of feature '%s:%s' differs: " + "source: '%s', destination: '%s'"), + featureName, "state", + virDomainHWBugTypeToString(src->features[i]), + virDomainHWBugTypeToString(dst->features[i])); + return false; + } + break; + case VIR_DOMAIN_FEATURE_LAST: break; } @@ -26970,6 +27008,15 @@ virDomainDefFormatInternal(virDomainDefPtr def, virDomainHPTResizingTypeToString(def->features[i])); break; + case VIR_DOMAIN_FEATURE_SBBC: + if (def->features[i] == VIR_DOMAIN_HWBUG_NONE) + break; + + virBufferAsprintf(buf, "<%s state='%s'/>\n", + name, + virDomainHWBugTypeToString(def->features[i])); + break; + /* coverity[dead_error_begin] */ case VIR_DOMAIN_FEATURE_LAST: break; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3a1fa1522..ab106e900 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1742,6 +1742,7 @@ typedef enum { VIR_DOMAIN_FEATURE_HPT, VIR_DOMAIN_FEATURE_VMCOREINFO, VIR_DOMAIN_FEATURE_HTM, + VIR_DOMAIN_FEATURE_SBBC, VIR_DOMAIN_FEATURE_LAST } virDomainFeature; @@ -1882,6 +1883,17 @@ typedef enum { VIR_ENUM_DECL(virDomainHPTResizing); +typedef enum { + VIR_DOMAIN_HWBUG_NONE = 0, + VIR_DOMAIN_HWBUG_BROKEN, + VIR_DOMAIN_HWBUG_WORKAROUND, + VIR_DOMAIN_HWBUG_FIXED, + + VIR_DOMAIN_HWBUG_LAST +} virDomainHWBug; + +VIR_ENUM_DECL(virDomainHWBug); + /* Operating system configuration data & machine / arch */ typedef struct _virDomainOSEnv virDomainOSEnv; typedef virDomainOSEnv *virDomainOSEnvPtr; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 17c3b71e0..c21346027 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -396,6 +396,8 @@ virDomainHostdevSubsysTypeToString; virDomainHPTResizingTypeToString; virDomainHubTypeFromString; virDomainHubTypeToString; +virDomainHWBugTypeFromString; +virDomainHWBugTypeToString; virDomainHypervTypeFromString; virDomainHypervTypeToString; virDomainInputBusTypeToString; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index c3b1f748a..be216bccf 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -460,6 +460,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "machine.pseries.max-cpu-compat", "dump-completed", "machine.pseries.cap-htm", + "machine.pseries.cap-sbbc", ); @@ -4903,6 +4904,7 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, if (qemuCaps->version >= 2012000 && ARCH_IS_PPC64(qemuCaps->arch)) { virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM); + virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC); } if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 5d9b67177..8fbfc94d5 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -445,6 +445,7 @@ typedef enum { QEMU_CAPS_MACHINE_PSERIES_MAX_CPU_COMPAT, /* -machine pseries,max-cpu-compat= */ QEMU_CAPS_DUMP_COMPLETED, /* DUMP_COMPLETED event */ QEMU_CAPS_MACHINE_PSERIES_CAP_HTM, /* -machine pseries,cap-htm= */ + QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC, /* -machine pseries,cap-sbbc= */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 877482853..c83758b77 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7066,6 +7066,8 @@ virDomainFeatureToQEMUCaps(int feature) switch ((virDomainFeature) feature) { case VIR_DOMAIN_FEATURE_HTM: return QEMU_CAPS_MACHINE_PSERIES_CAP_HTM; + case VIR_DOMAIN_FEATURE_SBBC: + return QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC; case VIR_DOMAIN_FEATURE_ACPI: case VIR_DOMAIN_FEATURE_APIC: case VIR_DOMAIN_FEATURE_PAE: @@ -7096,6 +7098,8 @@ virDomainFeatureToMachineOption(int feature) switch ((virDomainFeature) feature) { case VIR_DOMAIN_FEATURE_HTM: return "cap-htm"; + case VIR_DOMAIN_FEATURE_SBBC: + return "cap-sbbc"; case VIR_DOMAIN_FEATURE_ACPI: case VIR_DOMAIN_FEATURE_APIC: case VIR_DOMAIN_FEATURE_PAE: @@ -7406,6 +7410,15 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, goto cleanup; break; + case VIR_DOMAIN_FEATURE_SBBC: + if (def->features[i] == VIR_DOMAIN_HWBUG_NONE) + break; + + value = virDomainHWBugTypeToString(def->features[i]); + if (qemuBuildMachineCommandLineFeature(&buf, i, value, qemuCaps) < 0) + goto cleanup; + break; + case VIR_DOMAIN_FEATURE_ACPI: case VIR_DOMAIN_FEATURE_APIC: case VIR_DOMAIN_FEATURE_PAE: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 906d64894..d7ce6ed65 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3273,6 +3273,16 @@ qemuDomainDefValidateFeatures(const virDomainDef *def) } break; + case VIR_DOMAIN_FEATURE_SBBC: + if (def->features[i] != VIR_DOMAIN_HWBUG_NONE && + !qemuDomainIsPSeries(def)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The '%s' feature is only supported for %s guests"), + featureName, "pSeries"); + return -1; + } + break; + case VIR_DOMAIN_FEATURE_ACPI: case VIR_DOMAIN_FEATURE_APIC: case VIR_DOMAIN_FEATURE_PAE: diff --git a/tests/qemuxml2argvdata/pseries-features-sbbc.args b/tests/qemuxml2argvdata/pseries-features-sbbc.args new file mode 100644 index 000000000..e619056b2 --- /dev/null +++ b/tests/qemuxml2argvdata/pseries-features-sbbc.args @@ -0,0 +1,19 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-ppc64 \ +-name guest \ +-S \ +-machine pseries,accel=tcg,cap-sbbc=broken \ +-m 512 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid 1ccfd97d-5eb4-478a-bbe6-88d254c16db7 \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-guest/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-boot c diff --git a/tests/qemuxml2argvdata/pseries-features-sbbc.xml b/tests/qemuxml2argvdata/pseries-features-sbbc.xml new file mode 100644 index 000000000..eac2c19ae --- /dev/null +++ b/tests/qemuxml2argvdata/pseries-features-sbbc.xml @@ -0,0 +1,28 @@ +<domain type='qemu'> + <name>guest</name> + <uuid>1ccfd97d-5eb4-478a-bbe6-88d254c16db7</uuid> + <memory unit='KiB'>524288</memory> + <currentMemory unit='KiB'>524288</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='ppc64' machine='pseries'>hvm</type> + <boot dev='hd'/> + </os> + <features> + <sbbc state='broken'/> + </features> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-ppc64</emulator> + <controller type='usb' index='0' model='none'/> + <controller type='pci' index='0' model='pci-root'> + <model name='spapr-pci-host-bridge'/> + <target index='0'/> + </controller> + <memballoon model='none'/> + <panic model='pseries'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 085e3a126..0aa4145f2 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1901,6 +1901,11 @@ mymain(void) QEMU_CAPS_MACHINE_PSERIES_CAP_HTM); DO_TEST_FAILURE("pseries-features-htm", QEMU_CAPS_MACHINE_OPT); + DO_TEST("pseries-features-sbbc", + QEMU_CAPS_MACHINE_OPT, + QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC); + DO_TEST_FAILURE("pseries-features-sbbc", + QEMU_CAPS_MACHINE_OPT); DO_TEST_PARSE_ERROR("pseries-features-invalid-machine", NONE); DO_TEST("pseries-serial-native", diff --git a/tests/qemuxml2xmloutdata/pseries-features-sbbc.xml b/tests/qemuxml2xmloutdata/pseries-features-sbbc.xml new file mode 120000 index 000000000..0bbe53221 --- /dev/null +++ b/tests/qemuxml2xmloutdata/pseries-features-sbbc.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/pseries-features-sbbc.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index a593a59e0..05610a273 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -769,6 +769,9 @@ mymain(void) DO_TEST("pseries-features-htm", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM); + DO_TEST("pseries-features-sbbc", + QEMU_CAPS_MACHINE_OPT, + QEMU_CAPS_MACHINE_PSERIES_CAP_SBBC); DO_TEST("pseries-serial-native", QEMU_CAPS_NODEFCONFIG, -- 2.14.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list