Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


HVM configuration logic (create mptables, acpi tables, etc, based on ROS config)
Peter Dinda [Mon, 23 Mar 2015 21:11:00 +0000 (16:11 -0500)]
This updates the various ways we tell the guest what hardware is available.
In an HVM, we describe only the ROS components of the guest, not the
additional components (e.g., cores, memory, etc) that the HRT can also see.

palacios/src/devices/mptable.c
palacios/src/devices/nvram.c
palacios/src/palacios/vmm_fw_cfg.c

index 2eb0206..dc1390e 100644 (file)
@@ -21,6 +21,7 @@
 #include <palacios/vmm_string.h>
 #include <palacios/vm_guest_mem.h>
 
+
 /* 
   The guest bios is compiled with blank space for am MP table
   at a default address.  A cookie value is temporarily placed 
@@ -518,6 +519,12 @@ static int mptable_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     int have_apic = find_first_peer_device_of_class(cfg,"lapic")!=NULL;
     int have_ioapic = find_first_peer_device_of_class(cfg,"ioapic")!=NULL;
 
+    uint32_t num_cores = vm->num_cores;
+
+#ifdef V3_CONFIG_HVM
+    num_cores = v3_get_hvm_ros_cores(vm);
+#endif
+
     if (!have_apic) { 
       PrintError(vm, VCORE_NONE,  "Attempt to instantiate MPTABLE but machine has no apics!\n");
       return -1;
@@ -543,12 +550,12 @@ static int mptable_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
        return 0;
     }
 
-    if (vm->num_cores > 32) { 
+    if (num_cores > 32) { 
        PrintError(vm, VCORE_NONE,  "No support for >32 cores in writing MP table, aborting.\n");
        return -1;
     }
 
-    V3_Print(vm, VCORE_NONE, "Constructing mptable for %u cores at %p\n", vm->num_cores, target);
+    V3_Print(vm, VCORE_NONE, "Constructing mptable for %u cores at %p\n", num_cores, target);
 
     if (write_pointer(target, BIOS_MP_TABLE_DEFAULT_LOCATION + sizeof(struct mp_floating_pointer)) == -1) { 
        PrintError(vm, VCORE_NONE, "Unable to write mptable floating pointer, aborting.\n");
@@ -560,7 +567,7 @@ static int mptable_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
        return -1;
     }
 
-    if (write_mptable(target + sizeof(struct mp_floating_pointer), vm->num_cores, have_ioapic, have_pci)) {
+    if (write_mptable(target + sizeof(struct mp_floating_pointer), num_cores, have_ioapic, have_pci)) {
        PrintError(vm, VCORE_NONE, "Cannot inject mptable configuration header and entries\n");
        return -1;
     }
index 3284c49..f15795f 100644 (file)
@@ -638,6 +638,13 @@ static uint16_t compute_checksum(struct nvram_internal * nvram) {
 
 static int init_nvram_state(struct v3_vm_info * vm, struct nvram_internal * nvram, char *bootseq) {
     uint16_t checksum = 0;
+    uint64_t mem_size=vm->mem_size;
+    uint32_t num_cores=vm->num_cores;
+
+#ifdef V3_CONFIG_HVM
+    mem_size = v3_get_hvm_ros_memsize(vm);
+    num_cores = v3_get_hvm_ros_cores(vm);
+#endif
 
     memset(nvram->mem_state, 0, NVRAM_REG_MAX);
     memset(nvram->reg_map, 0, NVRAM_REG_MAX / 8);
@@ -725,10 +732,11 @@ static int init_nvram_state(struct v3_vm_info * vm, struct nvram_internal * nvra
     nvram->us = 0;
     nvram->pus = 0;
 
-    set_memory_size(nvram, vm->mem_size);
+
+    set_memory_size(nvram, mem_size);
     init_harddrives(nvram);
 
-    set_memory(nvram, NVRAM_REG_SMPCPUS, vm->num_cores - 1);
+    set_memory(nvram, NVRAM_REG_SMPCPUS, num_cores - 1);
     
     /* compute checksum (must follow all assignments here) */
     checksum = compute_checksum(nvram);
