module_param_array(cpu_list, int, &cpu_list_len, 0644);
MODULE_PARM_DESC(cpu_list, "Comma-delimited list of CPUs that Palacios will run on");
+// Palacios options parameter
+static char *options;
+module_param(options, charp, 0);
+MODULE_PARM_DESC(options, "Generic options to internal Palacios modules");
+
int mod_allocs = 0;
int mod_frees = 0;
-
static int v3_major_num = 0;
static struct v3_guest * guest_map[MAX_VMS] = {[0 ... MAX_VMS - 1] = 0};
palacios_init_mm();
// Initialize Palacios
- palacios_vmm_init();
+ palacios_vmm_init(options);
// initialize extensions
}
}
+/* Options are space-separated values of the form "X=Y", for example
+ * scheduler=EDF CPUs=1,2,3,4
+ * THe following code pushes them into a hashtable for each of access
+ * by other code. Storage is allocated for keys and values as part
+ * of this process. XXX Need a way to deallocate this storage if the
+ * module is removed XXX
+ */
+static char *option_storage;
+static struct hashtable *option_table;
+static char *truevalue = "true";
+
+static uint_t option_hash_fn(addr_t key) {
+ char * name = (char *)key;
+ return v3_hash_buffer((uint8_t *)name, strlen(name));
+}
+static int option_eq_fn(addr_t key1, addr_t key2) {
+ char * name1 = (char *)key1;
+ char * name2 = (char *)key2;
+
+ return (strcmp(name1, name2) == 0);
+}
-void Init_V3(struct v3_os_hooks * hooks, char * cpu_mask, int num_cpus) {
+void V3_parse_options(char *options)
+{
+ char *currKey = NULL, *currVal = NULL;
+ int parseKey = 1;
+ int len = strlen(options);
+ char *c;
+
+ option_storage = V3_Malloc(len + 1);
+ strcpy(option_storage, options);
+ c = option_storage;
+
+ option_table = v3_create_htable(0, option_hash_fn, option_eq_fn);
+ while (c && *c) {
+ /* Skip whitespace */
+ if (*c == ' ') {
+ *c = 0;
+ if (currKey) {
+ if (!currVal) {
+ currVal = truevalue;
+ }
+ v3_htable_insert(option_table, (addr_t)currKey, (addr_t)currVal);
+ parseKey = 1;
+ currKey = NULL;
+ currVal = NULL;
+ }
+ c++;
+ } else if (parseKey) {
+ if (!currKey) {
+ currKey = c;
+ }
+ if (*c == '=') {
+ parseKey = 0;
+ *c = 0;
+ }
+ c++;
+ } else /* !parseKey */ {
+ if (!currVal) {
+ currVal = c;
+ }
+ c++;
+ }
+ }
+ if (currKey) {
+ if (!currVal) {
+ currVal = truevalue;
+ }
+ v3_htable_insert(option_table, (addr_t)currKey, (addr_t)currVal);
+ }
+ return;
+}
+
+char *v3_lookup_option(char *key) {
+ return (char *)v3_htable_search(option_table, (addr_t)(key));
+}
+
+void Init_V3(struct v3_os_hooks * hooks, char * cpu_mask, int num_cpus, char *options) {
int i = 0;
int minor = 0;
int major = 0;
v3_cpu_types[i] = V3_INVALID_CPU;
}
+ // Parse host-os defined options into an easily-accessed format.
+ V3_parse_options(options);
+
// Register all the possible device types
V3_init_devices();