summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hmp-commands.hx28
-rw-r--r--hmp.c47
-rw-r--r--hmp.h2
-rw-r--r--hw/char/cadence_uart.c26
-rw-r--r--hw/core/qdev.c5
-rw-r--r--hw/i386/pc.c19
-rw-r--r--include/monitor/qdev.h1
-rw-r--r--memory.c2
-rw-r--r--monitor.c7
-rw-r--r--qdev-monitor.c57
-rwxr-xr-xscripts/qmp/qom-tree70
-rw-r--r--target-i386/cpu.c14
-rw-r--r--target-i386/cpu.h3
-rw-r--r--tests/Makefile2
-rw-r--r--tests/pc-cpu-test.c147
15 files changed, 397 insertions, 33 deletions
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 9c1e849859..328709dc8d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1674,6 +1674,32 @@ Add CPU with id @var{id}
ETEXI
{
+ .name = "qom-list",
+ .args_type = "path:s?",
+ .params = "path",
+ .help = "list QOM properties",
+ .mhandler.cmd = hmp_qom_list,
+ },
+
+STEXI
+@item qom-list [@var{path}]
+Print QOM properties of object at location @var{path}
+ETEXI
+
+ {
+ .name = "qom-set",
+ .args_type = "path:s,property:s,value:s",
+ .params = "path property value",
+ .help = "set QOM property",
+ .mhandler.cmd = hmp_qom_set,
+ },
+
+STEXI
+@item qom-set @var{path} @var{property} @var{value}
+Set QOM property @var{property} of object at location @var{path} to value @var{value}
+ETEXI
+
+ {
.name = "info",
.args_type = "item:s?",
.params = "[subcommand]",
@@ -1756,6 +1782,8 @@ show balloon information
show device tree
@item info qdm
show qdev device model list
+@item info qom-tree
+show object composition tree
@item info roms
show roms
@item info tpm
diff --git a/hmp.c b/hmp.c
index 7d5c81ed07..f31ae2796a 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1863,3 +1863,50 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
qapi_free_MemoryDeviceInfoList(info_list);
}
+
+void hmp_qom_list(Monitor *mon, const QDict *qdict)
+{
+ const char *path = qdict_get_try_str(qdict, "path");
+ ObjectPropertyInfoList *list;
+ Error *err = NULL;
+
+ if (path == NULL) {
+ monitor_printf(mon, "/\n");
+ return;
+ }
+
+ list = qmp_qom_list(path, &err);
+ if (err == NULL) {
+ ObjectPropertyInfoList *start = list;
+ while (list != NULL) {
+ ObjectPropertyInfo *value = list->value;
+
+ monitor_printf(mon, "%s (%s)\n",
+ value->name, value->type);
+ list = list->next;
+ }
+ qapi_free_ObjectPropertyInfoList(start);
+ }
+ hmp_handle_error(mon, &err);
+}
+
+void hmp_qom_set(Monitor *mon, const QDict *qdict)
+{
+ const char *path = qdict_get_str(qdict, "path");
+ const char *property = qdict_get_str(qdict, "property");
+ const char *value = qdict_get_str(qdict, "value");
+ Error *err = NULL;
+ bool ambiguous = false;
+ Object *obj;
+
+ obj = object_resolve_path(path, &ambiguous);
+ if (obj == NULL) {
+ error_set(&err, QERR_DEVICE_NOT_FOUND, path);
+ } else {
+ if (ambiguous) {
+ monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path);
+ }
+ object_property_parse(obj, value, property, &err);
+ }
+ hmp_handle_error(mon, &err);
+}
diff --git a/hmp.h b/hmp.h
index 371f8d45cd..2b9308be7c 100644
--- a/hmp.h
+++ b/hmp.h
@@ -96,6 +96,8 @@ void hmp_object_add(Monitor *mon, const QDict *qdict);
void hmp_object_del(Monitor *mon, const QDict *qdict);
void hmp_info_memdev(Monitor *mon, const QDict *qdict);
void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
+void hmp_qom_list(Monitor *mon, const QDict *qdict);
+void hmp_qom_set(Monitor *mon, const QDict *qdict);
void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 7044b357dc..a5dc2a4366 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -476,18 +476,12 @@ static void cadence_uart_reset(DeviceState *dev)
uart_update_status(s);
}
-static int cadence_uart_init(SysBusDevice *dev)
+static void cadence_uart_realize(DeviceState *dev, Error **errp)
{
UartState *s = CADENCE_UART(dev);
- memory_region_init_io(&s->iomem, OBJECT(s), &uart_ops, s, "uart", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
- sysbus_init_irq(dev, &s->irq);
-
s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
- (QEMUTimerCB *)fifo_trigger_update, s);
-
- s->char_tx_time = (get_ticks_per_sec() / 9600) * 10;
+ fifo_trigger_update, s);
s->chr = qemu_char_get_next_serial();
@@ -495,8 +489,18 @@ static int cadence_uart_init(SysBusDevice *dev)
qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive,
uart_event, s);
}
+}
- return 0;
+static void cadence_uart_init(Object *obj)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ UartState *s = CADENCE_UART(obj);
+
+ memory_region_init_io(&s->iomem, obj, &uart_ops, s, "uart", 0x1000);
+ sysbus_init_mmio(sbd, &s->iomem);
+ sysbus_init_irq(sbd, &s->irq);
+
+ s->char_tx_time = (get_ticks_per_sec() / 9600) * 10;
}
static int cadence_uart_post_load(void *opaque, int version_id)
@@ -528,9 +532,8 @@ static const VMStateDescription vmstate_cadence_uart = {
static void cadence_uart_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
- sdc->init = cadence_uart_init;
+ dc->realize = cadence_uart_realize;
dc->vmsd = &vmstate_cadence_uart;
dc->reset = cadence_uart_reset;
}
@@ -539,6 +542,7 @@ static const TypeInfo cadence_uart_info = {
.name = TYPE_CADENCE_UART,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(UartState),
+ .instance_init = cadence_uart_init,
.class_init = cadence_uart_class_init,
};
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 6be58669f7..6e6a65d49b 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -501,8 +501,9 @@ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
* with an error without doing anything. If it has none, it will
* never fail. So we can just call it with a NULL Error pointer.
*/
- object_property_add_child(qdev_get_machine(), "non-qdev-gpio[*]",
- OBJECT(pin), NULL);
+ object_property_add_child(container_get(qdev_get_machine(),
+ "/unattached"),
+ "non-qdev-gpio[*]", OBJECT(pin), NULL);
}
object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
g_free(propname);
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/include/monitor/qdev.h b/include/monitor/qdev.h
index 5eb4a1171e..719075283c 100644
--- a/include/monitor/qdev.h
+++ b/include/monitor/qdev.h
@@ -8,6 +8,7 @@
void hmp_info_qtree(Monitor *mon, const QDict *qdict);
void hmp_info_qdm(Monitor *mon, const QDict *qdict);
+void hmp_info_qom_tree(Monitor *mon, const QDict *dict);
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
int qdev_device_help(QemuOpts *opts);
DeviceState *qdev_device_add(QemuOpts *opts);
diff --git a/memory.c b/memory.c
index 20f6d9eeac..ee3f2a8a95 100644
--- a/memory.c
+++ b/memory.c
@@ -868,7 +868,7 @@ void memory_region_init(MemoryRegion *mr,
uint64_t size)
{
if (!owner) {
- owner = qdev_get_machine();
+ owner = container_get(qdev_get_machine(), "/unattached");
}
object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION);
diff --git a/monitor.c b/monitor.c
index 8b703f97be..42116a942e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2890,6 +2890,13 @@ static mon_cmd_t info_cmds[] = {
.mhandler.cmd = hmp_info_qdm,
},
{
+ .name = "qom-tree",
+ .args_type = "path:s?",
+ .params = "[path]",
+ .help = "show QOM composition tree",
+ .mhandler.cmd = hmp_info_qom_tree,
+ },
+ {
.name = "roms",
.args_type = "",
.params = "",
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 5d30ac534c..1d87f573e8 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -678,6 +678,63 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict)
qdev_print_devinfos(true);
}
+typedef struct QOMCompositionState {
+ Monitor *mon;
+ int indent;
+} QOMCompositionState;
+
+static void print_qom_composition(Monitor *mon, Object *obj, int indent);
+
+static int print_qom_composition_child(Object *obj, void *opaque)
+{
+ QOMCompositionState *s = opaque;
+
+ print_qom_composition(s->mon, obj, s->indent);
+
+ return 0;
+}
+
+static void print_qom_composition(Monitor *mon, Object *obj, int indent)
+{
+ QOMCompositionState s = {
+ .mon = mon,
+ .indent = indent + 2,
+ };
+ char *name;
+
+ if (obj == object_get_root()) {
+ name = g_strdup("");
+ } else {
+ name = object_get_canonical_path_component(obj);
+ }
+ monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
+ object_get_typename(obj));
+ g_free(name);
+ object_child_foreach(obj, print_qom_composition_child, &s);
+}
+
+void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
+{
+ const char *path = qdict_get_try_str(dict, "path");
+ Object *obj;
+ bool ambiguous = false;
+
+ if (path) {
+ obj = object_resolve_path(path, &ambiguous);
+ if (!obj) {
+ monitor_printf(mon, "Path '%s' could not be resolved.\n", path);
+ return;
+ }
+ if (ambiguous) {
+ monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path);
+ return;
+ }
+ } else {
+ obj = qdev_get_machine();
+ }
+ print_qom_composition(mon, obj, 0);
+}
+
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
Error *local_err = NULL;
diff --git a/scripts/qmp/qom-tree b/scripts/qmp/qom-tree
new file mode 100755
index 0000000000..aea11d4b1a
--- /dev/null
+++ b/scripts/qmp/qom-tree
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+##
+# QEMU Object Model test tools
+#
+# Copyright IBM, Corp. 2011
+# Copyright (c) 2013 SUSE LINUX Products GmbH
+#
+# Authors:
+# Anthony Liguori <aliguori@amazon.com>
+# Andreas Faerber <afaerber@suse.de>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later. See
+# the COPYING file in the top-level directory.
+##
+
+import sys
+import os
+from qmp import QEMUMonitorProtocol
+
+cmd, args = sys.argv[0], sys.argv[1:]
+socket_path = None
+path = None
+prop = None
+
+def usage():
+ return '''environment variables:
+ QMP_SOCKET=<path | addr:port>
+usage:
+ %s [-h] [-s <QMP socket path | addr:port>] [<path>]
+''' % cmd
+
+def usage_error(error_msg = "unspecified error"):
+ sys.stderr.write('%s\nERROR: %s\n' % (usage(), error_msg))
+ exit(1)
+
+if len(args) > 0:
+ if args[0] == "-h":
+ print usage()
+ exit(0);
+ elif args[0] == "-s":
+ try:
+ socket_path = args[1]
+ except:
+ usage_error("missing argument: QMP socket path or address");
+ args = args[2:]
+
+if not socket_path:
+ if os.environ.has_key('QMP_SOCKET'):
+ socket_path = os.environ['QMP_SOCKET']
+ else:
+ usage_error("no QMP socket path or address given");
+
+srv = QEMUMonitorProtocol(socket_path)
+srv.connect()
+
+def list_node(path):
+ print '%s' % path
+ items = srv.command('qom-list', path=path)
+ for item in items:
+ if not item['type'].startswith('child<'):
+ try:
+ print ' %s: %s (%s)' % (item['name'], srv.command('qom-get', path=path, property=item['name']), item['type'])
+ except:
+ print ' %s: <EXCEPTION> (%s)' % (item['name'], item['type'])
+ print ''
+ for item in items:
+ if item['type'].startswith('child<'):
+ list_node(path + '/' + item['name'])
+
+list_node('/machine')
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();
+}