aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/spapr.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ppc/spapr.c')
-rw-r--r--hw/ppc/spapr.c90
1 files changed, 46 insertions, 44 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 63315f2d0f..227075103e 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1483,9 +1483,9 @@ void spapr_free_hpt(SpaprMachineState *spapr)
close_htab_fd(spapr);
}
-void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift,
- Error **errp)
+int spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, Error **errp)
{
+ ERRP_GUARD();
long rc;
/* Clean up any HPT info from a previous boot */
@@ -1495,22 +1495,23 @@ void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift,
if (rc == -EOPNOTSUPP) {
error_setg(errp, "HPT not supported in nested guests");
- return;
+ return -EOPNOTSUPP;
}
if (rc < 0) {
/* kernel-side HPT needed, but couldn't allocate one */
- error_setg_errno(errp, errno,
- "Failed to allocate KVM HPT of order %d (try smaller maxmem?)",
+ error_setg_errno(errp, errno, "Failed to allocate KVM HPT of order %d",
shift);
- /* This is almost certainly fatal, but if the caller really
- * wants to carry on with shift == 0, it's welcome to try */
+ error_append_hint(errp, "Try smaller maxmem?\n");
+ return -errno;
} else if (rc > 0) {
/* kernel-side HPT allocated */
if (rc != shift) {
error_setg(errp,
- "Requested order %d HPT, but kernel allocated order %ld (try smaller maxmem?)",
+ "Requested order %d HPT, but kernel allocated order %ld",
shift, rc);
+ error_append_hint(errp, "Try smaller maxmem?\n");
+ return -ENOSPC;
}
spapr->htab_shift = shift;
@@ -1524,7 +1525,7 @@ void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift,
if (!spapr->htab) {
error_setg_errno(errp, errno,
"Could not allocate HPT of order %d", shift);
- return;
+ return -ENOMEM;
}
memset(spapr->htab, 0, size);
@@ -1537,6 +1538,7 @@ void spapr_reallocate_hpt(SpaprMachineState *spapr, int shift,
/* We're setting up a hash table, so that means we're not radix */
spapr->patb_entry = 0;
spapr_set_all_lpcrs(0, LPCR_HR | LPCR_UPRT);
+ return 0;
}
void spapr_setup_hpt(SpaprMachineState *spapr)
@@ -2290,11 +2292,13 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id)
}
if (section_hdr) {
+ int ret;
+
/* First section gives the htab size */
- spapr_reallocate_hpt(spapr, section_hdr, &local_err);
- if (local_err) {
+ ret = spapr_reallocate_hpt(spapr, section_hdr, &local_err);
+ if (ret < 0) {
error_report_err(local_err);
- return -EINVAL;
+ return ret;
}
return 0;
}
@@ -2345,8 +2349,10 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id)
assert(fd >= 0);
- rc = kvmppc_load_htab_chunk(f, fd, index, n_valid, n_invalid);
+ rc = kvmppc_load_htab_chunk(f, fd, index, n_valid, n_invalid,
+ &local_err);
if (rc < 0) {
+ error_report_err(local_err);
return rc;
}
}
@@ -2641,6 +2647,16 @@ static hwaddr spapr_rma_size(SpaprMachineState *spapr, Error **errp)
return rma_size;
}
+static void spapr_create_nvdimm_dr_connectors(SpaprMachineState *spapr)
+{
+ MachineState *machine = MACHINE(spapr);
+ int i;
+
+ for (i = 0; i < machine->ram_slots; i++) {
+ spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_PMEM, i);
+ }
+}
+
/* pSeries LPAR / sPAPR hardware init */
static void spapr_machine_init(MachineState *machine)
{
@@ -3372,7 +3388,7 @@ int spapr_lmb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
return 0;
}
-static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
+static bool spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
bool dedicated_hp_event_source, Error **errp)
{
SpaprDrc *drc;
@@ -3393,7 +3409,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
addr / SPAPR_MEMORY_BLOCK_SIZE);
spapr_drc_detach(drc);
}
- return;
+ return false;
}
if (!hotplugged) {
spapr_drc_reset(drc);
@@ -3415,52 +3431,43 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size,
nr_lmbs);
}
}
+ return true;
}
static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- Error *local_err = NULL;
SpaprMachineState *ms = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
- uint64_t size, addr, slot;
+ uint64_t size, addr;
+ int64_t slot;
bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort);
- pc_dimm_plug(dimm, MACHINE(ms), &local_err);
- if (local_err) {
- goto out;
- }
+ pc_dimm_plug(dimm, MACHINE(ms));
if (!is_nvdimm) {
addr = object_property_get_uint(OBJECT(dimm),
- PC_DIMM_ADDR_PROP, &local_err);
- if (local_err) {
+ PC_DIMM_ADDR_PROP, &error_abort);
+ if (!spapr_add_lmbs(dev, addr, size,
+ spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT), errp)) {
goto out_unplug;
}
- spapr_add_lmbs(dev, addr, size,
- spapr_ovec_test(ms->ov5_cas, OV5_HP_EVT),
- &local_err);
} else {
- slot = object_property_get_uint(OBJECT(dimm),
- PC_DIMM_SLOT_PROP, &local_err);
- if (local_err) {
+ slot = object_property_get_int(OBJECT(dimm),
+ PC_DIMM_SLOT_PROP, &error_abort);
+ /* We should have valid slot number at this point */
+ g_assert(slot >= 0);
+ if (!spapr_add_nvdimm(dev, slot, errp)) {
goto out_unplug;
}
- spapr_add_nvdimm(dev, slot, &local_err);
- }
-
- if (local_err) {
- goto out_unplug;
}
return;
out_unplug:
pc_dimm_unplug(dimm, MACHINE(ms));
-out:
- error_propagate(errp, local_err);
}
static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
@@ -3565,8 +3572,8 @@ static SpaprDimmState *spapr_recover_pending_dimm_state(SpaprMachineState *ms,
uint64_t addr_start, addr;
int i;
- addr_start = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP,
- &error_abort);
+ addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,
+ &error_abort);
addr = addr_start;
for (i = 0; i < nr_lmbs; i++) {
@@ -3624,7 +3631,6 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
SpaprMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
- Error *local_err = NULL;
PCDIMMDevice *dimm = PC_DIMM(dev);
uint32_t nr_lmbs;
uint64_t size, addr_start, addr;
@@ -3640,11 +3646,7 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,
- &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ &error_abort);
/*
* An existing pending dimm state for this DIMM means that there is an