Patchwork [RFC,v2,10/21] Implement "-dimm" command line option

login
register
mail settings
Submitter Vasilis Liaskovitis
Date July 11, 2012, 10:31 a.m.
Message ID <1342002726-18258-11-git-send-email-vasilis.liaskovitis@profitbricks.com>
Download mbox | patch
Permalink /patch/170456/
State New
Headers show

Comments

Vasilis Liaskovitis - July 11, 2012, 10:31 a.m.
Syntax: "-dimm id=name,size=sz,node=pxm,populated=on|off"

The starting physical address for all dimms is calculated automatically from top
of memory, skipping the pci hole at [PCI_HOLE_START, 4G). 
"populated=on" means the dimm is populated at machine startup. Default is off.
"node" is defining numa proximity for this dimm. Default is node zero.

Example:
"-dimm id=dimm0,size=512M,node=0,populated=off"
will define a 512M memory slot belonging to numa node 0.

Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
---
 qemu-config.c   |   25 +++++++++++++++++++++++++
 qemu-options.hx |    5 +++++
 sysemu.h        |    1 +
 vl.c            |   35 +++++++++++++++++++++++++++++++++++
 4 files changed, 66 insertions(+), 0 deletions(-)

Patch

diff --git a/qemu-config.c b/qemu-config.c
index 5c3296b..4abc31b 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -626,6 +626,30 @@  QemuOptsList qemu_boot_opts = {
     },
 };
 
+static QemuOptsList qemu_dimm_opts = {
+    .name = "dimm",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_dimm_opts.head),
+    .desc = {
+        {
+            .name = "id",
+            .type = QEMU_OPT_STRING,
+            .help = "id of this dimm device",
+        },{
+            .name = "size",
+            .type = QEMU_OPT_SIZE,
+            .help = "memory size for this dimm",
+        },{
+            .name = "populated",
+            .type = QEMU_OPT_BOOL,
+            .help = "populated for this dimm",
+        },{
+            .name = "node",
+            .type = QEMU_OPT_NUMBER,
+            .help = "NUMA node number (i.e. proximity) for this dimm",
+        },
+        { /* end of list */ }
+    },
+};
 static QemuOptsList *vm_config_groups[32] = {
     &qemu_drive_opts,
     &qemu_chardev_opts,
@@ -641,6 +665,7 @@  static QemuOptsList *vm_config_groups[32] = {
     &qemu_machine_opts,
     &qemu_boot_opts,
     &qemu_iscsi_opts,
+    &qemu_dimm_opts,
     NULL,
 };
 
diff --git a/qemu-options.hx b/qemu-options.hx
index 8b66264..61909f7 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2747,3 +2747,8 @@  HXCOMM This is the last statement. Insert new options before this line!
 STEXI
 @end table
 ETEXI
+
+DEF("dimm", HAS_ARG, QEMU_OPTION_dimm,
+        "-dimm id=dimmid,size=sz,node=nd,populated=on|off\n"
+        "specify memory dimm device with name dimmid, size sz on node nd",
+        QEMU_ARCH_ALL)
diff --git a/sysemu.h b/sysemu.h
index bc2c788..3e21a22 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -136,6 +136,7 @@  extern QEMUClock *rtc_clock;
 extern int nb_numa_nodes;
 extern uint64_t node_mem[MAX_NODES];
 extern uint64_t node_cpumask[MAX_NODES];
+extern int nb_hp_dimms;
 
 #define MAX_OPTION_ROMS 16
 typedef struct QEMUOptionRom {
diff --git a/vl.c b/vl.c
index 0ff8818..efe915e 100644
--- a/vl.c
+++ b/vl.c
@@ -120,6 +120,7 @@  int main(int argc, char **argv)
 #include "hw/xen.h"
 #include "hw/qdev.h"
 #include "hw/loader.h"
+#include "hw/dimm.h"
 #include "bt-host.h"
 #include "net.h"
 #include "net/slirp.h"
@@ -242,6 +243,7 @@  QTAILQ_HEAD(, FWBootEntry) fw_boot_order = QTAILQ_HEAD_INITIALIZER(fw_boot_order
 int nb_numa_nodes;
 uint64_t node_mem[MAX_NODES];
 uint64_t node_cpumask[MAX_NODES];
+int nb_hp_dimms;
 
 uint8_t qemu_uuid[16];
 
@@ -518,6 +520,23 @@  static void configure_rtc_date_offset(const char *startdate, int legacy)
         rtc_date_offset = time(NULL) - rtc_start_date;
     }
 }
+static void configure_dimm(QemuOpts *opts)
+{
+    const char *id;
+    uint64_t size, node;
+    bool populated;
+    if (nb_hp_dimms == MAX_DIMMS) {
+        fprintf(stderr, "qemu: maximum number of DIMMs (%d) exceeded\n",
+                MAX_DIMMS);
+        exit(1);
+    }
+    id = qemu_opts_id(opts);
+    size = qemu_opt_get_size(opts, "size", DEFAULT_DIMMSIZE);
+    populated = qemu_opt_get_bool(opts, "populated", 0);
+    node = qemu_opt_get_number(opts, "node", 0);
+    dimm_create((char*)id, size, node, nb_hp_dimms, populated);
+    nb_hp_dimms++;
+}
 
 static void configure_rtc(QemuOpts *opts)
 {
@@ -2273,6 +2292,8 @@  int main(int argc, char **argv, char **envp)
     DisplayChangeListener *dcl;
     int cyls, heads, secs, translation;
     QemuOpts *hda_opts = NULL, *opts, *machine_opts;
+    QemuOpts *dimm_opts[MAX_DIMMS];
+    int nb_dimm_opts = 0;
     QemuOptsList *olist;
     int optind;
     const char *optarg;
@@ -3200,6 +3221,18 @@  int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_qtest_log:
                 qtest_log = optarg;
                 break;
+            case QEMU_OPTION_dimm:
+                if (nb_dimm_opts == MAX_DIMMS) {
+                    fprintf(stderr, "qemu: maximum number of DIMMs (%d) exceeded\n",
+                        MAX_DIMMS);
+                }
+                dimm_opts[nb_dimm_opts] =
+                    qemu_opts_parse(qemu_find_opts("dimm"), optarg, 0);
+                if (!dimm_opts[nb_dimm_opts]) {
+                    exit(1);
+                }
+                nb_dimm_opts++;
+                break;
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
@@ -3517,6 +3550,8 @@  int main(int argc, char **argv, char **envp)
     }
     qemu_add_globals();
 
+    for (i = 0; i < nb_dimm_opts; i++)
+        configure_dimm(dimm_opts[i]);
     qdev_machine_init();
 
     machine->init(ram_size, boot_devices,