From b4510bb4109f5fad478fb238b0ab11be7d2bc2fd Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 30 Aug 2019 07:07:22 -0400 Subject: [PATCH 01/18] tests: add qtest_qmp_device_add_qdict() helper Add an API that takes QDict directly, so users could skip steps of first building json dictionary and converting it back to QDict in existing qtest_qmp_device_add() and instead use QDict directly without intermediate conversion. Signed-off-by: Igor Mammedov Message-Id: <20190830110723.15096-2-imammedo@redhat.com> Signed-off-by: Eduardo Habkost --- tests/libqtest.c | 29 +++++++++++++++++++---------- tests/libqtest.h | 12 ++++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/tests/libqtest.c b/tests/libqtest.c index 38e4f5b587..3706bccd8d 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -1243,28 +1243,37 @@ QDict *qtest_qmp_receive_success(QTestState *s, } /* - * Generic hot-plugging test via the device_add QMP command. + * Generic hot-plugging test via the device_add QMP commands. */ +void qtest_qmp_device_add_qdict(QTestState *qts, const char *drv, + const QDict *arguments) +{ + QDict *resp; + QDict *args = arguments ? qdict_clone_shallow(arguments) : qdict_new(); + + g_assert(!qdict_haskey(args, "driver")); + qdict_put_str(args, "driver", drv); + resp = qtest_qmp(qts, "{'execute': 'device_add', 'arguments': %p}", args); + g_assert(resp); + g_assert(!qdict_haskey(resp, "event")); /* We don't expect any events */ + g_assert(!qdict_haskey(resp, "error")); + qobject_unref(resp); +} + void qtest_qmp_device_add(QTestState *qts, const char *driver, const char *id, const char *fmt, ...) { - QDict *args, *response; + QDict *args; va_list ap; va_start(ap, fmt); args = qdict_from_vjsonf_nofail(fmt, ap); va_end(ap); - g_assert(!qdict_haskey(args, "driver") && !qdict_haskey(args, "id")); - qdict_put_str(args, "driver", driver); + g_assert(!qdict_haskey(args, "id")); qdict_put_str(args, "id", id); - response = qtest_qmp(qts, "{'execute': 'device_add', 'arguments': %p}", - args); - g_assert(response); - g_assert(!qdict_haskey(response, "event")); /* We don't expect any events */ - g_assert(!qdict_haskey(response, "error")); - qobject_unref(response); + qtest_qmp_device_add_qdict(qts, driver, args); } static void device_deleted_cb(void *opaque, const char *name, QDict *data) diff --git a/tests/libqtest.h b/tests/libqtest.h index a177e502d9..c9e21e05b3 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -659,6 +659,18 @@ QDict *qmp_fd(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3); void qtest_cb_for_every_machine(void (*cb)(const char *machine), bool skip_old_versioned); +/** + * qtest_qmp_device_add_qdict: + * @qts: QTestState instance to operate on + * @drv: Name of the device that should be added + * @arguments: QDict with properties for the device to intialize + * + * Generic hot-plugging test via the device_add QMP command with properties + * supplied in form of QDict. Use NULL for empty properties list. + */ +void qtest_qmp_device_add_qdict(QTestState *qts, const char *drv, + const QDict *arguments); + /** * qtest_qmp_device_add: * @qts: QTestState instance to operate on From 021a007efc31d99416335f73a3c8f1b9183e0047 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 30 Aug 2019 07:07:23 -0400 Subject: [PATCH 02/18] tests: cpu-plug-test: fix device_add for pc/q35 machines Commit bc1fb850a3 silently broke device_add test for CPU hotplug which resulted in test successfully passing though it wasn't actually run. Fix it by making sure that all non present CPUs reported by "query-hotpluggable-cpus" are hotplugged instead of making up and hardcoding values. Use of query-hotpluggable-cpus also allows consolidatiate device_add cpu testcases and reuse the same test function for all targets. While at it also add a check that at least one CPU was hotplugged, to avoid silent breakage in the future. Fixes: bc1fb850a3 (vl.c deprecate incorrect CPUs topology) Signed-off-by: Igor Mammedov Message-Id: <20190830110723.15096-3-imammedo@redhat.com> Signed-off-by: Eduardo Habkost --- tests/cpu-plug-test.c | 68 ++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/tests/cpu-plug-test.c b/tests/cpu-plug-test.c index 776407e1b6..058cef5ac1 100644 --- a/tests/cpu-plug-test.c +++ b/tests/cpu-plug-test.c @@ -12,6 +12,7 @@ #include "qemu-common.h" #include "libqtest-single.h" #include "qapi/qmp/qdict.h" +#include "qapi/qmp/qlist.h" struct PlugTestData { char *machine; @@ -72,12 +73,15 @@ static void test_plug_without_cpu_add(gconstpointer data) g_free(args); } -static void test_plug_with_device_add_x86(gconstpointer data) +static void test_plug_with_device_add(gconstpointer data) { const PlugTestData *td = data; char *args; - unsigned int s, c, t; QTestState *qts; + QDict *resp; + QList *cpus; + QObject *e; + int hotplugged = 0; args = g_strdup_printf("-machine %s -cpu %s " "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u", @@ -85,43 +89,29 @@ static void test_plug_with_device_add_x86(gconstpointer data) td->sockets, td->cores, td->threads, td->maxcpus); qts = qtest_init(args); - for (s = 1; s < td->sockets; s++) { - for (c = 0; c < td->cores; c++) { - for (t = 0; t < td->threads; t++) { - char *id = g_strdup_printf("id-%i-%i-%i", s, c, t); - qtest_qmp_device_add(qts, td->device_model, id, - "{'socket-id':%u, 'core-id':%u," - " 'thread-id':%u}", - s, c, t); - g_free(id); - } + resp = qtest_qmp(qts, "{ 'execute': 'query-hotpluggable-cpus'}"); + g_assert(qdict_haskey(resp, "return")); + cpus = qdict_get_qlist(resp, "return"); + g_assert(cpus); + + while ((e = qlist_pop(cpus))) { + const QDict *cpu, *props; + + cpu = qobject_to(QDict, e); + if (qdict_haskey(cpu, "qom-path")) { + continue; } + + g_assert(qdict_haskey(cpu, "props")); + props = qdict_get_qdict(cpu, "props"); + + qtest_qmp_device_add_qdict(qts, td->device_model, props); + hotplugged++; } - qtest_quit(qts); - g_free(args); -} - -static void test_plug_with_device_add_coreid(gconstpointer data) -{ - const PlugTestData *td = data; - char *args; - unsigned int c; - QTestState *qts; - - args = g_strdup_printf("-machine %s -cpu %s " - "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u", - td->machine, td->cpu_model, - td->sockets, td->cores, td->threads, td->maxcpus); - qts = qtest_init(args); - - for (c = 1; c < td->cores; c++) { - char *id = g_strdup_printf("id-%i", c); - qtest_qmp_device_add(qts, td->device_model, id, - "{'core-id':%u}", c); - g_free(id); - } - + /* make sure that there were hotplugged CPUs */ + g_assert(hotplugged); + qobject_unref(resp); qtest_quit(qts); g_free(args); } @@ -182,7 +172,7 @@ static void add_pc_test_case(const char *mname) path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u", mname, data2->sockets, data2->cores, data2->threads, data2->maxcpus); - qtest_add_data_func_full(path, data2, test_plug_with_device_add_x86, + qtest_add_data_func_full(path, data2, test_plug_with_device_add, test_data_free); g_free(path); } @@ -209,7 +199,7 @@ static void add_pseries_test_case(const char *mname) path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u", mname, data->sockets, data->cores, data->threads, data->maxcpus); - qtest_add_data_func_full(path, data, test_plug_with_device_add_coreid, + qtest_add_data_func_full(path, data, test_plug_with_device_add, test_data_free); g_free(path); } @@ -246,7 +236,7 @@ static void add_s390x_test_case(const char *mname) path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u", mname, data2->sockets, data2->cores, data2->threads, data2->maxcpus); - qtest_add_data_func_full(path, data2, test_plug_with_device_add_coreid, + qtest_add_data_func_full(path, data2, test_plug_with_device_add, test_data_free); g_free(path); } From 0533ef5f2089f4f12a0ec5c8035e5e15ba0b5556 Mon Sep 17 00:00:00 2001 From: Tao Xu Date: Thu, 5 Sep 2019 16:32:38 +0800 Subject: [PATCH 03/18] numa: Introduce MachineClass::auto_enable_numa for implicit NUMA node Add MachineClass::auto_enable_numa field. When it is true, a NUMA node is expected to be created implicitly. Acked-by: David Gibson Suggested-by: Igor Mammedov Suggested-by: Eduardo Habkost Reviewed-by: Igor Mammedov Signed-off-by: Tao Xu Message-Id: <20190905083238.1799-1-tao3.xu@intel.com> Signed-off-by: Eduardo Habkost --- hw/core/numa.c | 10 ++++++++-- hw/ppc/spapr.c | 9 +-------- include/hw/boards.h | 1 + 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/core/numa.c b/hw/core/numa.c index 4dfec5c95b..038c96d4ab 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -378,11 +378,17 @@ void numa_complete_configuration(MachineState *ms) * guest tries to use it with that drivers. * * Enable NUMA implicitly by adding a new NUMA node automatically. + * + * Or if MachineClass::auto_enable_numa is true and no NUMA nodes, + * assume there is just one node with whole RAM. */ - if (ms->ram_slots > 0 && ms->numa_state->num_nodes == 0 && - mc->auto_enable_numa_with_memhp) { + if (ms->numa_state->num_nodes == 0 && + ((ms->ram_slots > 0 && + mc->auto_enable_numa_with_memhp) || + mc->auto_enable_numa)) { NumaNodeOptions node = { }; parse_numa_node(ms, &node, &error_abort); + numa_info[0].node_mem = ram_size; } assert(max_numa_nodeid <= MAX_NODES); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 514a17ae74..4eb97d3a9b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -346,14 +346,6 @@ static int spapr_populate_memory(SpaprMachineState *spapr, void *fdt) hwaddr mem_start, node_size; int i, nb_nodes = machine->numa_state->num_nodes; NodeInfo *nodes = machine->numa_state->nodes; - NodeInfo ramnode; - - /* No NUMA nodes, assume there is just one node with whole RAM */ - if (!nb_nodes) { - nb_nodes = 1; - ramnode.node_mem = machine->ram_size; - nodes = &ramnode; - } for (i = 0, mem_start = 0; i < nb_nodes; ++i) { if (!nodes[i].node_mem) { @@ -4430,6 +4422,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) */ mc->numa_mem_align_shift = 28; mc->numa_mem_supported = true; + mc->auto_enable_numa = true; smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF; smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON; diff --git a/include/hw/boards.h b/include/hw/boards.h index be18a5c032..de45087f34 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -228,6 +228,7 @@ struct MachineClass { bool smbus_no_migration_support; bool nvdimm_supported; bool numa_mem_supported; + bool auto_enable_numa; HotplugHandler *(*get_hotplug_handler)(MachineState *machine, DeviceState *dev); From 217e8ef9c975fee3aa823391cd1d2fd24d6a546e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 10 Oct 2019 15:15:20 +0200 Subject: [PATCH 04/18] hw/acpi/piix4: Convert reset handler to DeviceReset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PIIX4/PM is a PCI device within the PIIX4 chipset, it will be reset when the PCI bus it stands on is reset. Convert its reset handler into a proper Device reset method. Reviewed-by: Igor Mammedov Reviewed-by: Li Qiang Reviewed-by: Michael S. Tsirkin Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20191010131527.32513-2-philmd@redhat.com> Signed-off-by: Eduardo Habkost --- hw/acpi/piix4.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 5742c3df87..4e079b39bd 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -27,7 +27,6 @@ #include "hw/pci/pci.h" #include "hw/qdev-properties.h" #include "hw/acpi/acpi.h" -#include "sysemu/reset.h" #include "sysemu/runstate.h" #include "sysemu/sysemu.h" #include "qapi/error.h" @@ -344,9 +343,9 @@ static const VMStateDescription vmstate_acpi = { } }; -static void piix4_reset(void *opaque) +static void piix4_pm_reset(DeviceState *dev) { - PIIX4PMState *s = opaque; + PIIX4PMState *s = PIIX4_PM(dev); PCIDevice *d = PCI_DEVICE(s); uint8_t *pci_conf = d->config; @@ -542,7 +541,6 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp) s->machine_ready.notify = piix4_pm_machine_ready; qemu_add_machine_init_done_notifier(&s->machine_ready); - qemu_register_reset(piix4_reset, s); piix4_acpi_system_hot_add_init(pci_address_space_io(dev), pci_get_bus(dev), s); @@ -692,6 +690,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3; k->revision = 0x03; k->class_id = PCI_CLASS_BRIDGE_OTHER; + dc->reset = piix4_pm_reset; dc->desc = "PM"; dc->vmsd = &vmstate_acpi; dc->props = piix4_pm_properties; From fd52c20f2c58152f6f23bed658474ae1d1a2fe52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 10 Oct 2019 15:15:21 +0200 Subject: [PATCH 05/18] hw/isa/piix4: Convert reset handler to DeviceReset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PIIX4/ISA is a PCI device within the PIIX4 chipset, it will be reset when the PCI bus it stands on is reset. Convert its reset handler into a proper Device reset method. Reviewed-by: Li Qiang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20191010131527.32513-3-philmd@redhat.com> Signed-off-by: Eduardo Habkost --- hw/isa/piix4.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 3294056cd5..890d999abf 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -28,7 +28,6 @@ #include "hw/isa/isa.h" #include "hw/sysbus.h" #include "migration/vmstate.h" -#include "sysemu/reset.h" PCIDevice *piix4_dev; @@ -40,9 +39,9 @@ typedef struct PIIX4State { #define PIIX4_PCI_DEVICE(obj) \ OBJECT_CHECK(PIIX4State, (obj), TYPE_PIIX4_PCI_DEVICE) -static void piix4_reset(void *opaque) +static void piix4_isa_reset(DeviceState *dev) { - PIIX4State *d = opaque; + PIIX4State *d = PIIX4_PCI_DEVICE(dev); uint8_t *pci_conf = d->dev.config; pci_conf[0x04] = 0x07; // master, memory and I/O @@ -97,7 +96,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp) return; } piix4_dev = &d->dev; - qemu_register_reset(piix4_reset, d); } int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn) @@ -118,6 +116,7 @@ static void piix4_class_init(ObjectClass *klass, void *data) k->vendor_id = PCI_VENDOR_ID_INTEL; k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0; k->class_id = PCI_CLASS_BRIDGE_ISA; + dc->reset = piix4_isa_reset; dc->desc = "ISA bridge"; dc->vmsd = &vmstate_piix4; /* From ee358e919e385fdc79d59d0d47b4a81e349cd5c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 10 Oct 2019 15:15:22 +0200 Subject: [PATCH 06/18] hw/ide/piix: Convert reset handler to DeviceReset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PIIX/IDE is a PCI device within a PIIX chipset, it will be reset when the PCI bus it stands on is reset. Convert its reset handler into a proper Device reset method. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20191010131527.32513-4-philmd@redhat.com> Reviewed-by: Li Qiang Signed-off-by: Eduardo Habkost --- hw/ide/piix.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/hw/ide/piix.c b/hw/ide/piix.c index fba6bc8bff..db313dd3b1 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -30,7 +30,6 @@ #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" #include "sysemu/dma.h" -#include "sysemu/reset.h" #include "hw/ide/pci.h" #include "trace.h" @@ -103,9 +102,9 @@ static void bmdma_setup_bar(PCIIDEState *d) } } -static void piix3_reset(void *opaque) +static void piix_ide_reset(DeviceState *dev) { - PCIIDEState *d = opaque; + PCIIDEState *d = PCI_IDE(dev); PCIDevice *pd = PCI_DEVICE(d); uint8_t *pci_conf = pd->config; int i; @@ -154,8 +153,6 @@ static void pci_piix_ide_realize(PCIDevice *dev, Error **errp) pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode - qemu_register_reset(piix3_reset, d); - bmdma_setup_bar(d); pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar); @@ -247,6 +244,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + dc->reset = piix_ide_reset; k->realize = pci_piix_ide_realize; k->exit = pci_piix_ide_exitfn; k->vendor_id = PCI_VENDOR_ID_INTEL; @@ -273,6 +271,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + dc->reset = piix_ide_reset; k->realize = pci_piix_ide_realize; k->exit = pci_piix_ide_exitfn; k->vendor_id = PCI_VENDOR_ID_INTEL; From d96c81f9b8bdeb19417a54178759ac170f080cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 10 Oct 2019 15:15:23 +0200 Subject: [PATCH 07/18] hw/ide/sii3112: Convert reset handler to DeviceReset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SiI3112A SATA controller is a PCI device, it will be reset when the PCI bus it stands on is reset. Convert its reset handler into a proper Device reset method. Reviewed-by: Li Qiang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20191010131527.32513-5-philmd@redhat.com> Signed-off-by: Eduardo Habkost --- hw/ide/sii3112.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c index 2181260531..06605d7af2 100644 --- a/hw/ide/sii3112.c +++ b/hw/ide/sii3112.c @@ -15,7 +15,6 @@ #include "qemu/osdep.h" #include "hw/ide/pci.h" #include "qemu/module.h" -#include "sysemu/reset.h" #include "trace.h" #define TYPE_SII3112_PCI "sii3112" @@ -237,9 +236,9 @@ static void sii3112_set_irq(void *opaque, int channel, int level) sii3112_update_irq(s); } -static void sii3112_reset(void *opaque) +static void sii3112_reset(DeviceState *dev) { - SiI3112PCIState *s = opaque; + SiI3112PCIState *s = SII3112_PCI(dev); int i; for (i = 0; i < 2; i++) { @@ -290,7 +289,6 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp) s->bmdma[i].bus = &s->bus[i]; ide_register_restart_cb(&s->bus[i]); } - qemu_register_reset(sii3112_reset, s); } static void sii3112_pci_class_init(ObjectClass *klass, void *data) @@ -303,6 +301,7 @@ static void sii3112_pci_class_init(ObjectClass *klass, void *data) pd->class_id = PCI_CLASS_STORAGE_RAID; pd->revision = 1; pd->realize = sii3112_pci_realize; + dc->reset = sii3112_reset; dc->desc = "SiI3112A SATA controller"; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); } From 71d3bacd7f77d06673041be3c50578807cd2555c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 10 Oct 2019 15:15:24 +0200 Subject: [PATCH 08/18] hw/ide/via82c: Convert reset handler to DeviceReset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The VIA82C686B IDE controller is a PCI device, it will be reset when the PCI bus it stands on is reset. Convert its reset handler into a proper Device reset method. Reviewed-by: Li Qiang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20191010131527.32513-6-philmd@redhat.com> Signed-off-by: Eduardo Habkost --- hw/ide/via.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index 7087dc676e..053622bd82 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -29,7 +29,6 @@ #include "migration/vmstate.h" #include "qemu/module.h" #include "sysemu/dma.h" -#include "sysemu/reset.h" #include "hw/ide/pci.h" #include "trace.h" @@ -120,10 +119,10 @@ static void via_ide_set_irq(void *opaque, int n, int level) } } -static void via_ide_reset(void *opaque) +static void via_ide_reset(DeviceState *dev) { - PCIIDEState *d = opaque; - PCIDevice *pd = PCI_DEVICE(d); + PCIIDEState *d = PCI_IDE(dev); + PCIDevice *pd = PCI_DEVICE(dev); uint8_t *pci_conf = pd->config; int i; @@ -172,8 +171,6 @@ static void via_ide_realize(PCIDevice *dev, Error **errp) pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); dev->wmask[PCI_INTERRUPT_LINE] = 0xf; - qemu_register_reset(via_ide_reset, d); - memory_region_init_io(&d->data_bar[0], OBJECT(d), &pci_ide_data_le_ops, &d->bus[0], "via-ide0-data", 8); pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->data_bar[0]); @@ -229,6 +226,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + dc->reset = via_ide_reset; k->realize = via_ide_realize; k->exit = via_ide_exitfn; k->vendor_id = PCI_VENDOR_ID_VIA; From 9dc1a7699d52c9086950e7a64f0cbc657b70b645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 10 Oct 2019 15:15:25 +0200 Subject: [PATCH 09/18] hw/isa/vt82c686: Convert reset handler to DeviceReset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The VIA VT82C686 Southbridge is a PCI device, it will be reset when the PCI bus it stands on is reset. Convert its reset handler into a proper Device reset method. Reviewed-by: Li Qiang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20191010131527.32513-7-philmd@redhat.com> Signed-off-by: Eduardo Habkost --- hw/isa/vt82c686.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 50bd28fa82..616f67f347 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -23,7 +23,6 @@ #include "hw/isa/apm.h" #include "hw/acpi/acpi.h" #include "hw/i2c/pm_smbus.h" -#include "sysemu/reset.h" #include "qemu/module.h" #include "qemu/timer.h" #include "exec/address-spaces.h" @@ -116,11 +115,10 @@ static const MemoryRegionOps superio_ops = { }, }; -static void vt82c686b_reset(void * opaque) +static void vt82c686b_isa_reset(DeviceState *dev) { - PCIDevice *d = opaque; - uint8_t *pci_conf = d->config; - VT82C686BState *vt82c = VT82C686B_DEVICE(d); + VT82C686BState *vt82c = VT82C686B_DEVICE(dev); + uint8_t *pci_conf = vt82c->dev.config; pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | @@ -476,8 +474,6 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) * But we do not emulate a floppy, so just set it here. */ memory_region_add_subregion(isa_bus->address_space_io, 0x3f0, &vt82c->superio); - - qemu_register_reset(vt82c686b_reset, d); } ISABus *vt82c686b_isa_init(PCIBus *bus, int devfn) @@ -501,6 +497,7 @@ static void via_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE; k->class_id = PCI_CLASS_BRIDGE_ISA; k->revision = 0x40; + dc->reset = vt82c686b_isa_reset; dc->desc = "ISA bridge"; dc->vmsd = &vmstate_via; /* From f7030d0031d6a350d191178605b9c218457acbcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 10 Oct 2019 15:15:26 +0200 Subject: [PATCH 10/18] hw/input/lm832x: Convert reset handler to DeviceReset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LM8323 key-scan controller is a I2C device, it will be reset when the I2C bus it stands on is reset. Convert its reset handler into a proper Device reset method. Reviewed-by: Li Qiang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20191010131527.32513-8-philmd@redhat.com> Signed-off-by: Eduardo Habkost --- hw/input/lm832x.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/hw/input/lm832x.c b/hw/input/lm832x.c index a37eb854b9..aa629ddbf1 100644 --- a/hw/input/lm832x.c +++ b/hw/input/lm832x.c @@ -24,7 +24,6 @@ #include "migration/vmstate.h" #include "qemu/module.h" #include "qemu/timer.h" -#include "sysemu/reset.h" #include "ui/console.h" #define TYPE_LM8323 "lm8323" @@ -94,8 +93,10 @@ static void lm_kbd_gpio_update(LM823KbdState *s) { } -static void lm_kbd_reset(LM823KbdState *s) +static void lm_kbd_reset(DeviceState *dev) { + LM823KbdState *s = LM8323(dev); + s->config = 0x80; s->status = INT_NOINIT; s->acttime = 125; @@ -273,7 +274,7 @@ static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value) case LM832x_CMD_RESET: if (value == 0xaa) - lm_kbd_reset(s); + lm_kbd_reset(DEVICE(s)); else lm_kbd_error(s, ERR_BADPAR); s->reg = LM832x_GENERAL_ERROR; @@ -476,10 +477,6 @@ static void lm8323_realize(DeviceState *dev, Error **errp) s->pwm.tm[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm1_tick, s); s->pwm.tm[2] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm2_tick, s); qdev_init_gpio_out(dev, &s->nirq, 1); - - lm_kbd_reset(s); - - qemu_register_reset((void *) lm_kbd_reset, s); } void lm832x_key_event(DeviceState *dev, int key, int state) @@ -507,6 +504,7 @@ static void lm8323_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); + dc->reset = lm_kbd_reset; dc->realize = lm8323_realize; k->event = lm_i2c_event; k->recv = lm_i2c_rx; From 88552b16f2a11a51323b8a4d643e73332d89d7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 10 Oct 2019 15:15:27 +0200 Subject: [PATCH 11/18] hw/misc/vmcoreinfo: Add comment about reset handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The VM coreinfo device does not sit on a bus, so it won't be reset automatically. This is why it calls qemu_register_reset(). Add a comment about it, so we don't convert its reset handler to a DeviceReset method. Reviewed-by: Marc-André Lureau Reviewed-by: Li Qiang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20191010131527.32513-9-philmd@redhat.com> Signed-off-by: Eduardo Habkost --- hw/misc/vmcoreinfo.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/misc/vmcoreinfo.c b/hw/misc/vmcoreinfo.c index 326a3ce8f4..a9d718fc23 100644 --- a/hw/misc/vmcoreinfo.c +++ b/hw/misc/vmcoreinfo.c @@ -61,6 +61,10 @@ static void vmcoreinfo_realize(DeviceState *dev, Error **errp) NULL, fw_cfg_vmci_write, s, &s->vmcoreinfo, sizeof(s->vmcoreinfo), false); + /* + * This device requires to register a global reset because it is + * not plugged to a bus (which, as its QOM parent, would reset it). + */ qemu_register_reset(vmcoreinfo_reset, dev); vmcoreinfo_state = s; } From fc2db8501f3bfa57000c625c1f8b304e4a15976e Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Tue, 30 Jul 2019 08:37:39 +0800 Subject: [PATCH 12/18] memory-device: not necessary to use goto for the last check We are already at the last condition check. Signed-off-by: Wei Yang Reviewed-by: Igor Mammedov Reviewed-by: David Hildenbrand Message-Id: <20190730003740.20694-2-richardw.yang@linux.intel.com> Signed-off-by: Eduardo Habkost --- hw/mem/memory-device.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c index 53953fdc3a..5029890e06 100644 --- a/hw/mem/memory-device.c +++ b/hw/mem/memory-device.c @@ -185,7 +185,6 @@ static uint64_t memory_device_get_free_addr(MachineState *ms, if (!range_contains_range(&as, &new)) { error_setg(errp, "could not find position in guest address space for " "memory device - memory fragmented due to alignments"); - goto out; } out: g_slist_free(list); From 64afc7c32bf1634df9d9ff77efbc39225400744a Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Tue, 30 Jul 2019 08:37:40 +0800 Subject: [PATCH 13/18] memory-device: break the loop if tmp exceed the hinted range The memory-device list built by memory_device_build_list is ordered by its address, this means if the tmp range exceed the hinted range, all the following range will not overlap with it. And this won't change default pc-dimm mapping and address assignment stay the same as before this change. Signed-off-by: Wei Yang Message-Id: <20190730003740.20694-3-richardw.yang@linux.intel.com> Reviewed-by: David Hildenbrand Reviewed-by: Igor Mammedov Signed-off-by: Eduardo Habkost --- hw/mem/memory-device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c index 5029890e06..aef148c1d7 100644 --- a/hw/mem/memory-device.c +++ b/hw/mem/memory-device.c @@ -179,6 +179,8 @@ static uint64_t memory_device_get_free_addr(MachineState *ms, range_make_empty(&new); break; } + } else if (range_lob(&tmp) > range_upb(&new)) { + break; } } From f2be0bebb6f5d5436079d8c28f07da891082d753 Mon Sep 17 00:00:00 2001 From: Tao Xu Date: Thu, 26 Sep 2019 10:10:54 +0800 Subject: [PATCH 14/18] target/i386: clean up comments over 80 chars per line Add some comments, clean up comments over 80 chars per line. And there is an extra line in comment of CPUID_8000_0008_EBX_WBNOINVD, remove the extra enter and spaces. Acked-by: Stefano Garzarella Signed-off-by: Tao Xu Message-Id: <20190926021055.6970-2-tao3.xu@intel.com> [ehabkost: rebase to latest git master] Signed-off-by: Eduardo Habkost --- target/i386/cpu.h | 162 ++++++++++++++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 55 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index eaa5395aa5..93aad4655f 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -669,65 +669,117 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_SVM_PAUSEFILTER (1U << 10) #define CPUID_SVM_PFTHRESHOLD (1U << 12) -#define CPUID_7_0_EBX_FSGSBASE (1U << 0) -#define CPUID_7_0_EBX_BMI1 (1U << 3) -#define CPUID_7_0_EBX_HLE (1U << 4) -#define CPUID_7_0_EBX_AVX2 (1U << 5) -#define CPUID_7_0_EBX_SMEP (1U << 7) -#define CPUID_7_0_EBX_BMI2 (1U << 8) -#define CPUID_7_0_EBX_ERMS (1U << 9) -#define CPUID_7_0_EBX_INVPCID (1U << 10) -#define CPUID_7_0_EBX_RTM (1U << 11) -#define CPUID_7_0_EBX_MPX (1U << 14) -#define CPUID_7_0_EBX_AVX512F (1U << 16) /* AVX-512 Foundation */ -#define CPUID_7_0_EBX_AVX512DQ (1U << 17) /* AVX-512 Doubleword & Quadword Instrs */ -#define CPUID_7_0_EBX_RDSEED (1U << 18) -#define CPUID_7_0_EBX_ADX (1U << 19) -#define CPUID_7_0_EBX_SMAP (1U << 20) -#define CPUID_7_0_EBX_AVX512IFMA (1U << 21) /* AVX-512 Integer Fused Multiply Add */ -#define CPUID_7_0_EBX_PCOMMIT (1U << 22) /* Persistent Commit */ -#define CPUID_7_0_EBX_CLFLUSHOPT (1U << 23) /* Flush a Cache Line Optimized */ -#define CPUID_7_0_EBX_CLWB (1U << 24) /* Cache Line Write Back */ -#define CPUID_7_0_EBX_INTEL_PT (1U << 25) /* Intel Processor Trace */ -#define CPUID_7_0_EBX_AVX512PF (1U << 26) /* AVX-512 Prefetch */ -#define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */ -#define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */ -#define CPUID_7_0_EBX_SHA_NI (1U << 29) /* SHA1/SHA256 Instruction Extensions */ -#define CPUID_7_0_EBX_AVX512BW (1U << 30) /* AVX-512 Byte and Word Instructions */ -#define CPUID_7_0_EBX_AVX512VL (1U << 31) /* AVX-512 Vector Length Extensions */ +/* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */ +#define CPUID_7_0_EBX_FSGSBASE (1U << 0) +/* 1st Group of Advanced Bit Manipulation Extensions */ +#define CPUID_7_0_EBX_BMI1 (1U << 3) +/* Hardware Lock Elision */ +#define CPUID_7_0_EBX_HLE (1U << 4) +/* Intel Advanced Vector Extensions 2 */ +#define CPUID_7_0_EBX_AVX2 (1U << 5) +/* Supervisor-mode Execution Prevention */ +#define CPUID_7_0_EBX_SMEP (1U << 7) +/* 2nd Group of Advanced Bit Manipulation Extensions */ +#define CPUID_7_0_EBX_BMI2 (1U << 8) +/* Enhanced REP MOVSB/STOSB */ +#define CPUID_7_0_EBX_ERMS (1U << 9) +/* Invalidate Process-Context Identifier */ +#define CPUID_7_0_EBX_INVPCID (1U << 10) +/* Restricted Transactional Memory */ +#define CPUID_7_0_EBX_RTM (1U << 11) +/* Memory Protection Extension */ +#define CPUID_7_0_EBX_MPX (1U << 14) +/* AVX-512 Foundation */ +#define CPUID_7_0_EBX_AVX512F (1U << 16) +/* AVX-512 Doubleword & Quadword Instruction */ +#define CPUID_7_0_EBX_AVX512DQ (1U << 17) +/* Read Random SEED */ +#define CPUID_7_0_EBX_RDSEED (1U << 18) +/* ADCX and ADOX instructions */ +#define CPUID_7_0_EBX_ADX (1U << 19) +/* Supervisor Mode Access Prevention */ +#define CPUID_7_0_EBX_SMAP (1U << 20) +/* AVX-512 Integer Fused Multiply Add */ +#define CPUID_7_0_EBX_AVX512IFMA (1U << 21) +/* Persistent Commit */ +#define CPUID_7_0_EBX_PCOMMIT (1U << 22) +/* Flush a Cache Line Optimized */ +#define CPUID_7_0_EBX_CLFLUSHOPT (1U << 23) +/* Cache Line Write Back */ +#define CPUID_7_0_EBX_CLWB (1U << 24) +/* Intel Processor Trace */ +#define CPUID_7_0_EBX_INTEL_PT (1U << 25) +/* AVX-512 Prefetch */ +#define CPUID_7_0_EBX_AVX512PF (1U << 26) +/* AVX-512 Exponential and Reciprocal */ +#define CPUID_7_0_EBX_AVX512ER (1U << 27) +/* AVX-512 Conflict Detection */ +#define CPUID_7_0_EBX_AVX512CD (1U << 28) +/* SHA1/SHA256 Instruction Extensions */ +#define CPUID_7_0_EBX_SHA_NI (1U << 29) +/* AVX-512 Byte and Word Instructions */ +#define CPUID_7_0_EBX_AVX512BW (1U << 30) +/* AVX-512 Vector Length Extensions */ +#define CPUID_7_0_EBX_AVX512VL (1U << 31) -#define CPUID_7_0_ECX_AVX512BMI (1U << 1) -#define CPUID_7_0_ECX_VBMI (1U << 1) /* AVX-512 Vector Byte Manipulation Instrs */ -#define CPUID_7_0_ECX_UMIP (1U << 2) -#define CPUID_7_0_ECX_PKU (1U << 3) -#define CPUID_7_0_ECX_OSPKE (1U << 4) -#define CPUID_7_0_ECX_VBMI2 (1U << 6) /* Additional VBMI Instrs */ -#define CPUID_7_0_ECX_GFNI (1U << 8) -#define CPUID_7_0_ECX_VAES (1U << 9) -#define CPUID_7_0_ECX_VPCLMULQDQ (1U << 10) -#define CPUID_7_0_ECX_AVX512VNNI (1U << 11) -#define CPUID_7_0_ECX_AVX512BITALG (1U << 12) -#define CPUID_7_0_ECX_AVX512_VPOPCNTDQ (1U << 14) /* POPCNT for vectors of DW/QW */ -#define CPUID_7_0_ECX_LA57 (1U << 16) -#define CPUID_7_0_ECX_RDPID (1U << 22) -#define CPUID_7_0_ECX_CLDEMOTE (1U << 25) /* CLDEMOTE Instruction */ -#define CPUID_7_0_ECX_MOVDIRI (1U << 27) /* MOVDIRI Instruction */ -#define CPUID_7_0_ECX_MOVDIR64B (1U << 28) /* MOVDIR64B Instruction */ +/* AVX-512 Vector Byte Manipulation Instruction */ +#define CPUID_7_0_ECX_AVX512BMI (1U << 1) +#define CPUID_7_0_ECX_VBMI (1U << 1) +/* User-Mode Instruction Prevention */ +#define CPUID_7_0_ECX_UMIP (1U << 2) +/* Protection Keys for User-mode Pages */ +#define CPUID_7_0_ECX_PKU (1U << 3) +/* OS Enable Protection Keys */ +#define CPUID_7_0_ECX_OSPKE (1U << 4) +/* Additional AVX-512 Vector Byte Manipulation Instruction */ +#define CPUID_7_0_ECX_VBMI2 (1U << 6) +/* Galois Field New Instructions */ +#define CPUID_7_0_ECX_GFNI (1U << 8) +/* Vector AES Instructions */ +#define CPUID_7_0_ECX_VAES (1U << 9) +/* Carry-Less Multiplication Quadword */ +#define CPUID_7_0_ECX_VPCLMULQDQ (1U << 10) +/* Vector Neural Network Instructions */ +#define CPUID_7_0_ECX_AVX512VNNI (1U << 11) +/* Support for VPOPCNT[B,W] and VPSHUFBITQMB */ +#define CPUID_7_0_ECX_AVX512BITALG (1U << 12) +/* POPCNT for vectors of DW/QW */ +#define CPUID_7_0_ECX_AVX512_VPOPCNTDQ (1U << 14) +/* 5-level Page Tables */ +#define CPUID_7_0_ECX_LA57 (1U << 16) +/* Read Processor ID */ +#define CPUID_7_0_ECX_RDPID (1U << 22) +/* Cache Line Demote Instruction */ +#define CPUID_7_0_ECX_CLDEMOTE (1U << 25) +/* Move Doubleword as Direct Store Instruction */ +#define CPUID_7_0_ECX_MOVDIRI (1U << 27) +/* Move 64 Bytes as Direct Store Instruction */ +#define CPUID_7_0_ECX_MOVDIR64B (1U << 28) -#define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network Instructions */ -#define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation Single Precision */ -#define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */ -#define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29) /*Arch Capabilities*/ -#define CPUID_7_0_EDX_CORE_CAPABILITY (1U << 30) /*Core Capability*/ -#define CPUID_7_0_EDX_SPEC_CTRL_SSBD (1U << 31) /* Speculative Store Bypass Disable */ +/* AVX512 Neural Network Instructions */ +#define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) +/* AVX512 Multiply Accumulation Single Precision */ +#define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) +/* Speculation Control */ +#define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) +/* Arch Capabilities */ +#define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29) +/* Core Capability */ +#define CPUID_7_0_EDX_CORE_CAPABILITY (1U << 30) +/* Speculative Store Bypass Disable */ +#define CPUID_7_0_EDX_SPEC_CTRL_SSBD (1U << 31) -#define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) /* AVX512 BFloat16 Instruction */ +/* AVX512 BFloat16 Instruction */ +#define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) -#define CPUID_8000_0008_EBX_CLZERO (1U << 0) /* CLZERO instruction */ -#define CPUID_8000_0008_EBX_XSAVEERPTR (1U << 2) /* Always save/restore FP error pointers */ -#define CPUID_8000_0008_EBX_WBNOINVD (1U << 9) /* Write back and - do not invalidate cache */ -#define CPUID_8000_0008_EBX_IBPB (1U << 12) /* Indirect Branch Prediction Barrier */ +/* CLZERO instruction */ +#define CPUID_8000_0008_EBX_CLZERO (1U << 0) +/* Always save/restore FP error pointers */ +#define CPUID_8000_0008_EBX_XSAVEERPTR (1U << 2) +/* Write back and do not invalidate cache */ +#define CPUID_8000_0008_EBX_WBNOINVD (1U << 9) +/* Indirect Branch Prediction Barrier */ +#define CPUID_8000_0008_EBX_IBPB (1U << 12) #define CPUID_XSAVE_XSAVEOPT (1U << 0) #define CPUID_XSAVE_XSAVEC (1U << 1) From e7694a5eae34a31a5b240467b5201a7f31b7f96a Mon Sep 17 00:00:00 2001 From: Tao Xu Date: Thu, 26 Sep 2019 10:10:55 +0800 Subject: [PATCH 15/18] target/i386: drop the duplicated definition of cpuid AVX512_VBMI macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the duplicated definition of cpuid AVX512_VBMI macro and rename it as CPUID_7_0_ECX_AVX512_VBMI. Rename CPUID_7_0_ECX_VBMI2 as CPUID_7_0_ECX_AVX512_VBMI2. Acked-by: Stefano Garzarella Signed-off-by: Tao Xu Message-Id: <20190926021055.6970-3-tao3.xu@intel.com> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Eduardo Habkost --- target/i386/cpu.c | 8 ++++---- target/i386/cpu.h | 5 ++--- target/i386/hvf/x86_cpuid.c | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 44f1bbdcac..daece62c19 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2645,8 +2645,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP, .features[FEAT_7_0_ECX] = - CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | - CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI | + CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | + CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI | CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | CPUID_7_0_ECX_AVX512_VPOPCNTDQ, @@ -2703,8 +2703,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT, .features[FEAT_7_0_ECX] = - CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | - CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI | + CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | + CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI | CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 93aad4655f..cedb5bc205 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -723,8 +723,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_EBX_AVX512VL (1U << 31) /* AVX-512 Vector Byte Manipulation Instruction */ -#define CPUID_7_0_ECX_AVX512BMI (1U << 1) -#define CPUID_7_0_ECX_VBMI (1U << 1) +#define CPUID_7_0_ECX_AVX512_VBMI (1U << 1) /* User-Mode Instruction Prevention */ #define CPUID_7_0_ECX_UMIP (1U << 2) /* Protection Keys for User-mode Pages */ @@ -732,7 +731,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; /* OS Enable Protection Keys */ #define CPUID_7_0_ECX_OSPKE (1U << 4) /* Additional AVX-512 Vector Byte Manipulation Instruction */ -#define CPUID_7_0_ECX_VBMI2 (1U << 6) +#define CPUID_7_0_ECX_AVX512_VBMI2 (1U << 6) /* Galois Field New Instructions */ #define CPUID_7_0_ECX_GFNI (1U << 8) /* Vector AES Instructions */ diff --git a/target/i386/hvf/x86_cpuid.c b/target/i386/hvf/x86_cpuid.c index 4d957fe896..16762b6eb4 100644 --- a/target/i386/hvf/x86_cpuid.c +++ b/target/i386/hvf/x86_cpuid.c @@ -89,7 +89,7 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, ebx &= ~CPUID_7_0_EBX_INVPCID; } - ecx &= CPUID_7_0_ECX_AVX512BMI | CPUID_7_0_ECX_AVX512_VPOPCNTDQ; + ecx &= CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_AVX512_VPOPCNTDQ; edx &= CPUID_7_0_EDX_AVX512_4VNNIW | CPUID_7_0_EDX_AVX512_4FMAPS; } else { ebx = 0; From 76ecd7a514aa74b92dca807c60ca1e427e178fda Mon Sep 17 00:00:00 2001 From: Bingsong Si Date: Thu, 22 Aug 2019 12:29:01 +0800 Subject: [PATCH 16/18] i386: Fix legacy guest with xsave panic on host kvm without update cpuid. without kvm commit 412a3c41, CPUID(EAX=0xd,ECX=0).EBX always equal to 0 even through guest update xcr0, this will crash legacy guest(e.g., CentOS 6). Below is the call trace on the guest. [ 0.000000] kernel BUG at mm/bootmem.c:469! [ 0.000000] invalid opcode: 0000 [#1] SMP [ 0.000000] last sysfs file: [ 0.000000] CPU 0 [ 0.000000] Modules linked in: [ 0.000000] [ 0.000000] Pid: 0, comm: swapper Tainted: G --------------- H 2.6.32-279#2 Red Hat KVM [ 0.000000] RIP: 0010:[] [] alloc_bootmem_core+0x7b/0x29e [ 0.000000] RSP: 0018:ffffffff81a01cd8 EFLAGS: 00010046 [ 0.000000] RAX: ffffffff81cb1748 RBX: ffffffff81cb1720 RCX: 0000000001000000 [ 0.000000] RDX: 0000000000000040 RSI: 0000000000000000 RDI: ffffffff81cb1720 [ 0.000000] RBP: ffffffff81a01d38 R08: 0000000000000000 R09: 0000000000001000 [ 0.000000] R10: 02008921da802087 R11: 00000000ffff8800 R12: 0000000000000000 [ 0.000000] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000001000000 [ 0.000000] FS: 0000000000000000(0000) GS:ffff880002200000(0000) knlGS:0000000000000000 [ 0.000000] CS: 0010 DS: 0018 ES: 0018 CR0: 0000000080050033 [ 0.000000] CR2: 0000000000000000 CR3: 0000000001a85000 CR4: 00000000001406b0 [ 0.000000] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 0.000000] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 0.000000] Process swapper (pid: 0, threadinfo ffffffff81a00000, task ffffffff81a8d020) [ 0.000000] Stack: [ 0.000000] 0000000000000002 81a01dd881eaf060 000000007e5fe227 0000000000001001 [ 0.000000] 0000000000000040 0000000000000001 0000006cffffffff 0000000001000000 [ 0.000000] ffffffff81cb1720 0000000000000000 0000000000000000 0000000000000000 [ 0.000000] Call Trace: [ 0.000000] [] ___alloc_bootmem_nopanic+0x8d/0xca [ 0.000000] [] ___alloc_bootmem+0x11/0x39 [ 0.000000] [] __alloc_bootmem+0xb/0xd [ 0.000000] [] xsave_cntxt_init+0x249/0x2c0 [ 0.000000] [] init_thread_xstate+0x17/0x25 [ 0.000000] [] fpu_init+0x79/0xaa [ 0.000000] [] cpu_init+0x301/0x344 [ 0.000000] [] ? sort+0x155/0x230 [ 0.000000] [] trap_init+0x24e/0x25f [ 0.000000] [] start_kernel+0x21c/0x430 [ 0.000000] [] x86_64_start_reservations+0x125/0x129 [ 0.000000] [] x86_64_start_kernel+0xfa/0x109 [ 0.000000] Code: 03 48 89 f1 49 c1 e8 0c 48 0f af d0 48 c7 c6 00 a6 61 81 48 c7 c7 00 e5 79 81 31 c0 4c 89 74 24 08 e8 f2 d7 89 ff 4d 85 e4 75 04 <0f> 0b eb fe 48 8b 45 c0 48 83 e8 01 48 85 45 c0 74 04 0f 0b eb Signed-off-by: Bingsong Si Message-Id: <20190822042901.16858-1-owen.si@ucloud.cn> Signed-off-by: Eduardo Habkost --- target/i386/cpu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index daece62c19..b821132b6a 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -4693,7 +4693,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = xsave_area_size(x86_cpu_xsave_components(cpu)); *eax = env->features[FEAT_XSAVE_COMP_LO]; *edx = env->features[FEAT_XSAVE_COMP_HI]; - *ebx = xsave_area_size(env->xcr0); + /* + * The initial value of xcr0 and ebx == 0, On host without kvm + * commit 412a3c41(e.g., CentOS 6), the ebx's value always == 0 + * even through guest update xcr0, this will crash some legacy guest + * (e.g., CentOS 6), So set ebx == ecx to workaroud it. + */ + *ebx = kvm_enabled() ? *ecx : xsave_area_size(env->xcr0); } else if (count == 1) { *eax = env->features[FEAT_XSAVE]; } else if (count < ARRAY_SIZE(x86_ext_save_areas)) { From af95cafb877f563ed39ce8a5b2abe227dd5312fa Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 22 Aug 2019 19:52:10 -0300 Subject: [PATCH 17/18] i386: Omit all-zeroes entries from KVM CPUID table KVM has a 80-entry limit at KVM_SET_CPUID2. With the introduction of CPUID[0x1F], it is now possible to hit this limit with unusual CPU configurations, e.g.: $ ./x86_64-softmmu/qemu-system-x86_64 \ -smp 1,dies=2,maxcpus=2 \ -cpu EPYC,check=off,enforce=off \ -machine accel=kvm qemu-system-x86_64: kvm_init_vcpu failed: Argument list too long This happens because QEMU adds a lot of all-zeroes CPUID entries for unused CPUID leaves. In the example above, we end up creating 48 all-zeroes CPUID entries. KVM already returns all-zeroes when emulating the CPUID instruction if an entry is missing, so the all-zeroes entries are redundant. Skip those entries. This reduces the CPUID table size by half while keeping CPUID output unchanged. Reported-by: Yumei Huang Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1741508 Signed-off-by: Eduardo Habkost Message-Id: <20190822225210.32541-1-ehabkost@redhat.com> Acked-by: Paolo Bonzini Signed-off-by: Eduardo Habkost --- target/i386/kvm.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/target/i386/kvm.c b/target/i386/kvm.c index 11b9c854b5..8c73438c67 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -1567,6 +1567,13 @@ int kvm_arch_init_vcpu(CPUState *cs) c->function = i; c->flags = 0; cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); + if (!c->eax && !c->ebx && !c->ecx && !c->edx) { + /* + * KVM already returns all zeroes if a CPUID entry is missing, + * so we can omit it and avoid hitting KVM's 80-entry limit. + */ + cpuid_i--; + } break; } } @@ -1631,6 +1638,13 @@ int kvm_arch_init_vcpu(CPUState *cs) c->function = i; c->flags = 0; cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); + if (!c->eax && !c->ebx && !c->ecx && !c->edx) { + /* + * KVM already returns all zeroes if a CPUID entry is missing, + * so we can omit it and avoid hitting KVM's 80-entry limit. + */ + cpuid_i--; + } break; } } From 69edb0f37a52053978de65a81241ef171a6f2396 Mon Sep 17 00:00:00 2001 From: Xiaoyao Li Date: Sat, 12 Oct 2019 10:47:48 +0800 Subject: [PATCH 18/18] target/i386: Add Snowridge-v2 (no MPX) CPU model Add new version of Snowridge CPU model that removes MPX feature. MPX support is being phased out by Intel. GCC has dropped it, Linux kernel and KVM are also going to do that in the future. Signed-off-by: Xiaoyao Li Message-Id: <20191012024748.127135-1-xiaoyao.li@intel.com> Signed-off-by: Eduardo Habkost --- target/i386/cpu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index b821132b6a..47200b40c1 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2793,6 +2793,18 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_6_EAX_ARAT, .xlevel = 0x80000008, .model_id = "Intel Atom Processor (SnowRidge)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .props = (PropValue[]) { + { "mpx", "off" }, + { "model-id", "Intel Atom Processor (Snowridge, no MPX)" }, + { /* end of list */ }, + }, + }, + { /* end of list */ }, + }, }, { .name = "KnightsMill",