From: Jiri Denemark Date: Mon, 25 Aug 2025 14:36:01 +0000 (+0200) Subject: qemu: Drop legacy probing of CPU features X-Git-Tag: v11.8.0-rc1~100 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cab77b7a1481ba21ad29977385ea50017b205e91;p=thirdparty%2Flibvirt.git qemu: Drop legacy probing of CPU features The legacy probing which reads CPUID registers from QEMU and interprets the individual bits is not used with any QEMU version currently supported by libvirt. The code would only be used if QEMU_CAPS_CPU_UNAVAILABLE_FEATURES capability (detected by probing the presence of 'unavailable-features') was missing on x86, but all QEMU release we care about report unavailable-features on x86. Signed-off-by: Jiri Denemark Reviewed-by: Peter Krempa Reviewed-by: Ján Tomko --- diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 1f5b4ec215..0213bd5af8 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3669,36 +3669,6 @@ qemuMonitorSetDomainLog(qemuMonitor *mon, } -/** - * qemuMonitorJSONGetGuestCPUx86: - * @mon: Pointer to the monitor - * @cpuQOMPath: QOM path of a CPU to probe - * @data: returns the cpu data - * @disabled: returns the CPU data for features which were disabled by QEMU - * - * Retrieve the definition of the guest CPU from a running qemu instance. - * - * Returns 0 on success, -2 if the operation is not supported by the guest, - * -1 on other errors. - */ -int -qemuMonitorGetGuestCPUx86(qemuMonitor *mon, - const char *cpuQOMPath, - virCPUData **data, - virCPUData **disabled) -{ - VIR_DEBUG("cpuQOMPath=%s data=%p disabled=%p", cpuQOMPath, data, disabled); - - QEMU_CHECK_MONITOR(mon); - - *data = NULL; - if (disabled) - *disabled = NULL; - - return qemuMonitorJSONGetGuestCPUx86(mon, cpuQOMPath, data, disabled); -} - - /** * qemuMonitorGetGuestCPU: * @mon: Pointer to the monitor diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index a2ba5882f6..689a587ec6 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1263,11 +1263,6 @@ void qemuMonitorSetDomainLog(qemuMonitor *mon, void *opaque, virFreeCallback destroy); -int qemuMonitorGetGuestCPUx86(qemuMonitor *mon, - const char *cpuQOMPath, - virCPUData **data, - virCPUData **disabled); - typedef const char *(*qemuMonitorCPUFeatureTranslationCallback)(virArch arch, const char *name); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 0e5a9d3b4f..6402d18d37 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6578,197 +6578,6 @@ qemuMonitorJSONGetDeviceAliases(qemuMonitor *mon, } -static int -qemuMonitorJSONParseCPUx86FeatureWord(virJSONValue *data, - virCPUx86CPUID *cpuid) -{ - const char *reg; - unsigned long long eax_in; - unsigned long long ecx_in = 0; - unsigned long long features; - - memset(cpuid, 0, sizeof(*cpuid)); - - if (!(reg = virJSONValueObjectGetString(data, "cpuid-register"))) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("missing cpuid-register in CPU data")); - return -1; - } - if (virJSONValueObjectGetNumberUlong(data, "cpuid-input-eax", &eax_in) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("missing or invalid cpuid-input-eax in CPU data")); - return -1; - } - ignore_value(virJSONValueObjectGetNumberUlong(data, "cpuid-input-ecx", - &ecx_in)); - if (virJSONValueObjectGetNumberUlong(data, "features", &features) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("missing or invalid features in CPU data")); - return -1; - } - - cpuid->eax_in = eax_in; - cpuid->ecx_in = ecx_in; - if (STREQ(reg, "EAX")) { - cpuid->eax = features; - } else if (STREQ(reg, "EBX")) { - cpuid->ebx = features; - } else if (STREQ(reg, "ECX")) { - cpuid->ecx = features; - } else if (STREQ(reg, "EDX")) { - cpuid->edx = features; - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unknown CPU register '%1$s'"), reg); - return -1; - } - - return 0; -} - - -static virCPUData * -qemuMonitorJSONParseCPUx86Features(virJSONValue *data) -{ - g_autoptr(virCPUData) cpudata = NULL; - virCPUx86DataItem item = { 0 }; - size_t i; - - if (!(cpudata = virCPUDataNew(VIR_ARCH_X86_64))) - return NULL; - - item.type = VIR_CPU_X86_DATA_CPUID; - for (i = 0; i < virJSONValueArraySize(data); i++) { - if (qemuMonitorJSONParseCPUx86FeatureWord(virJSONValueArrayGet(data, i), - &item.data.cpuid) < 0) { - return NULL; - } - - virCPUx86DataAdd(cpudata, &item); - } - - return g_steal_pointer(&cpudata); -} - - -static int -qemuMonitorJSONGetCPUx86Data(qemuMonitor *mon, - const char *cpuQOMPath, - const char *property, - virCPUData **cpudata) -{ - g_autoptr(virJSONValue) cmd = NULL; - g_autoptr(virJSONValue) reply = NULL; - virJSONValue *data; - - if (!(cmd = qemuMonitorJSONMakeCommand("qom-get", - "s:path", cpuQOMPath, - "s:property", property, - NULL))) - return -1; - - if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) - return -1; - - if (!(data = qemuMonitorJSONGetReply(cmd, reply, VIR_JSON_TYPE_ARRAY))) - return -1; - - if (!(*cpudata = qemuMonitorJSONParseCPUx86Features(data))) - return -1; - - return 0; -} - - -/* - * Returns -1 on error, 0 if QEMU does not support reporting CPUID features - * of a guest CPU, and 1 if the feature is supported. - */ -static int -qemuMonitorJSONCheckCPUx86(qemuMonitor *mon, - const char *cpuQOMPath) -{ - g_autoptr(virJSONValue) cmd = NULL; - g_autoptr(virJSONValue) reply = NULL; - virJSONValue *data; - size_t i; - size_t n; - - if (!(cmd = qemuMonitorJSONMakeCommand("qom-list", - "s:path", cpuQOMPath, - NULL))) - return -1; - - if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) - return -1; - - if ((data = virJSONValueObjectGet(reply, "error"))) { - const char *klass = virJSONValueObjectGetString(data, "class"); - if (STREQ_NULLABLE(klass, "DeviceNotFound") || - STREQ_NULLABLE(klass, "CommandNotFound")) { - return 0; - } - } - - if (!(data = qemuMonitorJSONGetReply(cmd, reply, VIR_JSON_TYPE_ARRAY))) - return -1; - - n = virJSONValueArraySize(data); - - for (i = 0; i < n; i++) { - virJSONValue *element = virJSONValueArrayGet(data, i); - if (STREQ_NULLABLE(virJSONValueObjectGetString(element, "name"), - "feature-words")) - return 1; - } - - return 0; -} - - -/** - * qemuMonitorJSONGetGuestCPUx86: - * @mon: Pointer to the monitor - * @cpuQOMPath: QOM path of a CPU to probe - * @data: returns the cpu data of the guest - * @disabled: returns the CPU data for features which were disabled by QEMU - * - * Retrieve the definition of the guest CPU from a running qemu instance. - * - * Returns 0 on success, -2 if guest doesn't support this feature, - * -1 on other errors. - */ -int -qemuMonitorJSONGetGuestCPUx86(qemuMonitor *mon, - const char *cpuQOMPath, - virCPUData **data, - virCPUData **disabled) -{ - g_autoptr(virCPUData) cpuEnabled = NULL; - g_autoptr(virCPUData) cpuDisabled = NULL; - int rc; - - if ((rc = qemuMonitorJSONCheckCPUx86(mon, cpuQOMPath)) < 0) - return -1; - else if (!rc) - return -2; - - if (qemuMonitorJSONGetCPUx86Data(mon, cpuQOMPath, "feature-words", - &cpuEnabled) < 0) - return -1; - - if (disabled && - qemuMonitorJSONGetCPUx86Data(mon, cpuQOMPath, "filtered-features", - &cpuDisabled) < 0) - return -1; - - *data = g_steal_pointer(&cpuEnabled); - if (disabled) - *disabled = g_steal_pointer(&cpuDisabled); - return 0; -} - - static int qemuMonitorJSONGetCPUProperties(qemuMonitor *mon, const char *cpuQOMPath, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index f076e637ba..62050470e8 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -558,12 +558,6 @@ int qemuMonitorJSONGetDeviceAliases(qemuMonitor *mon, char ***aliases); -int -qemuMonitorJSONGetGuestCPUx86(qemuMonitor *mon, - const char *cpuQOMPath, - virCPUData **data, - virCPUData **disabled); - int qemuMonitorJSONGetGuestCPU(qemuMonitor *mon, virArch arch, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 059834648d..2988ffb157 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4579,29 +4579,22 @@ qemuProcessFetchGuestCPU(virDomainObj *vm, g_autoptr(virCPUData) dataEnabled = NULL; g_autoptr(virCPUData) dataDisabled = NULL; const char *cpuQOMPath = qemuProcessGetVCPUQOMPath(vm); - bool generic; int rc; *enabled = NULL; *disabled = NULL; - generic = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES); - - if (!generic && !ARCH_IS_X86(vm->def->os.arch)) + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CPU_UNAVAILABLE_FEATURES)) return 0; if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) return -1; - if (generic) { - rc = qemuMonitorGetGuestCPU(priv->mon, - vm->def->os.arch, - cpuQOMPath, - virQEMUCapsCPUFeatureFromQEMU, - &dataEnabled, &dataDisabled); - } else { - rc = qemuMonitorGetGuestCPUx86(priv->mon, cpuQOMPath, &dataEnabled, &dataDisabled); - } + rc = qemuMonitorGetGuestCPU(priv->mon, + vm->def->os.arch, + cpuQOMPath, + virQEMUCapsCPUFeatureFromQEMU, + &dataEnabled, &dataDisabled); qemuDomainObjExitMonitor(vm); diff --git a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-ecx.data b/tests/qemumonitorjsondata/qemumonitorjson-getcpu-ecx.data deleted file mode 100644 index 457bbbe339..0000000000 --- a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-ecx.data +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-ecx.json b/tests/qemumonitorjsondata/qemumonitorjson-getcpu-ecx.json deleted file mode 100644 index 9eca2dec11..0000000000 --- a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-ecx.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "return": [ - { - "cpuid-register": "EAX", - "cpuid-input-ecx": 1, - "cpuid-input-eax": 13, - "features": 1 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 2147483658, - "features": 0 - }, - { - "cpuid-register": "EAX", - "cpuid-input-eax": 1073741825, - "features": 16777467 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 3221225473, - "features": 0 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 2147483655, - "features": 0 - }, - { - "cpuid-register": "ECX", - "cpuid-input-eax": 2147483649, - "features": 289 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 2147483649, - "features": 739248128 - }, - { - "cpuid-register": "EBX", - "cpuid-input-ecx": 0, - "cpuid-input-eax": 7, - "features": 1839035 - }, - { - "cpuid-register": "ECX", - "cpuid-input-eax": 1, - "features": 4160369155 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 1, - "features": 260832255 - } - ], - "id": "feature-words" -} diff --git a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.data b/tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.data deleted file mode 100644 index b581821060..0000000000 --- a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.data +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.json b/tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.json deleted file mode 100644 index 29c00b4c95..0000000000 --- a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-full.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "return": [ - { - "cpuid-register": "EDX", - "cpuid-input-eax": 2147483658, - "features": 0 - }, - { - "cpuid-register": "EAX", - "cpuid-input-eax": 1073741825, - "features": 16777275 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 3221225473, - "features": 0 - }, - { - "cpuid-register": "ECX", - "cpuid-input-eax": 2147483649, - "features": 1 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 2147483649, - "features": 672139264 - }, - { - "cpuid-register": "EBX", - "cpuid-input-ecx": 0, - "cpuid-input-eax": 7, - "features": 0 - }, - { - "cpuid-register": "ECX", - "cpuid-input-eax": 1, - "features": 2545558051 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 1, - "features": 126614525 - } - ], - "id": "libvirt-6" -} diff --git a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.data b/tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.data deleted file mode 100644 index a4c503e201..0000000000 --- a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.data +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.json b/tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.json deleted file mode 100644 index b5fb9f3778..0000000000 --- a/tests/qemumonitorjsondata/qemumonitorjson-getcpu-host.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "return": [ - { - "cpuid-register": "EDX", - "cpuid-input-eax": 2147483658, - "features": 0 - }, - { - "cpuid-register": "EAX", - "cpuid-input-eax": 1073741825, - "features": 16777339 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 3221225473, - "features": 0 - }, - { - "cpuid-register": "ECX", - "cpuid-input-eax": 2147483649, - "features": 1 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 2147483649, - "features": 697564159 - }, - { - "cpuid-register": "EBX", - "cpuid-input-ecx": 0, - "cpuid-input-eax": 7, - "features": 2 - }, - { - "cpuid-register": "ECX", - "cpuid-input-eax": 1, - "features": 2545558051 - }, - { - "cpuid-register": "EDX", - "cpuid-input-eax": 1, - "features": 260832255 - } - ] -} diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 65b14ca318..7d128b6876 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -30,7 +30,6 @@ #include "qemu/qemu_alias.h" #include "qemu/qemu_chardev.h" #include "virerror.h" -#include "cpu/cpu.h" #include "qemu/qemu_monitor.h" #include "qemu/qemu_migration_params.h" #define LIBVIRT_QEMU_MIGRATION_PARAMSPRIV_H_ALLOW @@ -2109,108 +2108,6 @@ testQemuMonitorJSONqemuMonitorJSONGetDumpGuestMemoryCapability(const void *opaqu return 0; } -struct testCPUData { - const char *name; - virDomainXMLOption *xmlopt; - GHashTable *schema; -}; - - -static int -testQemuMonitorJSONGetCPUData(const void *opaque) -{ - const struct testCPUData *data = opaque; - g_autoptr(virCPUData) cpuData = NULL; - g_autofree char *jsonFile = NULL; - g_autofree char *dataFile = NULL; - g_autofree char *jsonStr = NULL; - g_autofree char *actual = NULL; - g_autoptr(qemuMonitorTest) test = NULL; - - if (!(test = qemuMonitorTestNewSchema(data->xmlopt, data->schema))) - return -1; - - jsonFile = g_strdup_printf("%s/qemumonitorjsondata/qemumonitorjson-getcpu-%s.json", - abs_srcdir, data->name); - dataFile = g_strdup_printf("%s/qemumonitorjsondata/qemumonitorjson-getcpu-%s.data", - abs_srcdir, data->name); - - if (virTestLoadFile(jsonFile, &jsonStr) < 0) - return -1; - - if (qemuMonitorTestAddItem(test, "qom-list", - "{" - " \"return\": [" - " {" - " \"name\": \"filtered-features\"," - " \"type\": \"X86CPUFeatureWordInfo\"" - " }," - " {" - " \"name\": \"feature-words\"," - " \"type\": \"X86CPUFeatureWordInfo\"" - " }" - " ]," - " \"id\": \"libvirt-19\"" - "}") < 0) - return -1; - - if (qemuMonitorTestAddItem(test, "qom-get", jsonStr) < 0) - return -1; - - if (qemuMonitorJSONGetGuestCPUx86(qemuMonitorTestGetMonitor(test), - "dummy", - &cpuData, NULL) < 0) - return -1; - - if (!(actual = virCPUDataFormat(cpuData))) - return -1; - - if (virTestCompareToFile(actual, dataFile) < 0) - return -1; - - return 0; -} - -static int -testQemuMonitorJSONGetNonExistingCPUData(const void *opaque) -{ - const testGenericData *data = opaque; - virDomainXMLOption *xmlopt = data->xmlopt; - g_autoptr(virCPUData) cpuData = NULL; - int rv; - g_autoptr(qemuMonitorTest) test = NULL; - - if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema))) - return -1; - - if (qemuMonitorTestAddItem(test, "qom-list", - "{" - " \"id\": \"libvirt-7\"," - " \"error\": {" - " \"class\": \"CommandNotFound\"," - " \"desc\": \"The command qom-list has not been found\"" - " }" - "}") < 0) - return -1; - - rv = qemuMonitorJSONGetGuestCPUx86(qemuMonitorTestGetMonitor(test), - "dummy", - &cpuData, NULL); - if (rv != -2) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "Unexpected return value %d, expecting -2", rv); - return -1; - } - - if (cpuData) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "Unexpected allocation of data = %p, expecting NULL", - cpuData); - return -1; - } - - return 0; -} static int testQemuMonitorJSONGetIOThreads(const void *opaque) @@ -2924,14 +2821,6 @@ mymain(void) #define DO_TEST_GEN_DEPRECATED(name, removed, ...) \ DO_TEST_GEN_FULL(name, true, removed, __VA_ARGS__) -#define DO_TEST_CPU_DATA(name) \ - do { \ - struct testCPUData data = { name, driver.xmlopt, qapiData.schema }; \ - const char *label = "GetCPUData(" name ")"; \ - if (virTestRun(label, testQemuMonitorJSONGetCPUData, &data) < 0) \ - ret = -1; \ - } while (0) - #define DO_TEST_CPU_INFO(name, maxvcpus) \ do { \ struct testCPUInfoData data = {name, maxvcpus, driver.xmlopt, \ @@ -2953,7 +2842,6 @@ mymain(void) DO_TEST(SetObjectProperty); DO_TEST(GetDeviceAliases); DO_TEST(CPU); - DO_TEST(GetNonExistingCPUData); DO_TEST(GetIOThreads); DO_TEST(GetSEVInfo); DO_TEST(Transaction); @@ -3015,10 +2903,6 @@ mymain(void) DO_TEST(qemuMonitorJSONSnapshot); DO_TEST(qemuMonitorJSONBlockdevSetActive); - DO_TEST_CPU_DATA("host"); - DO_TEST_CPU_DATA("full"); - DO_TEST_CPU_DATA("ecx"); - DO_TEST_CPU_INFO("x86-basic-pluggable", 8); DO_TEST_CPU_INFO("x86-full", 11); DO_TEST_CPU_INFO("x86-node-full", 8);