diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/i386/pc.c | 14 | ||||
-rw-r--r-- | hw/mem/nvdimm.c | 2 | ||||
-rw-r--r-- | hw/mem/pc-dimm.c | 14 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 42 | ||||
-rw-r--r-- | hw/ppc/spapr_drc.c | 30 | ||||
-rw-r--r-- | hw/ppc/spapr_iommu.c | 2 | ||||
-rw-r--r-- | hw/ppc/spapr_rtc.c | 2 |
7 files changed, 81 insertions, 25 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 5943539..2108104 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1691,10 +1691,15 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm); + MemoryRegion *mr; uint64_t align = TARGET_PAGE_SIZE; bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM); + mr = ddc->get_memory_region(dimm, &local_err); + if (local_err) { + goto out; + } + if (memory_region_get_alignment(mr) && pcmc->enforce_aligned_dimm) { align = memory_region_get_alignment(mr); } @@ -1758,10 +1763,15 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev, PCMachineState *pcms = PC_MACHINE(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm); + MemoryRegion *mr; HotplugHandlerClass *hhc; Error *local_err = NULL; + mr = ddc->get_memory_region(dimm, &local_err); + if (local_err) { + goto out; + } + hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc->unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c index db896b0..952fce5 100644 --- a/hw/mem/nvdimm.c +++ b/hw/mem/nvdimm.c @@ -71,7 +71,7 @@ static void nvdimm_init(Object *obj) NULL, NULL); } -static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm) +static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp) { NVDIMMDevice *nvdimm = NVDIMM(dimm); diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index ea67b46..bdf6649 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -363,7 +363,10 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name, PCDIMMDevice *dimm = PC_DIMM(obj); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj); - mr = ddc->get_memory_region(dimm); + mr = ddc->get_memory_region(dimm, errp); + if (!mr) { + return; + } value = memory_region_size(mr); visit_type_uint64(v, name, &value, errp); @@ -411,9 +414,14 @@ static void pc_dimm_unrealize(DeviceState *dev, Error **errp) host_memory_backend_set_mapped(dimm->hostmem, false); } -static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm) +static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm, Error **errp) { - return host_memory_backend_get_memory(dimm->hostmem, &error_abort); + if (!dimm->hostmem) { + error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property must be set"); + return NULL; + } + + return host_memory_backend_get_memory(dimm->hostmem, errp); } static MemoryRegion *pc_dimm_get_vmstate_memory_region(PCDIMMDevice *dimm) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f7a1972..cec441c 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2772,10 +2772,15 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm); - uint64_t align = memory_region_get_alignment(mr); - uint64_t size = memory_region_size(mr); - uint64_t addr; + MemoryRegion *mr; + uint64_t align, size, addr; + + mr = ddc->get_memory_region(dimm, &local_err); + if (local_err) { + goto out; + } + align = memory_region_get_alignment(mr); + size = memory_region_size(mr); pc_dimm_memory_plug(dev, &ms->hotplug_memory, mr, align, &local_err); if (local_err) { @@ -2808,10 +2813,16 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, { PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm); - uint64_t size = memory_region_size(mr); + MemoryRegion *mr; + uint64_t size; char *mem_dev; + mr = ddc->get_memory_region(dimm, errp); + if (!mr) { + return; + } + size = memory_region_size(mr); + if (size % SPAPR_MEMORY_BLOCK_SIZE) { error_setg(errp, "Hotplugged memory size must be a multiple of " "%lld MB", SPAPR_MEMORY_BLOCK_SIZE / M_BYTE); @@ -2882,7 +2893,7 @@ static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms, { sPAPRDRConnector *drc; PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm); + MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort); uint64_t size = memory_region_size(mr); uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE; uint32_t avail_lmbs = 0; @@ -2912,7 +2923,7 @@ void spapr_lmb_release(DeviceState *dev) sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_hotplug_handler(dev)); PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm); + MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort); sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev)); /* This information will get lost if a migration occurs @@ -2945,12 +2956,19 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev, Error *local_err = NULL; PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm); - uint64_t size = memory_region_size(mr); - uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE; - uint64_t addr_start, addr; + MemoryRegion *mr; + uint32_t nr_lmbs; + uint64_t size, addr_start, addr; int i; sPAPRDRConnector *drc; + + mr = ddc->get_memory_region(dimm, &local_err); + if (local_err) { + goto out; + } + size = memory_region_size(mr); + nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE; + addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err); if (local_err) { diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 5260b5d..605697d 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -442,12 +442,17 @@ void spapr_drc_reset(sPAPRDRConnector *drc) if (drc->dev) { /* A device present at reset is ready to go, same as coldplugged */ drc->state = drck->ready_state; + /* + * Ensure that we are able to send the FDT fragment again + * via configure-connector call if the guest requests. + */ + drc->ccs_offset = drc->fdt_start_offset; + drc->ccs_depth = 0; } else { drc->state = drck->empty_state; + drc->ccs_offset = -1; + drc->ccs_depth = -1; } - - drc->ccs_offset = -1; - drc->ccs_depth = -1; } static void drc_reset(void *opaque) @@ -1071,8 +1076,14 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu, } if ((drc->state != SPAPR_DRC_STATE_LOGICAL_UNISOLATE) - && (drc->state != SPAPR_DRC_STATE_PHYSICAL_UNISOLATE)) { - /* Need to unisolate the device before configuring */ + && (drc->state != SPAPR_DRC_STATE_PHYSICAL_UNISOLATE) + && (drc->state != SPAPR_DRC_STATE_LOGICAL_CONFIGURED) + && (drc->state != SPAPR_DRC_STATE_PHYSICAL_CONFIGURED)) { + /* + * Need to unisolate the device before configuring + * or it should already be in configured state to + * allow configure-connector be called repeatedly. + */ rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE; goto out; } @@ -1108,8 +1119,13 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu, /* done sending the device tree, move to configured state */ trace_spapr_drc_set_configured(drc_index); drc->state = drck->ready_state; - drc->ccs_offset = -1; - drc->ccs_depth = -1; + /* + * Ensure that we are able to send the FDT fragment + * again via configure-connector call if the guest requests. + */ + drc->ccs_offset = drc->fdt_start_offset; + drc->ccs_depth = 0; + fdt_offset_next = drc->fdt_start_offset; resp = SPAPR_DR_CC_RESPONSE_SUCCESS; } else { resp = SPAPR_DR_CC_RESPONSE_PREV_PARENT; diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index e614621..ed2d535 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -618,6 +618,8 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data) dc->init = spapr_tce_table_realize; dc->reset = spapr_tce_reset; dc->unrealize = spapr_tce_table_unrealize; + /* Reason: This is just an internal device for handling the hypercalls */ + dc->user_creatable = false; QLIST_INIT(&spapr_tce_tables); diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c index 00a4e4c..9ec3078 100644 --- a/hw/ppc/spapr_rtc.c +++ b/hw/ppc/spapr_rtc.c @@ -164,6 +164,8 @@ static void spapr_rtc_class_init(ObjectClass *oc, void *data) dc->realize = spapr_rtc_realize; dc->vmsd = &vmstate_spapr_rtc; + /* Reason: This is an internal device only for handling the hypercalls */ + dc->user_creatable = false; spapr_rtas_register(RTAS_GET_TIME_OF_DAY, "get-time-of-day", rtas_get_time_of_day); |