index 5fe46e5..80af5a4 100644 (file)
@@ -350,6 +350,13 @@ int v3_fw_cfg_init(struct v3_vm_info * vm) {
 
     struct v3_fw_cfg_state * cfg_state = &(vm->fw_cfg_state);
     int ret = 0;
+    uint64_t mem_size = vm->mem_size;
+    uint32_t num_cores = vm->num_cores;
+
+#ifdef V3_CONFIG_HVM
+    mem_size = v3_get_hvm_ros_memsize(vm);
+    num_cores = v3_get_hvm_ros_cores(vm);
+#endif
 
     
     // Be paranoid about starting this as all "unallocated"
@@ -383,13 +390,13 @@ int v3_fw_cfg_init(struct v3_vm_info * vm) {
     fw_cfg_add_bytes(cfg_state, FW_CFG_SIGNATURE, (uint8_t *)"QEMU", 4);
     //fw_cfg_add_bytes(cfg_state, FW_CFG_UUID, qemu_uuid, 16);
     fw_cfg_add_i16(cfg_state, FW_CFG_NOGRAPHIC, /*(uint16_t)(display_type == DT_NOGRAPHIC)*/ 0);
-    fw_cfg_add_i16(cfg_state, FW_CFG_NB_CPUS, (uint16_t)vm->num_cores);
-    fw_cfg_add_i16(cfg_state, FW_CFG_MAX_CPUS, (uint16_t)vm->num_cores);
+    fw_cfg_add_i16(cfg_state, FW_CFG_NB_CPUS, (uint16_t)num_cores);
+    fw_cfg_add_i16(cfg_state, FW_CFG_MAX_CPUS, (uint16_t)num_cores);
     fw_cfg_add_i16(cfg_state, FW_CFG_BOOT_MENU, (uint16_t)1);
     //fw_cfg_bootsplash(cfg_state);
 
     fw_cfg_add_i32(cfg_state, FW_CFG_ID, 1);
-    fw_cfg_add_i64(cfg_state, FW_CFG_RAM_SIZE, (uint64_t)vm->mem_size / (1024 * 1024));
+    fw_cfg_add_i64(cfg_state, FW_CFG_RAM_SIZE, mem_size / (1024 * 1024));
 
     //fw_cfg_add_bytes(cfg_state, FW_CFG_ACPI_TABLES, (uint8_t *)acpi_tables,
     //       acpi_tables_len);
@@ -422,7 +429,7 @@ int v3_fw_cfg_init(struct v3_vm_info * vm) {
        /* locations in fw_cfg NUMA array for each info region. */
        int node_offset = 0;
        int core_offset = 1;
-       int mem_offset = 1 + vm->num_cores;
+       int mem_offset = 1 + num_cores;
        
        if (num_nodes_str) {
            num_nodes = atoi(num_nodes_str);
@@ -433,7 +440,7 @@ int v3_fw_cfg_init(struct v3_vm_info * vm) {
            int i = 0;
 
            // Allocate the global NUMA configuration array
-           numa_fw_cfg = V3_Malloc((1 + vm->num_cores + num_nodes) * sizeof(uint64_t));
+           numa_fw_cfg = V3_Malloc((1 + num_cores + num_nodes) * sizeof(uint64_t));
 
            if (numa_fw_cfg == NULL) {
                PrintError(vm, VCORE_NONE, "Could not allocate fw_cfg NUMA config space\n");
@@ -441,14 +448,14 @@ int v3_fw_cfg_init(struct v3_vm_info * vm) {
                return -1;
            }
 
-           memset(numa_fw_cfg, 0, (1 + vm->num_cores + num_nodes) * sizeof(uint64_t));
+           memset(numa_fw_cfg, 0, (1 + num_cores + num_nodes) * sizeof(uint64_t));
 
            // First 8 bytes is the number of NUMA zones
            numa_fw_cfg[node_offset] = num_nodes;
            
            
            // Next region is array of core->node mappings
-           for (i = 0; i < vm->num_cores; i++) {
+           for (i = 0; i < num_cores; i++) {
                char * vnode_str = v3_cfg_val(vm->cores[i].core_cfg_data, "vnode");
                
                if (vnode_str == NULL) {
@@ -508,7 +515,7 @@ int v3_fw_cfg_init(struct v3_vm_info * vm) {
                
                V3_Print(vm, VCORE_NONE, "NUMA CONFIG: (nodes=%llu)\n", numa_fw_cfg[0]);
        
-               for (i = 0; i < vm->num_cores; i++) {
+               for (i = 0; i < num_cores; i++) {
                    V3_Print(vm, VCORE_NONE, "\tCore %d -> Node %llu\n", i, numa_fw_cfg[core_offset + i]);
                }
        
@@ -523,7 +530,7 @@ int v3_fw_cfg_init(struct v3_vm_info * vm) {
 
            // Register the NUMA cfg array with the FW_CFG interface
            fw_cfg_add_bytes_internal(cfg_state, FW_CFG_NUMA, (uint8_t *)numa_fw_cfg,
-                                     (1 + vm->num_cores + num_nodes) * sizeof(uint64_t));
+                                     (1 + num_cores + num_nodes) * sizeof(uint64_t));
 
        }
     }