From 8ce3c44c925982d834a8200ee0c9c00a7e9db20e Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 20 Aug 2014 20:38:11 +0200 Subject: [PATCH 1/5] loader: g_realloc(p, 0) frees and returns NULL, simplify Once upon a time, it was decided that qemu_realloc(ptr, 0) should abort. Switching to glib retired that bright idea. A bit of code that was added to cope with it (commit 3e372cf) is still around. Bury it. See also commit 6528499. Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/elf_ops.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index c6b5129bab..a517753a6f 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -147,18 +147,13 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, } i++; } - if (nsyms) { - syms = g_realloc(syms, nsyms * sizeof(*syms)); + syms = g_realloc(syms, nsyms * sizeof(*syms)); - qsort(syms, nsyms, sizeof(*syms), glue(symcmp, SZ)); - for (i = 0; i < nsyms - 1; i++) { - if (syms[i].st_size == 0) { - syms[i].st_size = syms[i + 1].st_value - syms[i].st_value; - } + qsort(syms, nsyms, sizeof(*syms), glue(symcmp, SZ)); + for (i = 0; i < nsyms - 1; i++) { + if (syms[i].st_size == 0) { + syms[i].st_size = syms[i + 1].st_value - syms[i].st_value; } - } else { - g_free(syms); - syms = NULL; } /* String table */ From 45363e46aeebfc99753389649eac7c7fc22bfe52 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 29 Sep 2014 11:27:32 +0300 Subject: [PATCH 2/5] Revert "virtio-pci: fix migration for pci bus master" This reverts commit 4d43d3f3c8147ade184df9a1e9e82826edd39e19. Reported to break PPC guests. Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-pci.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index f5608140f9..a827cd41bf 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -86,6 +86,9 @@ * 12 is historical, and due to x86 page size. */ #define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12 +/* Flags track per-device state like workarounds for quirks in older guests. */ +#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG (1 << 0) + static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, VirtIOPCIProxy *dev); @@ -320,6 +323,14 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) proxy->pci_dev.config[PCI_COMMAND] | PCI_COMMAND_MASTER, 1); } + + /* Linux before 2.6.34 sets the device as OK without enabling + the PCI device bus master bit. In this case we need to disable + some safety checks. */ + if ((val & VIRTIO_CONFIG_S_DRIVER_OK) && + !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { + proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG; + } break; case VIRTIO_MSI_CONFIG_VECTOR: msix_vector_unuse(&proxy->pci_dev, vdev->config_vector); @@ -469,18 +480,13 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - uint8_t cmd = proxy->pci_dev.config[PCI_COMMAND]; - pci_default_write_config(pci_dev, address, val, len); if (range_covers_byte(address, len, PCI_COMMAND) && !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) && - (cmd & PCI_COMMAND_MASTER)) { - /* Bus driver disables bus mastering - make it act - * as a kind of reset to render the device quiescent. */ + !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) { virtio_pci_stop_ioeventfd(proxy); - virtio_reset(vdev); - msix_unuse_all_vectors(&proxy->pci_dev); + virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK); } } @@ -889,19 +895,11 @@ static void virtio_pci_vmstate_change(DeviceState *d, bool running) VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); if (running) { - /* Linux before 2.6.34 drives the device without enabling - the PCI device bus master bit. Enable it automatically - for the guest. This is a PCI spec violation but so is - initiating DMA with bus master bit clear. - Note: this only makes a difference when migrating - across QEMU versions from an old QEMU, as for new QEMU - bus master and driver bits are always in sync. - TODO: consider enabling conditionally for compat machine types. */ - if (vdev->status & (VIRTIO_CONFIG_S_ACKNOWLEDGE | - VIRTIO_CONFIG_S_DRIVER)) { - pci_default_write_config(&proxy->pci_dev, PCI_COMMAND, - proxy->pci_dev.config[PCI_COMMAND] | - PCI_COMMAND_MASTER, 1); + /* Try to find out if the guest has bus master disabled, but is + in ready state. Then we have a buggy guest OS. */ + if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) && + !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { + proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG; } virtio_pci_start_ioeventfd(proxy); } else { @@ -1042,6 +1040,7 @@ static void virtio_pci_reset(DeviceState *qdev) virtio_pci_stop_ioeventfd(proxy); virtio_bus_reset(bus); msix_unuse_all_vectors(&proxy->pci_dev); + proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG; } static Property virtio_pci_properties[] = { From 22b80e85ff7d6150beefe06bb43d9b14ac4deb05 Mon Sep 17 00:00:00 2001 From: Gonglei Date: Thu, 18 Sep 2014 21:06:17 +0800 Subject: [PATCH 3/5] pci-hotplug-old: avoid losing error message When scsi_bus_legacy_add_drive() produces an error, we will lose the error message. Using error_report to report it. Cc: Markus Armbruster Signed-off-by: Gonglei Reviewed-by: Markus Armbruster Reviewed-by: Eric Blake Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pci-hotplug-old.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c index cf2caebfb1..d87c469096 100644 --- a/hw/pci/pci-hotplug-old.c +++ b/hw/pci/pci-hotplug-old.c @@ -107,6 +107,7 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter, { SCSIBus *scsibus; SCSIDevice *scsidev; + Error *local_err = NULL; scsibus = (SCSIBus *) object_dynamic_cast(OBJECT(QLIST_FIRST(&adapter->child_bus)), @@ -127,8 +128,10 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter, dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1); dinfo->bus = scsibus->busnr; scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit, - false, -1, NULL, NULL); + false, -1, NULL, &local_err); if (!scsidev) { + error_report("%s", error_get_pretty(local_err)); + error_free(local_err); return -1; } dinfo->unit = scsidev->id; From fc50ff0666315be5120c70ad00cd0b0097484b84 Mon Sep 17 00:00:00 2001 From: zhanghailiang Date: Fri, 26 Sep 2014 17:16:12 +0800 Subject: [PATCH 4/5] pc-dimm: Don't check dimm->node when there is non-NUMA config It should not break memory hotplug feature if there is non-NUMA option. This patch would also allow to use pc-dimm as replacement for initial memory for non-NUMA configs. Note: After this patch, the memory hotplug can work normally for Linux guest OS when there is non-NUMA option and NUMA option. But not support Windows guest OS to hotplug memory with no-NUMA config, actully, it's Windows limitation. Reviewed-By: Igor Mammedov Signed-off-by: zhanghailiang Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/mem/pc-dimm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 5bfc5b7483..a800ea7a9f 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -252,7 +252,7 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp) error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set"); return; } - if (dimm->node >= nb_numa_nodes) { + if ((nb_numa_nodes > 0) && (dimm->node >= nb_numa_nodes)) { error_setg(errp, "'DIMM property " PC_DIMM_NODE_PROP " has value %" PRIu32 "' which exceeds the number of numa nodes: %d", dimm->node, nb_numa_nodes); From 28d16f38d0d5881f95b074cc802dae8cacc1bf58 Mon Sep 17 00:00:00 2001 From: zhanghailiang Date: Tue, 23 Sep 2014 18:42:24 +0800 Subject: [PATCH 5/5] vl: Adjust the place of calling mlockall to speedup VM's startup If we configure mlock=on and memory policy=bind at the same time, It will consume lots of time for system to treat with memory, especially when call mbind behind mlockall. Adjust the place of calling mlockall, calling mbind before mlockall can remarkably reduce the time of VM's startup. Acked-by: Michael S. Tsirkin Signed-off-by: zhanghailiang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- vl.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/vl.c b/vl.c index dbdca594b7..9d2aaaf1dc 100644 --- a/vl.c +++ b/vl.c @@ -134,6 +134,7 @@ const char* keyboard_layout = NULL; ram_addr_t ram_size; const char *mem_path = NULL; int mem_prealloc = 0; /* force preallocation of physical target memory */ +bool enable_mlock = false; int nb_nics; NICInfo nd_table[MAX_NICS]; int autostart; @@ -1421,12 +1422,8 @@ static void smp_parse(QemuOpts *opts) } -static void configure_realtime(QemuOpts *opts) +static void realtime_init(void) { - bool enable_mlock; - - enable_mlock = qemu_opt_get_bool(opts, "mlock", true); - if (enable_mlock) { if (os_mlock() < 0) { fprintf(stderr, "qemu: locking memory failed\n"); @@ -3974,7 +3971,7 @@ int main(int argc, char **argv, char **envp) if (!opts) { exit(1); } - configure_realtime(opts); + enable_mlock = qemu_opt_get_bool(opts, "mlock", true); break; case QEMU_OPTION_msg: opts = qemu_opts_parse(qemu_find_opts("msg"), optarg, 0); @@ -4442,6 +4439,8 @@ int main(int argc, char **argv, char **envp) machine_class->init(current_machine); + realtime_init(); + audio_init(); cpu_synchronize_all_post_init();