diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/arm/fsl-imx6ul.c | 64 | ||||
| -rw-r--r-- | hw/arm/mcimx6ul-evk.c | 2 | ||||
| -rw-r--r-- | hw/block/pflash_cfi01.c | 19 | ||||
| -rw-r--r-- | hw/block/pflash_cfi02.c | 2 | ||||
| -rw-r--r-- | hw/i386/Kconfig | 4 | ||||
| -rw-r--r-- | hw/i386/acpi-build.c | 17 | ||||
| -rw-r--r-- | hw/intc/ioapic.c | 8 | ||||
| -rw-r--r-- | hw/scsi/virtio-scsi.c | 7 | ||||
| -rw-r--r-- | hw/virtio/virtio-balloon.c | 115 |
9 files changed, 120 insertions, 118 deletions
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c index f860165438..b074177a71 100644 --- a/hw/arm/fsl-imx6ul.c +++ b/hw/arm/fsl-imx6ul.c @@ -29,16 +29,12 @@ static void fsl_imx6ul_init(Object *obj) { - MachineState *ms = MACHINE(qdev_get_machine()); FslIMX6ULState *s = FSL_IMX6UL(obj); char name[NAME_SIZE]; int i; - for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX6UL_NUM_CPUS); i++) { - snprintf(name, NAME_SIZE, "cpu%d", i); - object_initialize_child(obj, name, &s->cpu[i], sizeof(s->cpu[i]), - "cortex-a7-" TYPE_ARM_CPU, &error_abort, NULL); - } + object_initialize_child(obj, "cpu0", &s->cpu, sizeof(s->cpu), + "cortex-a7-" TYPE_ARM_CPU, &error_abort, NULL); /* * A7MPCORE @@ -161,42 +157,25 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) MachineState *ms = MACHINE(qdev_get_machine()); FslIMX6ULState *s = FSL_IMX6UL(dev); int i; - qemu_irq irq; char name[NAME_SIZE]; - unsigned int smp_cpus = ms->smp.cpus; + SysBusDevice *sbd; + DeviceState *d; - if (smp_cpus > FSL_IMX6UL_NUM_CPUS) { - error_setg(errp, "%s: Only %d CPUs are supported (%d requested)", - TYPE_FSL_IMX6UL, FSL_IMX6UL_NUM_CPUS, smp_cpus); + if (ms->smp.cpus > 1) { + error_setg(errp, "%s: Only a single CPU is supported (%d requested)", + TYPE_FSL_IMX6UL, ms->smp.cpus); return; } - for (i = 0; i < smp_cpus; i++) { - Object *o = OBJECT(&s->cpu[i]); - - object_property_set_int(o, QEMU_PSCI_CONDUIT_SMC, - "psci-conduit", &error_abort); - - /* On uniprocessor, the CBAR is set to 0 */ - if (smp_cpus > 1) { - object_property_set_int(o, FSL_IMX6UL_A7MPCORE_ADDR, - "reset-cbar", &error_abort); - } - - if (i) { - /* Secondary CPUs start in PSCI powered-down state */ - object_property_set_bool(o, true, - "start-powered-off", &error_abort); - } - - object_property_set_bool(o, true, "realized", &error_abort); - } + object_property_set_int(OBJECT(&s->cpu), QEMU_PSCI_CONDUIT_SMC, + "psci-conduit", &error_abort); + object_property_set_bool(OBJECT(&s->cpu), true, + "realized", &error_abort); /* * A7MPCORE */ - object_property_set_int(OBJECT(&s->a7mpcore), smp_cpus, "num-cpu", - &error_abort); + object_property_set_int(OBJECT(&s->a7mpcore), 1, "num-cpu", &error_abort); object_property_set_int(OBJECT(&s->a7mpcore), FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL, "num-irq", &error_abort); @@ -204,18 +183,13 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp) &error_abort); sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR); - for (i = 0; i < smp_cpus; i++) { - SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore); - DeviceState *d = DEVICE(qemu_get_cpu(i)); - - irq = qdev_get_gpio_in(d, ARM_CPU_IRQ); - sysbus_connect_irq(sbd, i, irq); - sysbus_connect_irq(sbd, i + smp_cpus, qdev_get_gpio_in(d, ARM_CPU_FIQ)); - sysbus_connect_irq(sbd, i + 2 * smp_cpus, - qdev_get_gpio_in(d, ARM_CPU_VIRQ)); - sysbus_connect_irq(sbd, i + 3 * smp_cpus, - qdev_get_gpio_in(d, ARM_CPU_VFIQ)); - } + sbd = SYS_BUS_DEVICE(&s->a7mpcore); + d = DEVICE(&s->cpu); + + sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(d, ARM_CPU_IRQ)); + sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(d, ARM_CPU_FIQ)); + sysbus_connect_irq(sbd, 2, qdev_get_gpio_in(d, ARM_CPU_VIRQ)); + sysbus_connect_irq(sbd, 3, qdev_get_gpio_in(d, ARM_CPU_VFIQ)); /* * A7MPCORE DAP diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c index bbffb11c2a..1f6f4aed97 100644 --- a/hw/arm/mcimx6ul-evk.c +++ b/hw/arm/mcimx6ul-evk.c @@ -71,7 +71,7 @@ static void mcimx6ul_evk_init(MachineState *machine) } if (!qtest_enabled()) { - arm_load_kernel(&s->soc.cpu[0], &boot_info); + arm_load_kernel(&s->soc.cpu, &boot_info); } } diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 435be1e35c..a1ec1faae5 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -865,6 +865,24 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */ } +static void pflash_cfi01_system_reset(DeviceState *dev) +{ + PFlashCFI01 *pfl = PFLASH_CFI01(dev); + + /* + * The command 0x00 is not assigned by the CFI open standard, + * but QEMU historically uses it for the READ_ARRAY command (0xff). + */ + pfl->cmd = 0x00; + pfl->wcycle = 0; + memory_region_rom_device_set_romd(&pfl->mem, true); + /* + * The WSM ready timer occurs at most 150ns after system reset. + * This model deliberately ignores this delay. + */ + pfl->status = 0x80; +} + static Property pflash_cfi01_properties[] = { DEFINE_PROP_DRIVE("drive", PFlashCFI01, blk), /* num-blocks is the number of blocks actually visible to the guest, @@ -909,6 +927,7 @@ static void pflash_cfi01_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->reset = pflash_cfi01_system_reset; dc->realize = pflash_cfi01_realize; dc->props = pflash_cfi01_properties; dc->vmsd = &vmstate_pflash; diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index f68837a449..42886f6af5 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -577,7 +577,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value, pfl->cmd = 0x98; return; } - /* No break here */ + /* fall through */ default: DPRINTF("%s: invalid write for command %02x\n", __func__, pfl->cmd); diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index b9c96ac361..6350438036 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -52,6 +52,7 @@ config I440FX bool imply E1000_PCI imply VMPORT + imply VMMOUSE select PC_PCI select PC_ACPI select ACPI_SMBUS @@ -59,7 +60,6 @@ config I440FX select IDE_PIIX select DIMM select SMBIOS - select VMMOUSE select FW_CFG_DMA config ISAPC @@ -78,6 +78,7 @@ config Q35 imply AMD_IOMMU imply E1000E_PCI_EXPRESS imply VMPORT + imply VMMOUSE select PC_PCI select PC_ACPI select PCI_EXPRESS_Q35 @@ -85,7 +86,6 @@ config Q35 select AHCI_ICH9 select DIMM select SMBIOS - select VMMOUSE select FW_CFG_DMA config VTD diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index d281ffa89e..f3fdfefcd5 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -755,10 +755,16 @@ static void crs_range_set_free(CrsRangeSet *range_set) static gint crs_range_compare(gconstpointer a, gconstpointer b) { - CrsRangeEntry *entry_a = *(CrsRangeEntry **)a; - CrsRangeEntry *entry_b = *(CrsRangeEntry **)b; + CrsRangeEntry *entry_a = *(CrsRangeEntry **)a; + CrsRangeEntry *entry_b = *(CrsRangeEntry **)b; - return (int64_t)entry_a->base - (int64_t)entry_b->base; + if (entry_a->base < entry_b->base) { + return -1; + } else if (entry_a->base > entry_b->base) { + return 1; + } else { + return 0; + } } /* @@ -1908,10 +1914,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, scope = aml_scope("\\_SB"); dev = aml_device("PC%.02X", bus_num); aml_append(dev, aml_name_decl("_UID", aml_int(bus_num))); - aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num))); if (pci_bus_is_express(bus)) { + aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); + aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); aml_append(dev, build_q35_osc_method()); + } else { + aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); } if (numa_node != NUMA_NODE_UNASSIGNED) { diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c index c408749876..e99c37cceb 100644 --- a/hw/intc/ioapic.c +++ b/hw/intc/ioapic.c @@ -197,9 +197,11 @@ static void ioapic_update_kvm_routes(IOAPICCommonState *s) MSIMessage msg; struct ioapic_entry_info info; ioapic_entry_parse(s->ioredtbl[i], &info); - msg.address = info.addr; - msg.data = info.data; - kvm_irqchip_update_msi_route(kvm_state, i, msg, NULL); + if (!info.masked) { + msg.address = info.addr; + msg.data = info.data; + kvm_irqchip_update_msi_route(kvm_state, i, msg, NULL); + } } kvm_irqchip_commit_routes(kvm_state); } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index d0bdbff090..8b9e5e2b49 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -832,6 +832,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev); VirtIOSCSI *s = VIRTIO_SCSI(vdev); SCSIDevice *sd = SCSI_DEVICE(dev); + AioContext *ctx = s->ctx ?: qemu_get_aio_context(); if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) { virtio_scsi_acquire(s); @@ -841,14 +842,16 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, virtio_scsi_release(s); } + aio_disable_external(ctx); + qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); + aio_enable_external(ctx); + if (s->ctx) { virtio_scsi_acquire(s); /* If other users keep the BlockBackend in the iothread, that's ok */ blk_set_aio_context(sd->conf.blk, qemu_get_aio_context(), NULL); virtio_scsi_release(s); } - - qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); } static struct SCSIBusInfo virtio_scsi_scsi_info = { diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index e85d1c0d5c..25de154307 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -34,31 +34,53 @@ #define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT) -struct PartiallyBalloonedPage { - RAMBlock *rb; - ram_addr_t base; - unsigned long bitmap[]; -}; +typedef struct PartiallyBalloonedPage { + ram_addr_t base_gpa; + unsigned long *bitmap; +} PartiallyBalloonedPage; + +static void virtio_balloon_pbp_free(PartiallyBalloonedPage *pbp) +{ + if (!pbp->bitmap) { + return; + } + g_free(pbp->bitmap); + pbp->bitmap = NULL; +} + +static void virtio_balloon_pbp_alloc(PartiallyBalloonedPage *pbp, + ram_addr_t base_gpa, + long subpages) +{ + pbp->base_gpa = base_gpa; + pbp->bitmap = bitmap_new(subpages); +} + +static bool virtio_balloon_pbp_matches(PartiallyBalloonedPage *pbp, + ram_addr_t base_gpa) +{ + return pbp->base_gpa == base_gpa; +} static void balloon_inflate_page(VirtIOBalloon *balloon, - MemoryRegion *mr, hwaddr offset) + MemoryRegion *mr, hwaddr mr_offset, + PartiallyBalloonedPage *pbp) { - void *addr = memory_region_get_ram_ptr(mr) + offset; + void *addr = memory_region_get_ram_ptr(mr) + mr_offset; + ram_addr_t rb_offset, rb_aligned_offset, base_gpa; RAMBlock *rb; size_t rb_page_size; int subpages; - ram_addr_t ram_offset, host_page_base; /* XXX is there a better way to get to the RAMBlock than via a * host address? */ - rb = qemu_ram_block_from_host(addr, false, &ram_offset); + rb = qemu_ram_block_from_host(addr, false, &rb_offset); rb_page_size = qemu_ram_pagesize(rb); - host_page_base = ram_offset & ~(rb_page_size - 1); if (rb_page_size == BALLOON_PAGE_SIZE) { /* Easy case */ - ram_block_discard_range(rb, ram_offset, rb_page_size); + ram_block_discard_range(rb, rb_offset, rb_page_size); /* We ignore errors from ram_block_discard_range(), because it * has already reported them, and failing to discard a balloon * page is not fatal */ @@ -74,81 +96,51 @@ static void balloon_inflate_page(VirtIOBalloon *balloon, warn_report_once( "Balloon used with backing page size > 4kiB, this may not be reliable"); + rb_aligned_offset = QEMU_ALIGN_DOWN(rb_offset, rb_page_size); subpages = rb_page_size / BALLOON_PAGE_SIZE; + base_gpa = memory_region_get_ram_addr(mr) + mr_offset - + (rb_offset - rb_aligned_offset); - if (balloon->pbp - && (rb != balloon->pbp->rb - || host_page_base != balloon->pbp->base)) { + if (pbp->bitmap && !virtio_balloon_pbp_matches(pbp, base_gpa)) { /* We've partially ballooned part of a host page, but now * we're trying to balloon part of a different one. Too hard, * give up on the old partial page */ - g_free(balloon->pbp); - balloon->pbp = NULL; + virtio_balloon_pbp_free(pbp); } - if (!balloon->pbp) { - /* Starting on a new host page */ - size_t bitlen = BITS_TO_LONGS(subpages) * sizeof(unsigned long); - balloon->pbp = g_malloc0(sizeof(PartiallyBalloonedPage) + bitlen); - balloon->pbp->rb = rb; - balloon->pbp->base = host_page_base; + if (!pbp->bitmap) { + virtio_balloon_pbp_alloc(pbp, base_gpa, subpages); } - bitmap_set(balloon->pbp->bitmap, - (ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, - subpages); + set_bit((rb_offset - rb_aligned_offset) / BALLOON_PAGE_SIZE, + pbp->bitmap); - if (bitmap_full(balloon->pbp->bitmap, subpages)) { + if (bitmap_full(pbp->bitmap, subpages)) { /* We've accumulated a full host page, we can actually discard * it now */ - ram_block_discard_range(rb, balloon->pbp->base, rb_page_size); + ram_block_discard_range(rb, rb_aligned_offset, rb_page_size); /* We ignore errors from ram_block_discard_range(), because it * has already reported them, and failing to discard a balloon * page is not fatal */ - - g_free(balloon->pbp); - balloon->pbp = NULL; + virtio_balloon_pbp_free(pbp); } } static void balloon_deflate_page(VirtIOBalloon *balloon, - MemoryRegion *mr, hwaddr offset) + MemoryRegion *mr, hwaddr mr_offset) { - void *addr = memory_region_get_ram_ptr(mr) + offset; + void *addr = memory_region_get_ram_ptr(mr) + mr_offset; + ram_addr_t rb_offset; RAMBlock *rb; size_t rb_page_size; - ram_addr_t ram_offset, host_page_base; void *host_addr; int ret; /* XXX is there a better way to get to the RAMBlock than via a * host address? */ - rb = qemu_ram_block_from_host(addr, false, &ram_offset); + rb = qemu_ram_block_from_host(addr, false, &rb_offset); rb_page_size = qemu_ram_pagesize(rb); - host_page_base = ram_offset & ~(rb_page_size - 1); - - if (balloon->pbp - && rb == balloon->pbp->rb - && host_page_base == balloon->pbp->base) { - int subpages = rb_page_size / BALLOON_PAGE_SIZE; - - /* - * This means the guest has asked to discard some of the 4kiB - * subpages of a host page, but then changed its mind and - * asked to keep them after all. It's exceedingly unlikely - * for a guest to do this in practice, but handle it anyway, - * since getting it wrong could mean discarding memory the - * guest is still using. */ - bitmap_clear(balloon->pbp->bitmap, - (ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, - subpages); - - if (bitmap_empty(balloon->pbp->bitmap, subpages)) { - g_free(balloon->pbp); - balloon->pbp = NULL; - } - } host_addr = (void *)((uintptr_t)addr & ~(rb_page_size - 1)); @@ -335,16 +327,18 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) MemoryRegionSection section; for (;;) { + PartiallyBalloonedPage pbp = {}; size_t offset = 0; uint32_t pfn; + elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); if (!elem) { - return; + break; } while (iov_to_buf(elem->out_sg, elem->out_num, offset, &pfn, 4) == 4) { + unsigned int p = virtio_ldl_p(vdev, &pfn); hwaddr pa; - int p = virtio_ldl_p(vdev, &pfn); pa = (hwaddr) p << VIRTIO_BALLOON_PFN_SHIFT; offset += 4; @@ -368,7 +362,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) if (!qemu_balloon_is_inhibited()) { if (vq == s->ivq) { balloon_inflate_page(s, section.mr, - section.offset_within_region); + section.offset_within_region, &pbp); } else if (vq == s->dvq) { balloon_deflate_page(s, section.mr, section.offset_within_region); } else { @@ -381,6 +375,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) virtqueue_push(vq, elem, offset); virtio_notify(vdev, vq); g_free(elem); + virtio_balloon_pbp_free(&pbp); } } |