From 2e373d2c7d6f6ca22cfc7c907e62bb34bdd83bab Mon Sep 17 00:00:00 2001 From: Axel Heider Date: Wed, 8 Mar 2023 20:29:58 +0100 Subject: [PATCH] vm_arm: use dedicated namespace for VM config - Avoid polluting the global name space and group things in a struct - Pass config down to make the code more modular Signed-off-by: Axel Heider --- components/VM_Arm/src/main.c | 82 ++++++++++-------- components/VM_Arm/src/modules/init_ram.c | 5 +- templates/seL4VMParameters.template.c | 101 +++++++++++++---------- templates/seL4VMParameters.template.h | 51 +++++++----- 4 files changed, 141 insertions(+), 98 deletions(-) diff --git a/components/VM_Arm/src/main.c b/components/VM_Arm/src/main.c index 1865d404..ff65e211 100644 --- a/components/VM_Arm/src/main.c +++ b/components/VM_Arm/src/main.c @@ -395,7 +395,7 @@ static int camkes_vm_utspace_alloc_at(void *data, const cspacepath_t *dest, seL4 } -static int vmm_init(void) +static int vmm_init(const vm_config_t *vm_config) { vka_object_t fault_ep_obj; vka_t *vka; @@ -446,7 +446,8 @@ static int vmm_init(void) vka_cspace_make_path(vka, cap, &path); int utType = device ? ALLOCMAN_UT_DEV : ALLOCMAN_UT_KERNEL; if (utType == ALLOCMAN_UT_DEV && - paddr >= ram_paddr_base && paddr <= (ram_paddr_base + (ram_size - 1))) { + paddr >= vm_config->ram.phys_base && + paddr <= (vm_config->ram.phys_base + (vm_config->ram.size - 1))) { utType = ALLOCMAN_UT_DEV_MEM; } err = allocman_utspace_add_uts(allocman, 1, &path, &size, &paddr, utType); @@ -461,8 +462,8 @@ static int vmm_init(void) cspacepath_t path; vka_cspace_make_path(vka, cap, &path); int utType = ALLOCMAN_UT_DEV; - if (paddr >= ram_paddr_base && - paddr <= (ram_paddr_base + (ram_size - 1))) { + if (paddr >= vm_config->ram.phys_base && + paddr <= (vm_config->ram.phys_base + (vm_config->ram.size - 1))) { utType = ALLOCMAN_UT_DEV_MEM; } err = allocman_utspace_add_uts(allocman, 1, &path, &size, &paddr, utType); @@ -706,8 +707,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; @@ -766,23 +768,26 @@ 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, 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; @@ -819,13 +824,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); @@ -834,14 +839,15 @@ 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; @@ -849,19 +855,20 @@ static int load_vm(vm_t *vm, const char *kernel_name, const char *dtb_name, cons /* 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; @@ -874,11 +881,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); @@ -891,21 +898,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; @@ -1113,7 +1123,7 @@ static int main_continued(void) return err; } - err = vmm_init(); + err = vmm_init(&vm_config); assert(!err); /* Create the VM */ @@ -1173,7 +1183,7 @@ static int main_continued(void) } /* 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(); diff --git a/components/VM_Arm/src/modules/init_ram.c b/components/VM_Arm/src/modules/init_ram.c index 600e2fc0..326fc66f 100644 --- a/components/VM_Arm/src/modules/init_ram.c +++ b/components/VM_Arm/src/modules/init_ram.c @@ -14,7 +14,10 @@ void WEAK init_ram_module(vm_t *vm, void *cookie) { - int err = vm_ram_register_at(vm, ram_base, ram_size, vm->mem.map_one_to_one); + int err = vm_ram_register_at(vm, + vm_config.ram.base, + vm_config.ram.size, + vm->mem.map_one_to_one); assert(!err); } diff --git a/templates/seL4VMParameters.template.c b/templates/seL4VMParameters.template.c index e4750194..797d4bae 100644 --- a/templates/seL4VMParameters.template.c +++ b/templates/seL4VMParameters.template.c @@ -1,5 +1,6 @@ /* * Copyright 2023, DornerWorks + * Copyright 2023, Hensoldt Cyber * * SPDX-License-Identifier: BSD-2-Clause */ @@ -16,49 +17,60 @@ /*- set is_64_bit = (8 == macros.get_word_size(options.architecture)) -*/ /*- set entry_offset = 0x80000 if is_64_bit else 0x8000 -*/ +const vm_config_t vm_config = { + /*- if vm_address_config -*/ -const unsigned long ram_base = /*? vm_address_config.get('ram_base') ?*/; -const unsigned long ram_paddr_base = /*? vm_address_config.get('ram_paddr_base') ?*/; -const unsigned long ram_size = /*? vm_address_config.get('ram_size') ?*/; -const unsigned long dtb_addr = /*? vm_address_config.get('dtb_addr') ?*/; -const unsigned long initrd_addr = /*? vm_address_config.get('initrd_addr') ?*/; + .ram = { + .phys_base = /*? vm_address_config.get('ram_paddr_base') ?*/, + .base = /*? vm_address_config.get('ram_base') ?*/, + .size = /*? vm_address_config.get('ram_size') ?*/, + }, + + .dtb_addr = /*? vm_address_config.get('dtb_addr') ?*/, + .initrd_addr = /*? vm_address_config.get('initrd_addr') ?*/, /*- if vm_address_config.get('kernel_entry_addr') != '-1' -*/ -const unsigned long entry_addr = /*? vm_address_config.get('kernel_entry_addr') ?*/; + .entry_addr = /*? vm_address_config.get('kernel_entry_addr') ?*/, /*- else -*/ #warning Using standard Linux entry point, please consider setting kernel_entry_addr explicitly. -const unsigned long entry_addr = ram_base + /*? '0x%x'%entry_offset ?*/; + .entry_addr = /*? vm_address_config.get('ram_base') ?*/ + /*? '0x%x'%entry_offset ?*/, /*- endif -*/ /*- else -*/ #warning You are using the deprecated linux_address_config structure. Please use the vm_address_config structure instead -const unsigned long ram_base = /*? linux_address_config.get('linux_ram_base') ?*/; -const unsigned long ram_paddr_base = /*? linux_address_config.get('linux_ram_paddr_base') ?*/; -const unsigned long ram_size = /*? linux_address_config.get('linux_ram_size') ?*/; -const unsigned long dtb_addr = /*? linux_address_config.get('dtb_addr') ?*/; -const unsigned long initrd_addr = /*? linux_address_config.get('initrd_addr') ?*/; -/* Use standard Linux entry point. */ -const unsigned long entry_addr = ram_base + /*? '0x%x'%entry_offset ?*/; + .ram = { + .phys_base = /*? linux_address_config.get('linux_ram_paddr_base') ?*/, + .base = /*? linux_address_config.get('linux_ram_base') ?*/, + .size = /*? linux_address_config.get('linux_ram_size') ?*/, + }, + + .dtb_addr = /*? linux_address_config.get('dtb_addr') ?*/, + .initrd_addr = /*? linux_address_config.get('initrd_addr') ?*/, + /* Use standard Linux entry point. */ + .entry_addr = /*? linux_address_config.get('linux_ram_base') ?*/ + /*? '0x%x'%entry_offset ?*/, /*- endif -*/ /*- if vm_image_config -*/ -const char *_kernel_name = "/*? vm_image_config.get('kernel_name') ?*/"; -const char *_dtb_name = "/*? vm_image_config.get('dtb_name', "") ?*/"; -const char *_initrd_name = "/*? vm_image_config.get('initrd_name', "") ?*/"; -const char *kernel_bootcmdline = "/*? vm_image_config.get('kernel_bootcmdline', "") ?*/"; -const char *kernel_stdout = "/*? vm_image_config.get('kernel_stdout', "") ?*/"; -const char *dtb_base_name = "/*? vm_image_config.get('dtb_base_name', "") ?*/"; + .provide_initrd = /*? vm_image_config.get('provide_initrd') ?*/, + .generate_dtb = /*? vm_image_config.get('generate_dtb') ?*/, + .provide_dtb = /*? vm_image_config.get('provide_dtb') ?*/, + .map_one_to_one = /*? vm_image_config.get('map_one_to_one') ?*/, + .clean_cache = /*? vm_image_config.get('clean_cache') ?*/, + + .files = { + .kernel = "/*? vm_image_config.get('kernel_name') ?*/", + .initrd = "/*? vm_image_config.get('initrd_name', "") ?*/", + .dtb = "/*? vm_image_config.get('dtb_name', "") ?*/", + .dtb_base = "/*? vm_image_config.get('dtb_base_name', "") ?*/", + }, -const int provide_initrd = /*? vm_image_config.get('provide_initrd') ?*/; -const int generate_dtb = /*? vm_image_config.get('generate_dtb') ?*/; -const int provide_dtb = /*? vm_image_config.get('provide_dtb') ?*/; -const int map_one_to_one = /*? vm_image_config.get('map_one_to_one') ?*/; -const int clean_cache = /*? vm_image_config.get('clean_cache') ?*/; + .kernel_bootcmdline = "/*? vm_image_config.get('kernel_bootcmdline', "") ?*/", + .kernel_stdout = "/*? vm_image_config.get('kernel_stdout', "") ?*/", /*- else -*/ @@ -66,39 +78,44 @@ const int clean_cache = /*? vm_image_config.get('clean_cache') ?*/; map_one_to_one, and clean_cache flags are set to replicate previous behavior, which may cause your configuration to break. \ Please use the vm_image_config structure instead." -const char *_kernel_name = "/*? linux_image_config.get('linux_name') ?*/"; -const char *_dtb_name = "/*? linux_image_config.get('dtb_name') ?*/"; -const char *_initrd_name = "/*? linux_image_config.get('initrd_name') ?*/"; -const char *kernel_bootcmdline = "/*? linux_image_config.get('linux_bootcmdline') ?*/"; -const char *kernel_stdout = "/*? linux_image_config.get('linux_stdout') ?*/"; -const char *dtb_base_name = "/*? linux_image_config.get('dtb_base_name') ?*/"; - #ifdef CONFIG_VM_INITRD_FILE #warning VmInitRdFile is a deprecated setting. Please remove and use vm_image_config.provide_initrd -const int provide_initrd = 1; + .provide_initrd = 1, #else -const int provide_initrd = 0; + .provide_initrd = 0, #endif #ifdef CONFIG_VM_DTB_FILE #warning VmDtbFile is a deprecated setting. Please remove and use vm_image_config.provide_dtb -const int provide_dtb = 1; -const int generate_dtb = 0; + .provide_dtb = 1, + .generate_dtb = 0, #else -const int provide_dtb = 0; -const int generate_dtb = 1; + .provide_dtb = 0, + .generate_dtb = 1, #endif #if defined(CONFIG_PLAT_EXYNOS5) || defined(CONFIG_PLAT_QEMU_ARM_VIRT) || defined(CONFIG_PLAT_TX2) -const int map_one_to_one = 1; + .map_one_to_one = 1, #else -const int map_one_to_one = 0; + .map_one_to_one = 0, #endif #if defined(CONFIG_PLAT_TX1) || defined(CONFIG_PLAT_TX2) -const int clean_cache = 1; + .clean_cache = 1, #else -const int clean_cache = 0; + .clean_cache = 0, #endif + .files = { + .kernel = "/*? linux_image_config.get('linux_name') ?*/", + .initrd = "/*? linux_image_config.get('initrd_name') ?*/", + .dtb = "/*? linux_image_config.get('dtb_name') ?*/", + .dtb_base = "/*? linux_image_config.get('dtb_base_name') ?*/", + }, + + .kernel_bootcmdline = "/*? linux_image_config.get('linux_bootcmdline') ?*/", + .kernel_stdout = "/*? linux_image_config.get('linux_stdout') ?*/", + /*- endif -*/ + +}; diff --git a/templates/seL4VMParameters.template.h b/templates/seL4VMParameters.template.h index 2fe180d0..3f196140 100644 --- a/templates/seL4VMParameters.template.h +++ b/templates/seL4VMParameters.template.h @@ -1,27 +1,40 @@ /* * Copyright 2023, DornerWorks + * Copyright 2023, Hensoldt Cyber * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -extern const unsigned long ram_base; -extern const unsigned long ram_paddr_base; -extern const unsigned long ram_size; -extern const unsigned long dtb_addr; -extern const unsigned long initrd_addr; -extern const unsigned long entry_addr; - -extern const int provide_initrd; -extern const int generate_dtb; -extern const int provide_dtb; -extern const int map_one_to_one; -extern const int clean_cache; - -extern const char *_kernel_name; -extern const char *_dtb_name; -extern const char *_initrd_name; -extern const char *kernel_bootcmdline; -extern const char *kernel_stdout; -extern const char *dtb_base_name; +typedef struct { + + struct { + unsigned long phys_base; + unsigned long base; + unsigned long size; + } ram; + + int provide_initrd; + int generate_dtb; + int provide_dtb; + int map_one_to_one; + int clean_cache; + + unsigned long dtb_addr; + unsigned long initrd_addr; + unsigned long entry_addr; + + struct { + char const *kernel; + char const *initrd; + char const *dtb; + char const *dtb_base; + } files; + + char const *kernel_bootcmdline; + char const *kernel_stdout; + +} vm_config_t; + +extern const vm_config_t vm_config;