diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 2139e2dfa..ed23660fe 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -179,6 +179,9 @@ COMMON_C_SRCS += lib/fdt/fdt_rw.c COMMON_C_SRCS += lib/fdt/fdt_strerror.c COMMON_C_SRCS += lib/fdt/fdt_sw.c COMMON_C_SRCS += lib/fdt/fdt_wip.c +COMMON_C_SRCS += common/vfdt.c +else +COMMON_C_SRCS += common/vfdt_static.c endif ifdef STACK_PROTECTOR diff --git a/hypervisor/arch/riscv/guest/vm.c b/hypervisor/arch/riscv/guest/vm.c index 9e57646f9..76d16489f 100644 --- a/hypervisor/arch/riscv/guest/vm.c +++ b/hypervisor/arch/riscv/guest/vm.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -52,6 +53,11 @@ int32_t arch_init_vm(struct acrn_vm *vm, struct acrn_vm_config *vm_config) init_vsbi(vm); (void)vm_config; + + if (is_service_vm(vm)) { + init_service_vm_vfdt(vm); + } + return 0; } @@ -84,3 +90,8 @@ void arch_vm_prepare_bsp(struct acrn_vcpu *vcpu) void arch_trigger_level_intr(__unused struct acrn_vm *vm, __unused uint32_t irq, __unused bool assert) {} + +void arch_init_service_vm_vfdt(struct acrn_vm *vm) +{ + (void)vm; +} diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index fcf64aea1..1b9f75fc3 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -932,3 +932,5 @@ void arch_trigger_level_intr(struct acrn_vm *vm, uint32_t irq, bool assert) vpic_set_irqline(vm_pic(vm), irq, operation); vioapic_set_irqline_lock(vm, irq, operation); } + +void arch_init_service_vm_vfdt(__unused struct acrn_vm *vm) { } diff --git a/hypervisor/boot/guest/rawimage_loader.c b/hypervisor/boot/guest/rawimage_loader.c index 489abdb18..b73796f0e 100644 --- a/hypervisor/boot/guest/rawimage_loader.c +++ b/hypervisor/boot/guest/rawimage_loader.c @@ -7,6 +7,7 @@ #include #include #include +#include /** * @pre vm != NULL @@ -20,6 +21,13 @@ static void load_rawimage(struct acrn_vm *vm) /* TODO: GPA 0 load support */ kernel_load_gpa = vm_config->os_config.kernel_load_addr; + /* TODO: For simplicity assume there are enough space just before kernel load address + * Fix this after implementing find_space_from_vm_vfdt API + */ + if (vm->sw.fdt_info.src_addr != NULL) { + vm->sw.fdt_info.load_addr = (void *)round_page_down(kernel_load_gpa - MAX_FDT_SIZE); + } + /* Copy the guest kernel image to its run-time location */ (void)copy_to_gpa(vm, sw_kernel->kernel_src_addr, kernel_load_gpa, sw_kernel->kernel_size); diff --git a/hypervisor/common/vfdt.c b/hypervisor/common/vfdt.c new file mode 100644 index 000000000..eaffd2aa7 --- /dev/null +++ b/hypervisor/common/vfdt.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2025 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +void init_service_vm_vfdt(struct acrn_vm *vm) +{ + void *fdt = vm_get_vfdt(vm); + struct acrn_vm_config *vm_config; + uint16_t vm_id; + uint64_t i, addr, size; + + /* Re-use host FDT */ + fdt_move(get_host_fdt(), fdt, MAX_FDT_SIZE); + + /* Reserve hypervisor mem range */ + fdt_add_rsvd_node(fdt, get_hv_image_base(), get_hv_image_size()); + + /* Remove hv owned devices */ + /* TODO: to be implemented */ + + /* Reserve pre-launched VM mem range */ + for (vm_id = 0; vm_id < CONFIG_MAX_VM_NUM; vm_id++) { + vm_config = get_vm_config(vm_id); + if (vm_config->load_order == PRE_LAUNCHED_VM) { + for (i = 0; i < vm_config->memory.region_num; i++) { + addr = vm_config->memory.host_regions[i].start_hpa; + size = vm_config->memory.host_regions[i].size_hpa; + fdt_add_rsvd_node(fdt, addr, size); + } + } + } + + /* Remove pre-launch owned devices */ + /* TODO: to be implemented */ + + arch_init_service_vm_vfdt(vm); + + vm->sw.fdt_info.src_addr = fdt; + vm->sw.fdt_info.size = fdt_totalsize(fdt); + /* load addr is initialized in image loader */ +} diff --git a/hypervisor/common/vfdt_static.c b/hypervisor/common/vfdt_static.c new file mode 100644 index 000000000..312780661 --- /dev/null +++ b/hypervisor/common/vfdt_static.c @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2025 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +void init_service_vm_vfdt(struct acrn_vm *vm) +{ + /* TODO: to be implemented */ + (void)vm; +} diff --git a/hypervisor/include/common/vm.h b/hypervisor/include/common/vm.h index cdcba0108..f8d6d4ae2 100644 --- a/hypervisor/include/common/vm.h +++ b/hypervisor/include/common/vm.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -100,6 +101,8 @@ struct acrn_vm { void *root_stg2ptp; struct pgtable stg2_pgtable; spinlock_t stg2pt_lock; /* Spin-lock used to protect stg2pt to add/modify/remove for a VM */ + + uint8_t fdt_raw[MAX_FDT_SIZE] __aligned(8); } __aligned(PAGE_SIZE); /* diff --git a/hypervisor/include/dm/vfdt.h b/hypervisor/include/dm/vfdt.h index dcec0b4bf..f81e06f1b 100644 --- a/hypervisor/include/dm/vfdt.h +++ b/hypervisor/include/dm/vfdt.h @@ -12,4 +12,11 @@ */ #define VIRT_FDT_LOAD_ADDR 0x80200000UL +void init_service_vm_vfdt(struct acrn_vm *vm); +void arch_init_service_vm_vfdt(struct acrn_vm *vm); + +static inline void *vm_get_vfdt(struct acrn_vm *vm) { + return (void *)vm->fdt_raw; +} + #endif /* VFDT_H */