Skip to content

Commit

Permalink
Merge patch-axel-19a
Browse files Browse the repository at this point in the history
  • Loading branch information
Axel Heider committed Mar 29, 2023
2 parents 5094c59 + 0a8ac78 commit 9ec3ecb
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 146 deletions.
2 changes: 1 addition & 1 deletion components/VM_Arm/configurations/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
emits HaveNotification notification_ready_connector; \
maybe uses VMDTBPassthrough dtb_self; \
provides VMDTBPassthrough dtb; \
attribute int base_prio; \
attribute int base_prio = 100; \
attribute int num_vcpus = 1; \
attribute int num_extra_frame_caps; \
attribute int extra_frame_map_address; \
Expand Down
4 changes: 2 additions & 2 deletions components/VM_Arm/src/fdt_manipulation.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static int append_prop_with_cells(void *fdt, int offset, uint64_t val, int num_
return err;
}

int fdt_generate_memory_node(void *fdt, unsigned long base, size_t size)
int fdt_generate_memory_node(void *fdt, uintptr_t base, size_t size)
{
int root_offset = fdt_path_offset(fdt, "/");
int address_cells = fdt_address_cells(fdt, root_offset);
Expand Down Expand Up @@ -92,7 +92,7 @@ int fdt_generate_chosen_node(void *fdt, const char *stdout_path, const char *boo
return 0;
}

int fdt_append_chosen_node_with_initrd_info(void *fdt, unsigned long base, size_t size)
int fdt_append_chosen_node_with_initrd_info(void *fdt, uintptr_t base, size_t size)
{
int root_offset = fdt_path_offset(fdt, "/");
int address_cells = fdt_address_cells(fdt, root_offset);
Expand Down
4 changes: 2 additions & 2 deletions components/VM_Arm/src/fdt_manipulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @param size, the size of the memory region
* @return -1 on error, 0 otherwise
*/
int fdt_generate_memory_node(void *fdt, unsigned long base, size_t size);
int fdt_generate_memory_node(void *fdt, uintptr_t base, size_t size);

/**
* generate a "chosen" node
Expand All @@ -33,4 +33,4 @@ int fdt_generate_chosen_node(void *fdt, const char *stdout_path, const char *boo
* @param size, the size of the initrd image
* @return -1 on error, 0 otherwise
*/
int fdt_append_chosen_node_with_initrd_info(void *fdt, unsigned long base, size_t size);
int fdt_append_chosen_node_with_initrd_info(void *fdt, uintptr_t base, size_t size);
153 changes: 81 additions & 72 deletions components/VM_Arm/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,6 @@ seL4_CPtr camkes_alloc(seL4_ObjectType type, size_t size, unsigned flags);
extern void *fs_buf;
int start_extra_frame_caps;

int VM_PRIO = 100;
int NUM_VCPUS = 1;

#define IRQSERVER_PRIO (VM_PRIO + 1)
#define IRQ_MESSAGE_LABEL 0xCAFE

#define DMA_VSTART 0x40000000
Expand Down Expand Up @@ -129,6 +125,13 @@ int get_crossvm_irq_num(void)
return free_plat_interrupts[0];
}

static vm_vcpu_t *vm_get_boot_vcpu(vm_t *vm, const vm_config_t *vm_config)
{
assert(BOOT_VCPU < vm_config->num_vcpus);
assert(BOOT_VCPU < ARRAY_SIZE(vm->vcpus));
return vm->vcpus[BOOT_VCPU];
}

static int _dma_morecore(size_t min_size, int cached, struct dma_mem_descriptor *dma_desc)
{
static uint32_t _vaddr = DMA_VSTART;
Expand Down Expand Up @@ -395,8 +398,8 @@ static int camkes_vm_utspace_alloc_at(void *data, const cspacepath_t *dest, seL4

}

static bool add_uts(vka_t *vka, seL4_CPtr cap, uintptr_t paddr, size_t size_bits,
bool is_device)
static bool add_uts(const vm_config_t *vm_config, vka_t *vka, seL4_CPtr cap, uintptr_t paddr,
size_t size_bits, bool is_device)
{
cspacepath_t path;
vka_cspace_make_path(vka, cap, &path);
Expand Down Expand Up @@ -437,8 +440,8 @@ static bool add_uts(vka_t *vka, seL4_CPtr cap, uintptr_t paddr, size_t size_bits
* "ram_base".
*/

bool is_guest_ram = (paddr >= ram_paddr_base) &&
((paddr - ram_paddr_base) < ram_size);
bool is_guest_ram = (paddr >= vm_config->ram.phys_base) &&
((paddr - vm_config->ram.phys_base) < vm_config->ram.size);

int ut_type = !is_device ? ALLOCMAN_UT_KERNEL
: is_guest_ram ? ALLOCMAN_UT_DEV_MEM
Expand All @@ -450,7 +453,7 @@ static bool add_uts(vka_t *vka, seL4_CPtr cap, uintptr_t paddr, size_t size_bits
ut_type);
}

static int vmm_init(void)
static int vmm_init(const vm_config_t *vm_config)
{
vka_object_t fault_ep_obj;
vka_t *vka;
Expand Down Expand Up @@ -499,7 +502,7 @@ static int vmm_init(void)
uintptr_t paddr;
bool is_device;
seL4_CPtr cap = simple_get_nth_untyped(simple, i, &size_bits, &paddr, &is_device);
err = add_uts(vka, cap, paddr, size_bits, is_device);
err = add_uts(vm_config, vka, cap, paddr, size_bits, is_device);
assert(!err);
}

Expand All @@ -511,7 +514,7 @@ static int vmm_init(void)
uintptr_t paddr;
seL4_CPtr cap = camkes_dtb_get_nth_untyped(i, &size_bits, &paddr);
/* These UTs are considered device untypeds */
err = add_uts(vka, cap, paddr, size_bits, true);
err = add_uts(vm_config, vka, cap, paddr, size_bits, true);
assert(!err);
}
}
Expand Down Expand Up @@ -544,7 +547,7 @@ static int vmm_init(void)
assert(!err);

/* Create an IRQ server */
_irq_server = irq_server_new(vspace, vka, IRQSERVER_PRIO,
_irq_server = irq_server_new(vspace, vka, vm_config->priority.irqserver,
simple, simple_get_cnode(simple), fault_ep_obj.cptr,
IRQ_MESSAGE_LABEL, 256, &_io_ops.malloc_ops);
assert(_irq_server);
Expand Down Expand Up @@ -659,8 +662,8 @@ static void irq_handler(void *data, ps_irq_acknowledge_fn_t acknowledge_fn, void
/* Fill in the rest of the details */
token->acknowledge_fn = acknowledge_fn;
token->ack_data = ack_data;
int err;
err = vm_inject_irq(token->vm->vcpus[BOOT_VCPU], token->virq);
vm_vcpu_t *vcpu_boot = vm_get_boot_vcpu(token->vm, &vm_config);
int err = vm_inject_irq(vcpu_boot, token->virq);
if (err) {
ZF_LOGW("IRQ %d Dropped", token->virq);
}
Expand Down Expand Up @@ -752,8 +755,9 @@ static int route_irqs(vm_vcpu_t *vcpu, irq_server_t *irq_server)
return 0;
}

static int generate_fdt(vm_t *vm, void *fdt_ori, void *gen_fdt, int buf_size, size_t initrd_size, char **paths,
int num_paths)
static int generate_fdt(vm_t *vm, const vm_config_t *vm_config,
void *fdt_ori, void *gen_fdt, int buf_size,
size_t initrd_size, char **paths, int num_paths)
{
int err = 0;

Expand Down Expand Up @@ -812,23 +816,27 @@ static int generate_fdt(vm_t *vm, void *fdt_ori, void *gen_fdt, int buf_size, si
return -1;
}

/* generate a memory node (ram_base and ram_size) */
err = fdt_generate_memory_node(gen_fdt, ram_base, ram_size);
/* generate a memory node */
err = fdt_generate_memory_node(gen_fdt, vm_config->ram.base,
vm_config->ram.size);
if (err) {
ZF_LOGE("Couldn't generate memory_node (%d)\n", err);
return -1;
}

/* generate a chosen node (vm_image_config.kernel_bootcmdline, kernel_stdout) */
err = fdt_generate_chosen_node(gen_fdt, kernel_stdout, kernel_bootcmdline,
NUM_VCPUS);
/* generate a chosen node */
err = fdt_generate_chosen_node(gen_fdt, vm_config->kernel_stdout,
vm_config->kernel_bootcmdline,
vm_config->num_vcpus);
if (err) {
ZF_LOGE("Couldn't generate chosen_node (%d)\n", err);
return -1;
}

if (provide_initrd) {
err = fdt_append_chosen_node_with_initrd_info(gen_fdt, initrd_addr, initrd_size);
if (vm_config->provide_initrd) {
err = fdt_append_chosen_node_with_initrd_info(gen_fdt,
vm_config->initrd_addr,
initrd_size);
if (err) {
ZF_LOGE("Couldn't generate chosen_node_with_initrd_info (%d)\n", err);
return -1;
Expand Down Expand Up @@ -865,13 +873,13 @@ static int load_generated_dtb(vm_t *vm, uintptr_t paddr, void *addr, size_t size
return 0;
}

static int load_vm(vm_t *vm, const char *kernel_name, const char *dtb_name, const char *initrd_name)
static int load_vm(vm_t *vm, const vm_config_t *vm_config)
{
seL4_Word entry;
seL4_Word dtb;
int err;

vm->mem.map_one_to_one = map_one_to_one; /* Map memory 1:1 if configured to do so */
vm->mem.map_one_to_one = vm_config->map_one_to_one; /* Map memory 1:1 if configured to do so */

/* Install devices */
err = install_vm_devices(vm);
Expand All @@ -880,34 +888,36 @@ static int load_vm(vm_t *vm, const char *kernel_name, const char *dtb_name, cons
return -1;
}

vm->entry = entry_addr;
vm->mem.clean_cache = clean_cache;
vm->entry = vm_config->entry_addr;
vm->mem.clean_cache = vm_config->clean_cache;

printf("Loading Kernel: \'%s\'\n", kernel_name);
printf("Loading Kernel: \'%s\'\n", vm_config->files.kernel);

/* Load kernel */
guest_kernel_image_t kernel_image_info;
err = vm_load_guest_kernel(vm, kernel_name, ram_base, 0, &kernel_image_info);
err = vm_load_guest_kernel(vm, vm_config->files.kernel, vm_config->ram.base,
0, &kernel_image_info);
entry = kernel_image_info.kernel_image.load_paddr;
if (!entry || err) {
return -1;
}

/* Attempt to load initrd if provided */
guest_image_t initrd_image;
if (provide_initrd) {
printf("Loading Initrd: \'%s\'\n", initrd_name);
err = vm_load_guest_module(vm, initrd_name, initrd_addr, 0, &initrd_image);
if (vm_config->provide_initrd) {
printf("Loading Initrd: \'%s\'\n", vm_config->files.initrd);
err = vm_load_guest_module(vm, vm_config->files.initrd,
vm_config->initrd_addr, 0, &initrd_image);
void *initrd = (void *)initrd_image.load_paddr;
if (!initrd || err) {
return -1;
}
}

ZF_LOGW_IF(provide_dtb && generate_dtb,
ZF_LOGW_IF(vm_config->provide_dtb && vm_config->generate_dtb,
"provide_dtb and generate_dtb are both set. The provided dtb will NOT be loaded");

if (generate_dtb) {
if (vm_config->generate_dtb) {
void *fdt_ori;
void *gen_fdt = gen_dtb_buf;
int size_gen = DTB_BUFFER_SIZE;
Expand All @@ -920,11 +930,11 @@ static int load_vm(vm_t *vm, const char *kernel_name, const char *dtb_name, cons
int dtb_fd = -1;

/* No point checking the file server if the string is empty! */
if ((NULL != dtb_base_name) && (dtb_base_name[0] != '\0')) {
dtb_fd = open(dtb_base_name, 0);
if ((NULL != vm_config->files.dtb_base) && (vm_config->files.dtb_base[0] != '\0')) {
dtb_fd = open(vm_config->files.dtb_base, 0);
}

/* If dtb_base_name is in the file server, grab it and use it as a base */
/* If dtb_base is in the file server, grab it and use it as a base */
if (dtb_fd >= 0) {
size_t dtb_len = read(dtb_fd, gen_dtb_base_buf, DTB_BUFFER_SIZE);
close(dtb_fd);
Expand All @@ -937,21 +947,24 @@ static int load_vm(vm_t *vm, const char *kernel_name, const char *dtb_name, cons
fdt_ori = (void *)ps_io_fdt_get(&_io_ops.io_fdt);
}

err = generate_fdt(vm, fdt_ori, gen_fdt, size_gen, initrd_image.size, paths, num_paths);
err = generate_fdt(vm, vm_config, fdt_ori, gen_fdt, size_gen,
initrd_image.size, paths, num_paths);
if (err) {
ZF_LOGE("Failed to generate a fdt");
return -1;
}
vm_ram_mark_allocated(vm, dtb_addr, size_gen);
vm_ram_touch(vm, dtb_addr, size_gen, load_generated_dtb, gen_fdt);
vm_ram_mark_allocated(vm, vm_config->dtb_addr, size_gen);
vm_ram_touch(vm, vm_config->dtb_addr, size_gen, load_generated_dtb,
gen_fdt);
printf("Loading Generated DTB\n");
dtb = dtb_addr;
} else if (provide_dtb) {
printf("Loading DTB: \'%s\'\n", dtb_name);
dtb = vm_config->dtb_addr;
} else if (vm_config->provide_dtb) {
printf("Loading DTB: \'%s\'\n", vm_config->files.dtb);

/* Load device tree */
guest_image_t dtb_image;
err = vm_load_guest_module(vm, dtb_name, dtb_addr, 0, &dtb_image);
err = vm_load_guest_module(vm, vm_config->files.dtb,
vm_config->dtb_addr, 0, &dtb_image);
dtb = dtb_image.load_paddr;
if (!dtb || err) {
return -1;
Expand All @@ -962,7 +975,8 @@ static int load_vm(vm_t *vm, const char *kernel_name, const char *dtb_name, cons
}

/* Set boot arguments */
err = vcpu_set_bootargs(vm->vcpus[BOOT_VCPU], entry, MACH_TYPE, dtb);
vm_vcpu_t *vcpu_boot = vm_get_boot_vcpu(vm, vm_config);
err = vcpu_set_bootargs(vcpu_boot, entry, MACH_TYPE, dtb);
if (err) {
printf("Error: Failed to set boot arguments\n");
return -1;
Expand Down Expand Up @@ -1159,7 +1173,7 @@ static int main_continued(void)
return err;
}

err = vmm_init();
err = vmm_init(&vm_config);
assert(!err);

/* Create the VM */
Expand Down Expand Up @@ -1202,31 +1216,32 @@ static int main_continued(void)
err = vm_create_default_irq_controller(&vm);
assert(!err);

for (int i = 0; i < NUM_VCPUS; i++) {
vm_vcpu_t *new_vcpu = create_vmm_plat_vcpu(&vm, VM_PRIO - 1);
ZF_LOGD("Creating %d VCPUs", vm_config.num_vcpus);
for (int i = 0; i < vm_config.num_vcpus; i++) {
vm_vcpu_t *new_vcpu = create_vmm_plat_vcpu(&vm, vm_config.priority.vcpu);
assert(new_vcpu);
}
vm_vcpu_t *vm_vcpu = vm.vcpus[BOOT_VCPU];
err = vm_assign_vcpu_target(vm_vcpu, 0);
vm_vcpu_t *vcpu_boot = vm_get_boot_vcpu(&vm, &vm_config);
err = vm_assign_vcpu_target(vcpu_boot, 0);
if (err) {
return -1;
}

/* Route IRQs */
err = route_irqs(vm_vcpu, _irq_server);
err = route_irqs(vcpu_boot, _irq_server);
if (err) {
return -1;
}

/* Load system images */
err = load_vm(&vm, _kernel_name, _dtb_name, _initrd_name);
err = load_vm(&vm, &vm_config);
if (err) {
printf("Failed to load VM image\n");
seL4_DebugHalt();
return -1;
}

err = vcpu_start(vm_vcpu);
err = vcpu_start(vcpu_boot);
if (err) {
ZF_LOGE("Failed to start Boot VCPU");
return -1;
Expand All @@ -1244,27 +1259,21 @@ static int main_continued(void)
return 0;
}

/* base_prio and num_vcpus are optional attributes of the VM component. */
extern const int __attribute__((weak)) base_prio;
extern const int __attribute__((weak)) num_vcpus;

int run(void)
{
/* if the base_prio attribute is set, use it */
if (&base_prio != NULL) {
VM_PRIO = base_prio;
}
/* if the num_vcpus attribute is set, try to use it */
if (&num_vcpus != NULL) {
if (num_vcpus > CONFIG_MAX_NUM_NODES) {
ZF_LOGE("Invalid 'num_vcpus' attribute setting: Exceeds maximum number of supported nodes. Capping value to CONFIG_MAX_NUM_NODES (%d)",
CONFIG_MAX_NUM_NODES);
NUM_VCPUS = CONFIG_MAX_NUM_NODES;
} else if (num_vcpus <= 0) {
ZF_LOGE("Invalid 'num_vcpus' attribute setting: Can't have 0 or negative amount of vcpus. Capping value to 1 vcpu (default value)");
} else {
NUM_VCPUS = num_vcpus;
}
if (vm_config.priority.irqserver <= vm_config.priority.vmm) {
ZF_LOGF("IRQ server priority (%u) must be higher than VMM priority (%u)",
vm_config.priority.irqserver, vm_config.priority.vmm);
}

if (vm_config.priority.vmm <= vm_config.priority.vcpu) {
ZF_LOGF("VMM priority (%u) must be higher than VCPU priority (%u)",
vm_config.priority.vmm, vm_config.priority.vcpu);
}

if (vm_config.num_vcpus > CONFIG_MAX_NUM_NODES) {
ZF_LOGF("Number of VCPUs (%u) exceeds CONFIG_MAX_NUM_NODES (%u)",
vm_config.num_vcpus, CONFIG_MAX_NUM_NODES);
}

return main_continued();
Expand Down
Loading

0 comments on commit 9ec3ecb

Please sign in to comment.