From: Peter Dinda Date: Mon, 23 Mar 2015 21:11:00 +0000 (-0500) Subject: HVM configuration logic (create mptables, acpi tables, etc, based on ROS config) X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=32cee4124eb5ac84b2c8990d056fd50f987203a5 HVM configuration logic (create mptables, acpi tables, etc, based on ROS config) 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. --- diff --git a/palacios/src/devices/mptable.c b/palacios/src/devices/mptable.c index 2eb0206..dc1390e 100644 --- a/palacios/src/devices/mptable.c +++ b/palacios/src/devices/mptable.c @@ -21,6 +21,7 @@ #include #include + /* 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; } diff --git a/palacios/src/devices/nvram.c b/palacios/src/devices/nvram.c index 3284c49..f15795f 100644 --- a/palacios/src/devices/nvram.c +++ b/palacios/src/devices/nvram.c @@ -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); diff --git a/palacios/src/palacios/vmm_fw_cfg.c b/palacios/src/palacios/vmm_fw_cfg.c index 5fe46e5..80af5a4 100644 --- a/palacios/src/palacios/vmm_fw_cfg.c +++ b/palacios/src/palacios/vmm_fw_cfg.c @@ -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)); } }