mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-06-07 17:46:15 +00:00
Currently, we use STR_LEN for all checking the size of all the acrn-dm parameters. But some parameters like kernel boot args can grow based on different needs. For example, when kata launches guest VM using acrn, the kernel boot args increases by 256 bytes (i.e 1024 +256). Just increasing STR_LEN will unnecessarily increase allocations for other acrn-dm parameters. So decoupling only boot_args length and increasing it to 2048. PS: If other parameters like ramdisk path, kernel path, elf_path etc. don't need 1024 bytes, we can reduce STR_LEN to 256 or 512 bytes. Tracked-On: #3138 Signed-off-by: Vijay Dhanraj <vijay.dhanraj@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
269 lines
6.8 KiB
C
269 lines
6.8 KiB
C
/*-
|
|
* Copyright (c) 2017 Intel Corporation
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "vmmapi.h"
|
|
#include "sw_load.h"
|
|
#include "dm.h"
|
|
#include "pci_core.h"
|
|
|
|
int with_bootargs;
|
|
static char bootargs[BOOT_ARG_LEN];
|
|
|
|
/*
|
|
* Default e820 mem map:
|
|
*
|
|
* there is reserved memory hole for PCI hole and APIC etc
|
|
* so the memory layout could be separated into lowmem & highmem.
|
|
* - if request memory size <= ctx->lowmem_limit, then there is only
|
|
* map[0]:0~ctx->lowmem for RAM
|
|
* ctx->lowmem = request_memory_size
|
|
* - if request memory size > ctx->lowmem_limit, then there are
|
|
* map[0]:0~ctx->lowmem_limit & map[2]:4G~ctx->highmem for RAM
|
|
* ctx->highmem = request_memory_size - ctx->lowmem_limit
|
|
*
|
|
* Begin Limit Type Length
|
|
* 0: 0 - 0xA0000 RAM 0xA0000
|
|
* 1: 0xA0000 - 0x100000 (reserved) 0x60000
|
|
* 2: 0x100000 - lowmem RAM lowmem - 1MB
|
|
* 3: lowmem - 0x80000000 (reserved) 2GB - lowmem
|
|
* 4: 0xE0000000 - 0x100000000 MCFG, MMIO 512MB
|
|
* 5: 0x100000000 - 0x140000000 64-bit PCI hole 1GB
|
|
* 6: 0x140000000 - highmem RAM highmem - 5GB
|
|
*/
|
|
const struct e820_entry e820_default_entries[NUM_E820_ENTRIES] = {
|
|
{ /* 0 to video memory */
|
|
.baseaddr = 0x00000000,
|
|
.length = 0xA0000,
|
|
.type = E820_TYPE_RAM
|
|
},
|
|
|
|
{ /* video memory, ROM (used for e820/mptable/smbios/acpi) */
|
|
.baseaddr = 0xA0000,
|
|
.length = 0x60000,
|
|
.type = E820_TYPE_RESERVED
|
|
},
|
|
|
|
{ /* 1MB to lowmem */
|
|
.baseaddr = 0x100000,
|
|
.length = 0x48f00000,
|
|
.type = E820_TYPE_RAM
|
|
},
|
|
|
|
{ /* lowmem to lowmem_limit */
|
|
.baseaddr = 0x49000000,
|
|
.length = 0x37000000,
|
|
.type = E820_TYPE_RESERVED
|
|
},
|
|
|
|
{ /* ECFG_BASE to 4GB */
|
|
.baseaddr = PCI_EMUL_ECFG_BASE,
|
|
.length = (4 * GB) - PCI_EMUL_ECFG_BASE,
|
|
.type = E820_TYPE_RESERVED
|
|
},
|
|
|
|
{ /* 4GB to 5GB */
|
|
.baseaddr = PCI_EMUL_MEMBASE64,
|
|
.length = PCI_EMUL_MEMLIMIT64 - PCI_EMUL_MEMBASE64,
|
|
.type = E820_TYPE_RESERVED
|
|
},
|
|
|
|
{ /* 5GB to highmem */
|
|
.baseaddr = PCI_EMUL_MEMLIMIT64,
|
|
.length = 0x000100000,
|
|
.type = E820_TYPE_RESERVED
|
|
},
|
|
};
|
|
|
|
int
|
|
acrn_parse_bootargs(char *arg)
|
|
{
|
|
size_t len = strnlen(arg, BOOT_ARG_LEN);
|
|
|
|
if (len < BOOT_ARG_LEN) {
|
|
strncpy(bootargs, arg, len + 1);
|
|
with_bootargs = 1;
|
|
printf("SW_LOAD: get bootargs %s\n", bootargs);
|
|
return 0;
|
|
} else
|
|
return -1;
|
|
}
|
|
|
|
char*
|
|
get_bootargs(void)
|
|
{
|
|
return bootargs;
|
|
}
|
|
|
|
int
|
|
check_image(char *path, size_t size_limit, size_t *size)
|
|
{
|
|
FILE *fp;
|
|
long len;
|
|
|
|
fp = fopen(path, "r");
|
|
|
|
if (fp == NULL) {
|
|
fprintf(stderr,
|
|
"SW_LOAD ERR: image file failed to open\n");
|
|
return -1;
|
|
}
|
|
|
|
fseek(fp, 0, SEEK_END);
|
|
len = ftell(fp);
|
|
|
|
if (len == 0 || (size_limit && len > size_limit)) {
|
|
fprintf(stderr,
|
|
"SW_LOAD ERR: file is %s\n",
|
|
len ? "too large" : "empty");
|
|
fclose(fp);
|
|
return -1;
|
|
}
|
|
|
|
fclose(fp);
|
|
*size = len;
|
|
return 0;
|
|
}
|
|
|
|
/* Assumption:
|
|
* the range [start, start + size] belongs to one entry of e820 table
|
|
*/
|
|
int
|
|
add_e820_entry(struct e820_entry *e820, int len, uint64_t start,
|
|
uint64_t size, uint32_t type)
|
|
{
|
|
int i, length = len;
|
|
uint64_t e_s, e_e;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
e_s = e820[i].baseaddr;
|
|
e_e = e820[i].baseaddr + e820[i].length;
|
|
if ((e_s <= start) && ((start + size) <= e_e)) {
|
|
int index_s = 0, index_e = 3;
|
|
uint64_t pt[4];
|
|
uint32_t pt_t[3];
|
|
|
|
pt[0] = e_s;
|
|
pt[1] = start;
|
|
pt[2] = start + size;
|
|
pt[3] = e_e;
|
|
|
|
pt_t[0] = e820[i].type;
|
|
pt_t[1] = type;
|
|
pt_t[2] = e820[i].type;
|
|
|
|
if (e_s == start) {
|
|
index_s = 1;
|
|
}
|
|
|
|
if (e_e == (start + size)) {
|
|
index_e = 2;
|
|
}
|
|
length += index_e - index_s - 1;
|
|
|
|
if ((i != (len - 1) && ((index_e - index_s) > 1))) {
|
|
memmove(&e820[i + index_e - index_s],
|
|
&e820[i + 1], (len - i - 1) *
|
|
sizeof(struct e820_entry));
|
|
}
|
|
|
|
for (; index_s < index_e; index_s++, i++) {
|
|
e820[i].baseaddr = pt[index_s];
|
|
e820[i].length = pt[index_s + 1] - pt[index_s];
|
|
e820[i].type = pt_t[index_s];
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return length;
|
|
}
|
|
|
|
uint32_t
|
|
acrn_create_e820_table(struct vmctx *ctx, struct e820_entry *e820)
|
|
{
|
|
uint32_t removed = 0, k;
|
|
|
|
memcpy(e820, e820_default_entries, sizeof(e820_default_entries));
|
|
|
|
assert(ctx->lowmem > e820[LOWRAM_E820_ENTRY].baseaddr);
|
|
e820[LOWRAM_E820_ENTRY].length = ctx->lowmem -
|
|
e820[LOWRAM_E820_ENTRY].baseaddr;
|
|
|
|
/* remove [lowmem, lowmem_limit) if it's empty */
|
|
if (ctx->lowmem_limit > ctx->lowmem) {
|
|
e820[LOWRAM_E820_ENTRY+1].baseaddr = ctx->lowmem;
|
|
e820[LOWRAM_E820_ENTRY+1].length =
|
|
ctx->lowmem_limit - ctx->lowmem;
|
|
} else {
|
|
memmove(&e820[LOWRAM_E820_ENTRY+1], &e820[LOWRAM_E820_ENTRY+2],
|
|
sizeof(e820[LOWRAM_E820_ENTRY+2]) *
|
|
(NUM_E820_ENTRIES - (LOWRAM_E820_ENTRY+2)));
|
|
removed++;
|
|
}
|
|
|
|
/* remove [5GB, highmem) if it's empty */
|
|
if (ctx->highmem > 0) {
|
|
e820[HIGHRAM_E820_ENTRY - removed].type = E820_TYPE_RAM;
|
|
e820[HIGHRAM_E820_ENTRY - removed].length = ctx->highmem;
|
|
} else {
|
|
removed++;
|
|
}
|
|
|
|
printf("SW_LOAD: build e820 %d entries to addr: %p\r\n",
|
|
NUM_E820_ENTRIES - removed, (void *)e820);
|
|
|
|
for (k = 0; k < NUM_E820_ENTRIES - removed; k++)
|
|
printf("SW_LOAD: entry[%d]: addr 0x%016lx, size 0x%016lx, "
|
|
" type 0x%x\r\n",
|
|
k, e820[k].baseaddr,
|
|
e820[k].length,
|
|
e820[k].type);
|
|
|
|
return (NUM_E820_ENTRIES - removed);
|
|
}
|
|
|
|
int
|
|
acrn_sw_load(struct vmctx *ctx)
|
|
{
|
|
if (vsbl_file_name)
|
|
return acrn_sw_load_vsbl(ctx);
|
|
else if (ovmf_file_name)
|
|
return acrn_sw_load_ovmf(ctx);
|
|
else if (kernel_file_name)
|
|
return acrn_sw_load_bzimage(ctx);
|
|
else if (elf_file_name)
|
|
return acrn_sw_load_elf(ctx);
|
|
else
|
|
return -1;
|
|
}
|