diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-03-17 16:19:12 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-03-17 16:19:13 +0000 |
commit | ac738eadc409813c5fbb37dae8d254cb5664733a (patch) | |
tree | 6fe608edd1bfb22f1d9480449db54db579c0db40 | |
parent | 1a87e52770ca64f5a09e9c46d29ea3b5a5db5ffd (diff) | |
parent | e1570d0005f29f97d4b1d603b4548591340c57e1 (diff) |
Merge remote-tracking branch 'remotes/afaerber/tags/qom-cpu-for-peter' into staging
QOM CPUState and X86CPU
* QTest for PC X86CPU
* Confinement of ICC bridge X86CPU parenting to PC code
# gpg: Signature made Tue Mar 17 15:23:31 2015 GMT using RSA key ID 3E7E013F
# gpg: Good signature from "Andreas Färber <afaerber@suse.de>"
# gpg: aka "Andreas Färber <afaerber@suse.com>"
* remotes/afaerber/tags/qom-cpu-for-peter:
target-i386: Remove icc_bridge parameter from cpu_x86_create()
tests: Add PC CPU test
pc: Suppress APIC ID compatibility warning for QTest
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/i386/pc.c | 19 | ||||
-rw-r--r-- | target-i386/cpu.c | 14 | ||||
-rw-r--r-- | target-i386/cpu.h | 3 | ||||
-rw-r--r-- | tests/Makefile | 2 | ||||
-rw-r--r-- | tests/pc-cpu-test.c | 147 |
5 files changed, 166 insertions, 19 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b5b2aadb52..4b46c299c3 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -45,6 +45,7 @@ #include "sysemu/sysemu.h" #include "sysemu/numa.h" #include "sysemu/kvm.h" +#include "sysemu/qtest.h" #include "kvm_i386.h" #include "hw/xen/xen.h" #include "sysemu/block-backend.h" @@ -653,7 +654,7 @@ static uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index) correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index); if (compat_apic_id_mode) { - if (cpu_index != correct_id && !warned) { + if (cpu_index != correct_id && !warned && !qtest_enabled()) { error_report("APIC IDs set in compatibility mode, " "CPU topology won't match the configuration"); warned = true; @@ -992,18 +993,26 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id, DeviceState *icc_bridge, Error **errp) { - X86CPU *cpu; + X86CPU *cpu = NULL; Error *local_err = NULL; - cpu = cpu_x86_create(cpu_model, icc_bridge, &local_err); + if (icc_bridge == NULL) { + error_setg(&local_err, "Invalid icc-bridge value"); + goto out; + } + + cpu = cpu_x86_create(cpu_model, &local_err); if (local_err != NULL) { - error_propagate(errp, local_err); - return NULL; + goto out; } + qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); + object_unref(OBJECT(cpu)); + object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); +out: if (local_err) { error_propagate(errp, local_err); object_unref(OBJECT(cpu)); diff --git a/target-i386/cpu.c b/target-i386/cpu.c index ed7e5d5de3..f01690bfea 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2076,8 +2076,7 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp) } -X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge, - Error **errp) +X86CPU *cpu_x86_create(const char *cpu_model, Error **errp) { X86CPU *cpu = NULL; X86CPUClass *xcc; @@ -2108,15 +2107,6 @@ X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge, cpu = X86_CPU(object_new(object_class_get_name(oc))); -#ifndef CONFIG_USER_ONLY - if (icc_bridge == NULL) { - error_setg(&error, "Invalid icc-bridge value"); - goto out; - } - qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc")); - object_unref(OBJECT(cpu)); -#endif - x86_cpu_parse_featurestr(CPU(cpu), features, &error); if (error) { goto out; @@ -2139,7 +2129,7 @@ X86CPU *cpu_x86_init(const char *cpu_model) Error *error = NULL; X86CPU *cpu; - cpu = cpu_x86_create(cpu_model, NULL, &error); + cpu = cpu_x86_create(cpu_model, &error); if (error) { goto out; } diff --git a/target-i386/cpu.h b/target-i386/cpu.h index e4c27b1fa8..15db6d7aba 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -982,8 +982,7 @@ typedef struct CPUX86State { #include "cpu-qom.h" X86CPU *cpu_x86_init(const char *cpu_model); -X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge, - Error **errp); +X86CPU *cpu_x86_create(const char *cpu_model, Error **errp); int cpu_x86_exec(CPUX86State *s); void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf); void x86_cpudef_setup(void); diff --git a/tests/Makefile b/tests/Makefile index 1ef95c95cb..55aa7452b4 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -173,6 +173,7 @@ gcov-files-i386-y += hw/usb/dev-hid.c gcov-files-i386-y += hw/usb/dev-storage.c check-qtest-i386-y += tests/usb-hcd-xhci-test$(EXESUF) gcov-files-i386-y += hw/usb/hcd-xhci.c +check-qtest-i386-y += tests/pc-cpu-test$(EXESUF) check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF) check-qtest-x86_64-y = $(check-qtest-i386-y) gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c @@ -363,6 +364,7 @@ tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y) tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o $(libqos-usb-obj-y) tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y) tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y) +tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y) tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o libqemuutil.a libqemustub.a diff --git a/tests/pc-cpu-test.c b/tests/pc-cpu-test.c new file mode 100644 index 0000000000..a0122d3d61 --- /dev/null +++ b/tests/pc-cpu-test.c @@ -0,0 +1,147 @@ +/* + * QTest testcase for PC CPUs + * + * Copyright (c) 2015 SUSE Linux GmbH + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include <glib.h> +#include <string.h> + +#include "qemu-common.h" +#include "libqtest.h" +#include "qemu/osdep.h" +#include "qapi/qmp/types.h" + +struct PCTestData { + const char *machine; + const char *cpu_model; + unsigned sockets; + unsigned cores; + unsigned threads; + unsigned maxcpus; +}; +typedef struct PCTestData PCTestData; + +static void test_pc_with_cpu_add(gconstpointer data) +{ + const PCTestData *s = data; + char *args; + QDict *response; + unsigned int i; + + args = g_strdup_printf("-machine %s -cpu %s " + "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u", + s->machine, s->cpu_model, + s->sockets, s->cores, s->threads, s->maxcpus); + qtest_start(args); + + for (i = s->sockets * s->cores * s->threads; i < s->maxcpus; i++) { + response = qmp("{ 'execute': 'cpu-add'," + " 'arguments': { 'id': %d } }", i); + g_assert(response); + g_assert(!qdict_haskey(response, "error")); + QDECREF(response); + } + + qtest_end(); + g_free(args); +} + +static void test_pc_without_cpu_add(gconstpointer data) +{ + const PCTestData *s = data; + char *args; + QDict *response; + + args = g_strdup_printf("-machine %s -cpu %s " + "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u", + s->machine, s->cpu_model, + s->sockets, s->cores, s->threads, s->maxcpus); + qtest_start(args); + + response = qmp("{ 'execute': 'cpu-add'," + " 'arguments': { 'id': %d } }", + s->sockets * s->cores * s->threads); + g_assert(response); + g_assert(qdict_haskey(response, "error")); + QDECREF(response); + + qtest_end(); + g_free(args); +} + +static void add_pc_test_cases(void) +{ + const char *arch = qtest_get_arch(); + QDict *response, *minfo; + QList *list; + const QListEntry *p; + QObject *qobj; + QString *qstr; + const char *mname, *path; + PCTestData *data; + + qtest_start("-machine none"); + response = qmp("{ 'execute': 'query-machines' }"); + g_assert(response); + list = qdict_get_qlist(response, "return"); + g_assert(list); + + for (p = qlist_first(list); p; p = qlist_next(p)) { + minfo = qobject_to_qdict(qlist_entry_obj(p)); + g_assert(minfo); + qobj = qdict_get(minfo, "name"); + g_assert(qobj); + qstr = qobject_to_qstring(qobj); + g_assert(qstr); + mname = qstring_get_str(qstr); + if (!g_str_has_prefix(mname, "pc-")) { + continue; + } + data = g_malloc(sizeof(PCTestData)); + data->machine = mname; + data->cpu_model = "Haswell"; /* 1.3+ theoretically */ + data->sockets = 1; + data->cores = 3; + data->threads = 2; + data->maxcpus = data->sockets * data->cores * data->threads * 2; + if (g_str_has_suffix(mname, "-1.4") || + (strcmp(mname, "pc-1.3") == 0) || + (strcmp(mname, "pc-1.2") == 0) || + (strcmp(mname, "pc-1.1") == 0) || + (strcmp(mname, "pc-1.0") == 0) || + (strcmp(mname, "pc-0.15") == 0) || + (strcmp(mname, "pc-0.14") == 0) || + (strcmp(mname, "pc-0.13") == 0) || + (strcmp(mname, "pc-0.12") == 0) || + (strcmp(mname, "pc-0.11") == 0) || + (strcmp(mname, "pc-0.10") == 0)) { + path = g_strdup_printf("/%s/cpu/%s/init/%ux%ux%u&maxcpus=%u", + arch, mname, data->sockets, data->cores, + data->threads, data->maxcpus); + g_test_add_data_func(path, data, test_pc_without_cpu_add); + } else { + path = g_strdup_printf("/%s/cpu/%s/add/%ux%ux%u&maxcpus=%u", + arch, mname, data->sockets, data->cores, + data->threads, data->maxcpus); + g_test_add_data_func(path, data, test_pc_with_cpu_add); + } + } + qtest_end(); +} + +int main(int argc, char **argv) +{ + const char *arch = qtest_get_arch(); + + g_test_init(&argc, &argv, NULL); + + if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { + add_pc_test_cases(); + } + + return g_test_run(); +} |