static void assign_storage(SCLPDevice *sclp, SCCB *sccb)

{

    MemoryRegion *mr = NULL;

    uint64_t this_subregion_size;

    AssignStorage *assign_info = (AssignStorage *) sccb;

    sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();

    assert(mhd);

    ram_addr_t assign_addr = (assign_info->rn - 1) * mhd->rzm;

    MemoryRegion *sysmem = get_system_memory();



    if ((assign_addr % MEM_SECTION_SIZE == 0) &&

        (assign_addr >= mhd->padded_ram_size)) {

        /* Re-use existing memory region if found */

        mr = memory_region_find(sysmem, assign_addr, 1).mr;

        memory_region_unref(mr);

        if (!mr) {



            MemoryRegion *standby_ram = g_new(MemoryRegion, 1);



            /* offset to align to standby_subregion_size for allocation */

            ram_addr_t offset = assign_addr -

                                (assign_addr - mhd->padded_ram_size)

                                % mhd->standby_subregion_size;



            /* strlen("standby.ram") + 4 (Max of KVM_MEMORY_SLOTS) +  NULL */

            char id[16];

            snprintf(id, 16, "standby.ram%d",

                     (int)((offset - mhd->padded_ram_size) /

                     mhd->standby_subregion_size) + 1);



            /* Allocate a subregion of the calculated standby_subregion_size */

            if (offset + mhd->standby_subregion_size >

                mhd->padded_ram_size + mhd->standby_mem_size) {

                this_subregion_size = mhd->padded_ram_size +

                  mhd->standby_mem_size - offset;

            } else {

                this_subregion_size = mhd->standby_subregion_size;

            }



            memory_region_init_ram(standby_ram, NULL, id, this_subregion_size, &error_abort);

            /* This is a hack to make memory hotunplug work again. Once we have

             * subdevices, we have to unparent them when unassigning memory,

             * instead of doing it via the ref count of the MemoryRegion. */

            object_ref(OBJECT(standby_ram));

            object_unparent(OBJECT(standby_ram));

            vmstate_register_ram_global(standby_ram);

            memory_region_add_subregion(sysmem, offset, standby_ram);

        }

        /* The specified subregion is no longer in standby */

        mhd->standby_state_map[(assign_addr - mhd->padded_ram_size)

                               / MEM_SECTION_SIZE] = 1;

    }

    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);

}
