Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- commit c547e9863a482729d7bf5ccccf2a53dedfed140b
- Author: Eduardo Otubo <eduardo.otubo@profitbricks.com>
- Date: Mon Jun 15 10:10:06 2015 +0200
- dimmpop: implementation of dimmpop
- Implement -dimmpop option to populate dimms at bootup
- syntax: -dimmpop pfx=poolid,slots=n,size=XGB
- This will populate n dimms with ids poolid0, ..., poolidn-1, each one of
- size XGB
- Signed-off-by: Anshul Makkar <anshul.makkar@profitbricks.com>
- Signed-off-by: Eduardo Otubo <eduardo.otubo@profitbricks.com>
- diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
- index 39f0c97..55343b0 100644
- --- a/hw/mem/pc-dimm.c
- +++ b/hw/mem/pc-dimm.c
- @@ -370,4 +370,53 @@ static void pc_dimm_register_types(void)
- type_register_static(&pc_dimm_info);
- }
- +/* desc: activate newly added dimm devices through dimmpop
- + * id: id of the dimm device like pool0, pool1
- + * size: size of the newly added dimm device.
- + * return : success or failure.
- + */
- +int pc_dimm_activate(const char *id, uint64_t size)
- +{
- + char dimmid[32];
- + int ret = 0;
- + Error *local_err = NULL;
- + QmpInputVisitor *qiv;
- +
- + strcpy(dimmid, id);
- + strncat(dimmid, "-memdev", 7);
- +
- + QDict *sizeqdict;
- + sizeqdict = qdict_new();
- + QInt *sizeobj = qint_from_int(size);
- + qdict_put(sizeqdict, "size", sizeobj);
- +
- + qiv = qmp_input_visitor_new(QOBJECT(sizeobj));
- + object_add("memory-backend-ram", dimmid, sizeqdict, qmp_input_get_visitor(qiv), &local_err);
- + qmp_input_visitor_cleanup(qiv);
- + if (local_err) {
- + qerror_report_err(local_err);
- + error_free(local_err);
- + fprintf(stderr, "Object memdev creation failure \n");
- + ret = -EINVAL;
- + }
- +
- + QemuOpts *dimmopts = qemu_opts_create(qemu_find_opts("device"), id, 0, &error_abort);
- + qemu_opt_set(dimmopts, "driver", TYPE_PC_DIMM, &error_abort);
- + qemu_opt_set(dimmopts, "memdev", dimmid, &error_abort);
- +
- + /* no need for device addition. It is automatically taken care of when qemu calls device
- + * init functions. Only thing is that we need to define device properties correctly
- + */
- +#if 0
- + char num[16];
- + DeviceState *dev;
- + dev = qdev_device_add(dimmopts);
- + if (!dev)
- + {
- + fprintf(stderr, "Failed to add the dimm device \"%s\" \n", id);
- + }
- +#endif
- + return ret;
- +}
- +
- type_init(pc_dimm_register_types)
- diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
- index f7b80b4..981477d 100644
- --- a/include/hw/mem/pc-dimm.h
- +++ b/include/hw/mem/pc-dimm.h
- @@ -19,6 +19,11 @@
- #include "exec/memory.h"
- #include "sysemu/hostmem.h"
- #include "hw/qdev.h"
- +#include "qapi/qmp/qint.h"
- +#include "qapi/qmp-input-visitor.h"
- +#include "qmp-commands.h"
- +#include "qapi/qmp/qobject.h"
- +#include "monitor/qdev.h"
- #define DEFAULT_PC_DIMMSIZE (1024*1024*1024)
- @@ -76,6 +81,7 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,
- Error **errp);
- int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
- +int pc_dimm_activate(const char *id, uint64_t size);
- int qmp_pc_dimm_device_list(Object *obj, void *opaque);
- uint64_t pc_existing_dimms_capacity(Error **errp);
- diff --git a/qemu-options.hx b/qemu-options.hx
- index 319d971..8a23ff5 100644
- --- a/qemu-options.hx
- +++ b/qemu-options.hx
- @@ -3462,6 +3462,22 @@ Dump json-encoded vmstate information for current machine type to file
- in @var{file}
- ETEXI
- +DEF("dimmpop", HAS_ARG, QEMU_OPTION_dimmpop,
- + "-dimmpop [pfx=pool][,slots=n][,size=size]\n"
- + " configure dimms at system startup\n"
- + " pool: logical parition for dimm device\n"
- + " slots: number of dimm devices\n"
- + " size: size of each dimm (default: none\n",
- + QEMU_ARCH_ALL)
- +STEXI
- +@item -dimmpop [size=]@var{megs}
- +@findex -m
- +Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB. Optionally,
- +a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
- +gigabytes respectively. Optional pair @var{slots}, @var{maxmem} could be used
- +to set amount of hotluggable memory slots and possible maximum amount of memory.
- +ETEXI
- +
- HXCOMM This is the last statement. Insert new options before this line!
- STEXI
- @end table
- diff --git a/util/qemu-config.c b/util/qemu-config.c
- index 2d32ce7..9536915 100644
- --- a/util/qemu-config.c
- +++ b/util/qemu-config.c
- @@ -8,7 +8,7 @@
- #include "qmp-commands.h"
- #include "hw/i386/pc.h"
- -static QemuOptsList *vm_config_groups[32];
- +static QemuOptsList *vm_config_groups[64];
- static QemuOptsList *drive_config_groups[4];
- static QemuOptsList *find_list(QemuOptsList **lists, const char *group,
- diff --git a/vl.c b/vl.c
- index 74c2681..2168d95 100644
- --- a/vl.c
- +++ b/vl.c
- @@ -27,6 +27,7 @@
- #include <time.h>
- #include <errno.h>
- #include <sys/time.h>
- +#include "hw/mem/pc-dimm.h"
- #include "config-host.h"
- @@ -124,7 +125,6 @@ int main(int argc, char **argv)
- #define MAX_VIRTIO_CONSOLES 1
- #define MAX_SCLP_CONSOLES 1
- -
- static const char *data_dir[16];
- static int data_dir_idx;
- const char *bios_name = NULL;
- @@ -490,6 +490,29 @@ static QemuOptsList qemu_semihosting_config_opts = {
- },
- };
- +/* Dimmpop option: Used to populate VM with dimms of specific size at startup */
- +static QemuOptsList qemu_dimmpop_opts = {
- + .name = "dimmpop",
- + .head = QTAILQ_HEAD_INITIALIZER(qemu_dimmpop_opts.head),
- + .desc = {
- + {
- + .name = "pfx",
- + .type = QEMU_OPT_STRING,
- + .help = "pool prefix for this dimm device",
- + }, {
- + .name = "slots",
- + .type = QEMU_OPT_SIZE,
- + .help = "number of dimm devices to populate",
- +
- + }, {
- + .name = "size",
- + .type = QEMU_OPT_SIZE,
- + .help = "size of each dimm device to populate",
- + },
- + { /* end of the list */ }
- + },
- +};
- +
- /**
- * Get machine options
- *
- @@ -788,6 +811,62 @@ static void configure_rtc_date_offset(const char *startdate, int legacy)
- }
- }
- +/* desc: populate dimms at the startup using dimmpop
- + * param: command line options.
- + * return: null
- + */
- +static void configure_dimmpop(QemuOpts *opts)
- +{
- + const char *value, *pfx, *id;
- + int num, dimm;
- + uint64_t size;
- + const char *mem_str;
- + char buf[32];
- + ram_addr_t ram_size = 1024;
- +
- + id = qemu_opts_id(opts);
- + value = qemu_opt_get(opts, "pfx");
- + if (!value)
- + {
- + fprintf(stderr, "qemu: invalid prefix for dimm pool '%s'\n", id);
- + exit(1);
- + }
- +
- + pfx = value;
- + value = qemu_opt_get(opts, "slots");
- + if (!value) {
- + fprintf(stderr, "qemu: slots not defined for dimm pool '%s'\n", pfx);
- + exit(1);
- + }
- + else num = atoi(value);
- +
- + mem_str = qemu_opt_get(opts, "size");
- + if (!mem_str)
- + {
- + fprintf(stderr, "qemu: size not defined for the dimm pool.\n");
- + exit(1);
- + }
- + size = qemu_opt_get_size(opts, "size", ram_size);
- +
- + /* Fix up legacy suffix-less format */
- + if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1]))
- + {
- + uint64_t overflow_check = size;
- + size <<= 20;
- + if ((size >> 20) != overflow_check)
- + {
- + error_report("too large 'size' option value");
- + exit(EXIT_FAILURE);
- + }
- + }
- + for (dimm = 0; dimm < num; dimm++)
- + {
- + sprintf(buf, "%s%d", pfx, dimm);
- + if (pc_dimm_activate(buf, size))
- + fprintf(stderr, "qemu: dimm %s not defined for dimm pool '%s'\n", buf, pfx);
- + }
- +}
- +
- static void configure_rtc(QemuOpts *opts)
- {
- const char *value;
- @@ -2767,6 +2846,7 @@ int main(int argc, char **argv, char **envp)
- uint64_t ram_slots = 0;
- FILE *vmstate_dump_file = NULL;
- Error *main_loop_err = NULL;
- + QemuOpts *dimmpop_opts = NULL;
- qemu_init_cpu_loop();
- qemu_mutex_lock_iothread();
- @@ -2806,6 +2886,7 @@ int main(int argc, char **argv, char **envp)
- qemu_add_opts(&qemu_numa_opts);
- qemu_add_opts(&qemu_icount_opts);
- qemu_add_opts(&qemu_semihosting_config_opts);
- + qemu_add_opts(&qemu_dimmpop_opts);
- runstate_init();
- @@ -3753,6 +3834,14 @@ int main(int argc, char **argv, char **envp)
- exit(1);
- }
- break;
- + case QEMU_OPTION_dimmpop:
- + dimmpop_opts = qemu_opts_parse(qemu_find_opts("dimmpop"), optarg, 0);
- + if (!dimmpop_opts)
- + {
- + fprintf(stderr, "Failed to get dimmpop options \n");
- + exit(1);
- + }
- + break;
- default:
- os_parse_cmd_args(popt->index, optarg);
- }
- @@ -4239,6 +4328,14 @@ int main(int argc, char **argv, char **envp)
- exit(1);
- }
- + /* The location of configure_dimmpop is important. We need to make sure the it is called
- + * before the device_init_func is called for each device as in configure_dimmpop we are
- + * calling dimm_activate that creates the object (object_add). This is important before
- + * device initialization.
- + */
- + if(dimmpop_opts)
- + configure_dimmpop(dimmpop_opts);
- +
- /* init generic devices */
- if (qemu_opts_foreach(qemu_find_opts("device"), device_init_func, NULL, 1) != 0)
- exit(1);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement