diff options
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | hw/core/machine.c | 21 | ||||
-rw-r--r-- | hw/intc/xics.c | 13 | ||||
-rw-r--r-- | hw/misc/macio/mac_dbdma.c | 25 | ||||
-rw-r--r-- | hw/nvram/fw_cfg.c | 20 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 2 | ||||
-rw-r--r-- | hw/ppc/spapr_events.c | 3 | ||||
-rw-r--r-- | hw/ppc/spapr_pci.c | 31 | ||||
-rw-r--r-- | hw/ppc/spapr_rng.c | 1 | ||||
-rw-r--r-- | hw/ppc/spapr_vio.c | 7 | ||||
-rw-r--r-- | include/hw/boards.h | 1 | ||||
-rw-r--r-- | include/hw/compat.h | 8 | ||||
-rw-r--r-- | include/hw/ppc/xics.h | 5 | ||||
-rw-r--r-- | include/ui/spice-display.h | 2 | ||||
-rw-r--r-- | migration/savevm.c | 10 | ||||
-rw-r--r-- | qemu-options.hx | 3 | ||||
-rw-r--r-- | trace-events | 2 |
17 files changed, 120 insertions, 36 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 423cfb3b3b..a5853cd7b6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1091,6 +1091,7 @@ SPICE M: Gerd Hoffmann <kraxel@redhat.com> S: Supported F: include/ui/qemu-spice.h +F: include/ui/spice-display.h F: ui/spice-*.c F: audio/spiceaudio.c F: hw/display/qxl* @@ -1099,6 +1100,7 @@ Graphics M: Gerd Hoffmann <kraxel@redhat.com> S: Odd Fixes F: ui/ +F: include/ui/ Cocoa graphics M: Andreas Färber <andreas.faerber@web.de> diff --git a/hw/core/machine.c b/hw/core/machine.c index 6d1a0d8eeb..a8c4680b0c 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -312,6 +312,21 @@ static bool machine_get_suppress_vmdesc(Object *obj, Error **errp) return ms->suppress_vmdesc; } +static void machine_set_enforce_config_section(Object *obj, bool value, + Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->enforce_config_section = value; +} + +static bool machine_get_enforce_config_section(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return ms->enforce_config_section; +} + static int error_on_sysbus_device(SysBusDevice *sbdev, void *opaque) { error_report("Option '-device %s' cannot be handled by this machine", @@ -467,6 +482,12 @@ static void machine_initfn(Object *obj) object_property_set_description(obj, "suppress-vmdesc", "Set on to disable self-describing migration", NULL); + object_property_add_bool(obj, "enforce-config-section", + machine_get_enforce_config_section, + machine_set_enforce_config_section, NULL); + object_property_set_description(obj, "enforce-config-section", + "Set on to enforce configuration section migration", + NULL); /* Register notifier when init is done for sysbus sanity checks */ ms->sysbus_notifier.notify = machine_init_notify; diff --git a/hw/intc/xics.c b/hw/intc/xics.c index e66ae32881..213a370925 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -712,7 +712,7 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum) return -1; } -int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi) +int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp) { ICSState *ics = &icp->ics[src]; int irq; @@ -720,14 +720,14 @@ int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi) if (irq_hint) { assert(src == xics_find_source(icp, irq_hint)); if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) { - trace_xics_alloc_failed_hint(src, irq_hint); + error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint); return -1; } irq = irq_hint; } else { irq = ics_find_free_block(ics, 1, 1); if (irq < 0) { - trace_xics_alloc_failed_no_left(src); + error_setg(errp, "can't allocate IRQ: no IRQ left"); return -1; } irq += ics->offset; @@ -743,7 +743,8 @@ int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi) * Allocate block of consecutive IRQs, and return the number of the first IRQ in the block. * If align==true, aligns the first IRQ number to num. */ -int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align) +int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align, + Error **errp) { int i, first = -1; ICSState *ics = &icp->ics[src]; @@ -763,6 +764,10 @@ int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align) } else { first = ics_find_free_block(ics, num, 1); } + if (first < 0) { + error_setg(errp, "can't find a free %d-IRQ block", num); + return -1; + } if (first >= 0) { for (i = first; i < first + num; ++i) { diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index d81dea7b0d..6051f17dbd 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -557,11 +557,13 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, DBDMA_DPRINTF("DBDMA_register_channel 0x%x\n", nchan); + assert(rw); + assert(flush); + ch->irq = irq; ch->rw = rw; ch->flush = flush; ch->io.opaque = opaque; - ch->io.channel = ch; } static void @@ -775,6 +777,20 @@ static void dbdma_reset(void *opaque) memset(s->channels[i].regs, 0, DBDMA_SIZE); } +static void dbdma_unassigned_rw(DBDMA_io *io) +{ + DBDMA_channel *ch = io->channel; + qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n", + __func__, ch->channel); +} + +static void dbdma_unassigned_flush(DBDMA_io *io) +{ + DBDMA_channel *ch = io->channel; + qemu_log_mask(LOG_GUEST_ERROR, "%s: use of unassigned channel %d\n", + __func__, ch->channel); +} + void* DBDMA_init (MemoryRegion **dbdma_mem) { DBDMAState *s; @@ -784,8 +800,13 @@ void* DBDMA_init (MemoryRegion **dbdma_mem) for (i = 0; i < DBDMA_CHANNELS; i++) { DBDMA_io *io = &s->channels[i].io; + DBDMA_channel *ch = &s->channels[i]; qemu_iovec_init(&io->iov, 1); - s->channels[i].channel = i; + + ch->rw = dbdma_unassigned_rw; + ch->flush = dbdma_unassigned_flush; + ch->channel = i; + ch->io.channel = ch; } memory_region_init_io(&s->mem, NULL, &dbdma_ops, s, "dbdma", 0x1000); diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 79c5742b33..f3acb47bd4 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -778,17 +778,19 @@ FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase, DeviceState *dev; FWCfgState *s; uint32_t version = FW_CFG_VERSION; - bool dma_enabled = dma_iobase && dma_as; + bool dma_requested = dma_iobase && dma_as; dev = qdev_create(NULL, TYPE_FW_CFG_IO); qdev_prop_set_uint32(dev, "iobase", iobase); qdev_prop_set_uint32(dev, "dma_iobase", dma_iobase); - qdev_prop_set_bit(dev, "dma_enabled", dma_enabled); + if (!dma_requested) { + qdev_prop_set_bit(dev, "dma_enabled", false); + } fw_cfg_init1(dev); s = FW_CFG(dev); - if (dma_enabled) { + if (s->dma_enabled) { /* 64 bits for the address field */ s->dma_as = dma_as; s->dma_addr = 0; @@ -814,11 +816,13 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr, SysBusDevice *sbd; FWCfgState *s; uint32_t version = FW_CFG_VERSION; - bool dma_enabled = dma_addr && dma_as; + bool dma_requested = dma_addr && dma_as; dev = qdev_create(NULL, TYPE_FW_CFG_MEM); qdev_prop_set_uint32(dev, "data_width", data_width); - qdev_prop_set_bit(dev, "dma_enabled", dma_enabled); + if (!dma_requested) { + qdev_prop_set_bit(dev, "dma_enabled", false); + } fw_cfg_init1(dev); @@ -828,7 +832,7 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr, s = FW_CFG(dev); - if (dma_enabled) { + if (s->dma_enabled) { s->dma_as = dma_as; s->dma_addr = 0; sysbus_mmio_map(sbd, 2, dma_addr); @@ -873,7 +877,7 @@ static Property fw_cfg_io_properties[] = { DEFINE_PROP_UINT32("iobase", FWCfgIoState, iobase, -1), DEFINE_PROP_UINT32("dma_iobase", FWCfgIoState, dma_iobase, -1), DEFINE_PROP_BOOL("dma_enabled", FWCfgIoState, parent_obj.dma_enabled, - false), + true), DEFINE_PROP_END_OF_LIST(), }; @@ -913,7 +917,7 @@ static const TypeInfo fw_cfg_io_info = { static Property fw_cfg_mem_properties[] = { DEFINE_PROP_UINT32("data_width", FWCfgMemState, data_width, -1), DEFINE_PROP_BOOL("dma_enabled", FWCfgMemState, parent_obj.dma_enabled, - false), + true), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c119f55824..e9d4abf06a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2427,6 +2427,7 @@ static void spapr_machine_2_3_instance_options(MachineState *machine) spapr_machine_2_4_instance_options(machine); savevm_skip_section_footers(); global_state_set_optional(); + savevm_skip_configuration(); } static void spapr_machine_2_3_class_options(MachineClass *mc) @@ -2452,6 +2453,7 @@ DEFINE_SPAPR_MACHINE(2_3, "2.3", false); static void spapr_machine_2_2_instance_options(MachineState *machine) { spapr_machine_2_3_instance_options(machine); + machine->suppress_vmdesc = true; } static void spapr_machine_2_2_class_options(MachineClass *mc) diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index f5eac4b544..39f4682f95 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -588,7 +588,8 @@ out_no_events: void spapr_events_init(sPAPRMachineState *spapr) { QTAILQ_INIT(&spapr->pending_events); - spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false); + spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false, + &error_fatal); spapr->epow_notifier.notify = spapr_powerdown_req; qemu_register_powerdown_notifier(&spapr->epow_notifier); spapr_rtas_register(RTAS_CHECK_EXCEPTION, "check-exception", diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index cca9257fec..e8edad3ab7 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -275,11 +275,12 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, unsigned int req_num = rtas_ld(args, 4); /* 0 == remove all */ unsigned int seq_num = rtas_ld(args, 5); unsigned int ret_intr_type; - unsigned int irq, max_irqs = 0, num = 0; + unsigned int irq, max_irqs = 0; sPAPRPHBState *phb = NULL; PCIDevice *pdev = NULL; spapr_pci_msi *msi; int *config_addr_key; + Error *err = NULL; switch (func) { case RTAS_CHANGE_MSI_FN: @@ -305,9 +306,10 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, return; } + msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr); + /* Releasing MSIs */ if (!req_num) { - msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr); if (!msi) { trace_spapr_pci_msi("Releasing wrong config", config_addr); rtas_st(rets, 0, RTAS_OUT_HW_ERROR); @@ -316,10 +318,10 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, xics_free(spapr->icp, msi->first_irq, msi->num); if (msi_present(pdev)) { - spapr_msi_setmsg(pdev, 0, false, 0, num); + spapr_msi_setmsg(pdev, 0, false, 0, 0); } if (msix_present(pdev)) { - spapr_msi_setmsg(pdev, 0, true, 0, num); + spapr_msi_setmsg(pdev, 0, true, 0, 0); } g_hash_table_remove(phb->msi, &config_addr); @@ -353,13 +355,20 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, /* Allocate MSIs */ irq = xics_alloc_block(spapr->icp, 0, req_num, false, - ret_intr_type == RTAS_TYPE_MSI); - if (!irq) { - error_report("Cannot allocate MSIs for device %x", config_addr); + ret_intr_type == RTAS_TYPE_MSI, &err); + if (err) { + error_reportf_err(err, "Can't allocate MSIs for device %x: ", + config_addr); rtas_st(rets, 0, RTAS_OUT_HW_ERROR); return; } + /* Release previous MSIs */ + if (msi) { + xics_free(spapr->icp, msi->first_irq, msi->num); + g_hash_table_remove(phb->msi, &config_addr); + } + /* Setup MSI/MSIX vectors in the device (via cfgspace or MSIX BAR) */ spapr_msi_setmsg(pdev, SPAPR_PCI_MSI_WINDOW, ret_intr_type == RTAS_TYPE_MSIX, irq, req_num); @@ -1360,10 +1369,12 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) /* Initialize the LSI table */ for (i = 0; i < PCI_NUM_PINS; i++) { uint32_t irq; + Error *local_err = NULL; - irq = xics_alloc_block(spapr->icp, 0, 1, true, false); - if (!irq) { - error_setg(errp, "spapr_allocate_lsi failed"); + irq = xics_alloc_block(spapr->icp, 0, 1, true, false, &local_err); + if (local_err) { + error_propagate(errp, local_err); + error_prepend(errp, "can't allocate LSIs: "); return; } diff --git a/hw/ppc/spapr_rng.c b/hw/ppc/spapr_rng.c index 8484fcf547..a39d472b66 100644 --- a/hw/ppc/spapr_rng.c +++ b/hw/ppc/spapr_rng.c @@ -170,6 +170,7 @@ static void spapr_rng_class_init(ObjectClass *oc, void *data) dc->realize = spapr_rng_realize; set_bit(DEVICE_CATEGORY_MISC, dc->categories); dc->props = spapr_rng_properties; + dc->hotpluggable = false; } static const TypeInfo spapr_rng_info = { diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index ac6666a90b..0f61a550cb 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -431,6 +431,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev; VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev); char *id; + Error *local_err = NULL; if (dev->reg != -1) { /* @@ -463,9 +464,9 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) dev->qdev.id = id; } - dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false); - if (!dev->irq) { - error_setg(errp, "can't allocate IRQ"); + dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false, &local_err); + if (local_err) { + error_propagate(errp, local_err); return; } diff --git a/include/hw/boards.h b/include/hw/boards.h index de3b3bdafd..b5d7eae3f3 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -127,6 +127,7 @@ struct MachineState { char *firmware; bool iommu; bool suppress_vmdesc; + bool enforce_config_section; ram_addr_t ram_size; ram_addr_t maxram_size; diff --git a/include/hw/compat.h b/include/hw/compat.h index 2ebe739fcb..a5dbbf8984 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -42,6 +42,14 @@ .driver = "virtio-pci",\ .property = "migrate-extra",\ .value = "off",\ + },{\ + .driver = "fw_cfg_mem",\ + .property = "dma_enabled",\ + .value = "off",\ + },{\ + .driver = "fw_cfg_io",\ + .property = "dma_enabled",\ + .value = "off",\ }, #define HW_COMPAT_2_3 \ diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 355a96623c..f60b06ae82 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -161,8 +161,9 @@ struct ICSIRQState { qemu_irq xics_get_qirq(XICSState *icp, int irq); void xics_set_irq_type(XICSState *icp, int irq, bool lsi); -int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi); -int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align); +int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp); +int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align, + Error **errp); void xics_free(XICSState *icp, int irq, int num); void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu); diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h index 69a222b543..30ccfe3dab 100644 --- a/include/ui/spice-display.h +++ b/include/ui/spice-display.h @@ -25,7 +25,7 @@ #include "sysemu/sysemu.h" #if defined(CONFIG_OPENGL_DMABUF) -# if SPICE_SERVER_VERSION >= 0x000d00 /* release 0.13.0 */ +# if SPICE_SERVER_VERSION >= 0x000d01 /* release 0.13.1 */ # define HAVE_SPICE_GL 1 # include "ui/egl-helpers.h" # include "ui/egl-context.h" diff --git a/migration/savevm.c b/migration/savevm.c index b45915612f..96e7db5967 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -878,13 +878,19 @@ bool qemu_savevm_state_blocked(Error **errp) return false; } +static bool enforce_config_section(void) +{ + MachineState *machine = MACHINE(qdev_get_machine()); + return machine->enforce_config_section; +} + void qemu_savevm_state_header(QEMUFile *f) { trace_savevm_state_header(); qemu_put_be32(f, QEMU_VM_FILE_MAGIC); qemu_put_be32(f, QEMU_VM_FILE_VERSION); - if (!savevm_state.skip_configuration) { + if (!savevm_state.skip_configuration || enforce_config_section()) { qemu_put_byte(f, QEMU_VM_CONFIGURATION); vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0); } @@ -1883,7 +1889,7 @@ int qemu_loadvm_state(QEMUFile *f) return -ENOTSUP; } - if (!savevm_state.skip_configuration) { + if (!savevm_state.skip_configuration || enforce_config_section()) { if (qemu_get_byte(f) != QEMU_VM_CONFIGURATION) { error_report("Configuration section missing"); return -EINVAL; diff --git a/qemu-options.hx b/qemu-options.hx index 599db9474c..144e6a9b76 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -43,7 +43,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ " aes-key-wrap=on|off controls support for AES key wrapping (default=on)\n" " dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n" " suppress-vmdesc=on|off disables self-describing migration (default=off)\n" - " nvdimm=on|off controls NVDIMM support (default=off)\n", + " nvdimm=on|off controls NVDIMM support (default=off)\n" + " enforce-config-section=on|off enforce configuration section migration (default=off)\n", QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]] diff --git a/trace-events b/trace-events index 61a133f6ee..075ec27100 100644 --- a/trace-events +++ b/trace-events @@ -1409,8 +1409,6 @@ xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_ xics_ics_reject(int nr, int srcno) "reject irq %#x [src %d]" xics_ics_eoi(int nr) "ics_eoi: irq %#x" xics_alloc(int src, int irq) "source#%d, irq %d" -xics_alloc_failed_hint(int src, int irq) "source#%d, irq %d is already in use" -xics_alloc_failed_no_left(int src) "source#%d, no irq left" xics_alloc_block(int src, int first, int num, bool lsi, int align) "source#%d, first irq %d, %d irqs, lsi=%d, alignnum %d" xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs" xics_ics_free_warn(int src, int irq) "Source#%d, irq %d is already free" |