Commit 8f1ffe5b authored by David Hildenbrand's avatar David Hildenbrand Committed by Paolo Bonzini
Browse files

pc-dimm: assign and verify the "slot" property during pre_plug



We can assign and verify the slot before realizing and trying to plug.
reading/writing the slot property should never fail, so let's reduce
error handling a bit by using &error_abort.

To do this during pre_plug, add and use (x86, ppc) pc_dimm_pre_plug().

Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Reviewed-by: default avatarIgor Mammedov <imammedo@redhat.com>
Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Message-Id: <20180801133444.11269-2-david@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent efbb649d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1696,6 +1696,8 @@ static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
        error_setg(errp, "nvdimm is not enabled: missing 'nvdimm' in '-M'");
        return;
    }

    pc_dimm_pre_plug(dev, MACHINE(hotplug_dev), errp);
}

static void pc_memory_plug(HotplugHandler *hotplug_dev,
+18 −17
Original line number Diff line number Diff line
@@ -29,10 +29,27 @@

static int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);

void pc_dimm_pre_plug(DeviceState *dev, MachineState *machine, Error **errp)
{
    Error *local_err = NULL;
    int slot;

    slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
                                   &error_abort);
    slot = pc_dimm_get_free_slot(slot == PC_DIMM_UNASSIGNED_SLOT ? NULL : &slot,
                                 machine->ram_slots, &local_err);
    if (local_err) {
        goto out;
    }
    object_property_set_int(OBJECT(dev), slot, PC_DIMM_SLOT_PROP, &error_abort);
    trace_mhp_pc_dimm_assigned_slot(slot);
out:
    error_propagate(errp, local_err);
}

void pc_dimm_plug(DeviceState *dev, MachineState *machine, uint64_t align,
                  Error **errp)
{
    int slot;
    PCDIMMDevice *dimm = PC_DIMM(dev);
    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
    MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm,
@@ -59,22 +76,6 @@ void pc_dimm_plug(DeviceState *dev, MachineState *machine, uint64_t align,
    }
    trace_mhp_pc_dimm_assigned_address(addr);

    slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, &local_err);
    if (local_err) {
        goto out;
    }

    slot = pc_dimm_get_free_slot(slot == PC_DIMM_UNASSIGNED_SLOT ? NULL : &slot,
                                 machine->ram_slots, &local_err);
    if (local_err) {
        goto out;
    }
    object_property_set_int(OBJECT(dev), slot, PC_DIMM_SLOT_PROP, &local_err);
    if (local_err) {
        goto out;
    }
    trace_mhp_pc_dimm_assigned_slot(slot);

    memory_device_plug_region(machine, mr, addr);
    vmstate_register_ram(vmstate_mr, dev);

+8 −1
Original line number Diff line number Diff line
@@ -3205,6 +3205,7 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
    sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
    PCDIMMDevice *dimm = PC_DIMM(dev);
    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
    Error *local_err = NULL;
    MemoryRegion *mr;
    uint64_t size;
    Object *memdev;
@@ -3230,7 +3231,13 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
    memdev = object_property_get_link(OBJECT(dimm), PC_DIMM_MEMDEV_PROP,
                                      &error_abort);
    pagesize = host_memory_backend_pagesize(MEMORY_BACKEND(memdev));
    spapr_check_pagesize(spapr, pagesize, errp);
    spapr_check_pagesize(spapr, pagesize, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    pc_dimm_pre_plug(dev, MACHINE(hotplug_dev), errp);
}

struct sPAPRDIMMState {
+1 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ typedef struct PCDIMMDeviceClass {
                                               Error **errp);
} PCDIMMDeviceClass;

void pc_dimm_pre_plug(DeviceState *dev, MachineState *machine, Error **errp);
void pc_dimm_plug(DeviceState *dev, MachineState *machine, uint64_t align,
                  Error **errp);
void pc_dimm_unplug(DeviceState *dev, MachineState *machine);