From 7bcb81314fbae3ff82d0dd63231f40bec58fa3a5 Mon Sep 17 00:00:00 2001 From: Yifan Liu Date: Mon, 6 Oct 2025 14:10:47 +0000 Subject: [PATCH] hv: riscv: initialize service vm vfdt Initialize Service VM vFDT by reserving hypervisor and pre-launched VM memory regions. The vFDT is copied to Service VM to the place just before the kernel load address, and this needs to be fixed later when MMU module is implemented. Tracked-On: #8841 Signed-off-by: Yifan Liu Acked-by: Wang Yu1 --- hypervisor/Makefile | 3 ++ hypervisor/arch/riscv/guest/vm.c | 11 ++++++ hypervisor/arch/x86/guest/vm.c | 2 + hypervisor/boot/guest/rawimage_loader.c | 8 ++++ hypervisor/common/vfdt.c | 50 +++++++++++++++++++++++++ hypervisor/common/vfdt_static.c | 15 ++++++++ hypervisor/include/common/vm.h | 3 ++ hypervisor/include/dm/vfdt.h | 7 ++++ 8 files changed, 99 insertions(+) create mode 100644 hypervisor/common/vfdt.c create mode 100644 hypervisor/common/vfdt_static.c 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 */