From e6f65bf3d261b471fd6390ccaebf3d0ac2b97476 Mon Sep 17 00:00:00 2001 From: su-orange-hxy <3037915984@qq.com> Date: Tue, 7 May 2024 13:57:08 +0800 Subject: [PATCH] Virtualization: supporting "zvm delete vm" --- auto_zvm.sh | 1 + .../arm64/qemu_cortex_max/qemu_cortex_max.dts | 2 +- include/virtualization/os/os_linux.h | 3 +- include/virtualization/vm.h | 4 +-- include/virtualization/vm_dev.h | 2 ++ samples/_zvm/boards/qemu_cortex_max_smp.conf | 2 +- .../_zvm/boards/qemu_cortex_max_smp.overlay | 5 ++++ samples/_zvm/prj.conf | 4 +-- subsys/virtualization/os/os.c | 1 + subsys/virtualization/os/os_linux.c | 15 ++++++++++ subsys/virtualization/vdev/virtio_blk.c | 12 ++++---- subsys/virtualization/vm.c | 30 ++++--------------- subsys/virtualization/vm_dev.c | 30 +++++++++++++++++++ subsys/virtualization/vm_manager.c | 19 ++++++++++-- subsys/virtualization/vm_mm.c | 8 ++--- 15 files changed, 94 insertions(+), 44 deletions(-) diff --git a/auto_zvm.sh b/auto_zvm.sh index 3c12b5b71..d67301e4f 100755 --- a/auto_zvm.sh +++ b/auto_zvm.sh @@ -45,6 +45,7 @@ elif [ "$OPS" = "$ops_debug" ]; then -serial chardev:con -mon chardev=con,mode=readline -serial pty -serial pty -smp cpus=4 \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/zephyr.bin,addr=0xf2000000,force-raw=on \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/Image,addr=0xf3000000,force-raw=on \ + -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/Image,addr=0xe0000000,force-raw=on \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/linux-qemu-virtio.dtb,addr=0xf2a00000 \ -kernel $(pwd)/build/zephyr/zvm_host.elf diff --git a/boards/arm64/qemu_cortex_max/qemu_cortex_max.dts b/boards/arm64/qemu_cortex_max/qemu_cortex_max.dts index 52a4c74df..7d298651c 100644 --- a/boards/arm64/qemu_cortex_max/qemu_cortex_max.dts +++ b/boards/arm64/qemu_cortex_max/qemu_cortex_max.dts @@ -28,7 +28,7 @@ soc { sram0: memory@40000000 { compatible = "mmio-sram"; - reg = <0x0 0x40000000 0x0 DT_SIZE_M(512)>; + reg = <0x0 0x40000000 0x0 DT_SIZE_M(3072)>; }; }; diff --git a/include/virtualization/os/os_linux.h b/include/virtualization/os/os_linux.h index 128aea4bb..5cd3da847 100644 --- a/include/virtualization/os/os_linux.h +++ b/include/virtualization/os/os_linux.h @@ -22,7 +22,8 @@ #define LINUX_VM_IMAGE_SIZE DT_REG_SIZE(DT_NODELABEL(linux_ddr)) #define LINUX_VMSYS_BASE DT_PROP(DT_NODELABEL(linux_ddr), vm_reg_base) #define LINUX_VMSYS_SIZE DT_PROP(DT_NODELABEL(linux_ddr), vm_reg_size) - +#define LINUX_VMCPY_BASE DT_REG_ADDR(DT_ALIAS(linuxcpy)) +#define LINUX_VMCPY_SIZE DT_REG_SIZE(DT_ALIAS(linuxcpy)) #ifdef CONFIG_DTB_FILE_INPUT #define LINUX_DTB_MEM_BASE DT_PROP(DT_INST(0, linux_vm), dtb_address) #define LINUX_DTB_MEM_SIZE DT_PROP(DT_INST(0, linux_vm), dtb_size) diff --git a/include/virtualization/vm.h b/include/virtualization/vm.h index fbd367640..c32b25687 100644 --- a/include/virtualization/vm.h +++ b/include/virtualization/vm.h @@ -240,8 +240,8 @@ int z_list_vms_info(uint16_t vmid); * @param vm: the vm ready to init. * @return int : error code. */ -int vm_sysinfo_init(size_t argc, char **argv, struct vm **vm_ptr, struct getopt_state *state, - struct z_vm_info **vm_info_ptr); +int vm_sysinfo_init(size_t argc, char **argv, struct vm *vm_ptr, struct getopt_state *state, + struct z_vm_info *vm_info_ptr); /** * @brief Process vm exit for pause or delete vm now. diff --git a/include/virtualization/vm_dev.h b/include/virtualization/vm_dev.h index 204436475..39a093ed1 100644 --- a/include/virtualization/vm_dev.h +++ b/include/virtualization/vm_dev.h @@ -76,6 +76,8 @@ struct virt_dev *vm_virt_dev_add(struct vm *vm, const char *dev_name, bool pt_fl bool shareable, uint32_t dev_pbase, uint32_t dev_vbase, uint32_t dev_size, uint32_t dev_hirq, uint32_t dev_virq); +int vm_virt_dev_remove(struct vm *vm, struct virt_dev *vm_dev); + /** * @brief write or read vdev for VM operation.... */ diff --git a/samples/_zvm/boards/qemu_cortex_max_smp.conf b/samples/_zvm/boards/qemu_cortex_max_smp.conf index adac4b289..6bcd46716 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.conf +++ b/samples/_zvm/boards/qemu_cortex_max_smp.conf @@ -7,7 +7,7 @@ CONFIG_ARMV8_A_NS=y # kernel vm size(16M virt ram start + size) # It is the virt size of kernel, must bigger than true kernel size. #CONFIG_KERNEL_VM_SIZE=0xb0c00000 -CONFIG_KERNEL_VM_SIZE=0x20000000 +CONFIG_KERNEL_VM_SIZE=0xC0000000 # uart CONFIG_UART_PL011_PORT1=n diff --git a/samples/_zvm/boards/qemu_cortex_max_smp.overlay b/samples/_zvm/boards/qemu_cortex_max_smp.overlay index b2fe94b70..7d8712f79 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.overlay +++ b/samples/_zvm/boards/qemu_cortex_max_smp.overlay @@ -25,6 +25,7 @@ vmrtc = "/soc/pl031@9010000"; vmpmu = "/soc/pmu"; vmflash = "/soc/flash@0"; + linuxcpy = "/soc/linux_cpy@e0000000"; }; chosen { @@ -188,6 +189,10 @@ compatible = "arm,armv8-pmuv3"; }; + linux_cpy@e0000000 { + reg = <0x0 0xe0000000 0x0 DT_SIZE_M(240)>; + }; + }; vm_zephyr_space { diff --git a/samples/_zvm/prj.conf b/samples/_zvm/prj.conf index c56588ec8..de39c5e24 100644 --- a/samples/_zvm/prj.conf +++ b/samples/_zvm/prj.conf @@ -59,10 +59,10 @@ CONFIG_ISR_STACK_SIZE=65536 CONFIG_SHELL_STACK_SIZE=65536 # 32*4MB heap size. -CONFIG_HEAP_MEM_POOL_SIZE=134217728 +CONFIG_HEAP_MEM_POOL_SIZE=385875968 # MAX table -CONFIG_MAX_XLAT_TABLES=256 +CONFIG_MAX_XLAT_TABLES=10240 # dynamic memory allocation CONFIG_VM_DYNAMIC_MEMORY=n diff --git a/subsys/virtualization/os/os.c b/subsys/virtualization/os/os.c index dd779e54d..565686329 100644 --- a/subsys/virtualization/os/os.c +++ b/subsys/virtualization/os/os.c @@ -165,6 +165,7 @@ out: vm_info->vm_image_size = tmp_vm_info.vm_image_size; vm_info->vm_virt_base = tmp_vm_info.vm_virt_base; vm_info->vm_os_type = tmp_vm_info.vm_os_type; + vm_info->vm_sys_size = tmp_vm_info.vm_sys_size; /* Get the vm's entry point */ #if defined(CONFIG_SOC_QEMU_CORTEX_MAX) diff --git a/subsys/virtualization/os/os_linux.c b/subsys/virtualization/os/os_linux.c index a2dad8849..683cad6d2 100644 --- a/subsys/virtualization/os/os_linux.c +++ b/subsys/virtualization/os/os_linux.c @@ -50,6 +50,21 @@ int load_linux_image(struct vm_mem_domain *vmem_domain) ARG_UNUSED(blk); ARG_UNUSED(this_vm); + uint64_t *src_hva, des_hva; + uint64_t num_m = LINUX_VM_IMAGE_SIZE / (1024 * 1024); + uint64_t src_hpa = LINUX_VMCPY_BASE; + uint64_t des_hpa = LINUX_VM_IMAGE_BASE; + uint64_t per_size = 1048576; //1M + + while(num_m){ + z_phys_map((uint8_t **)&src_hva, (uintptr_t)src_hpa, per_size, K_MEM_CACHE_NONE | K_MEM_PERM_RW); + z_phys_map((uint8_t **)&des_hva, (uintptr_t)des_hpa, per_size, K_MEM_CACHE_NONE | K_MEM_PERM_RW); + memcpy(des_hva, src_hva, per_size); + des_hpa += per_size; + src_hpa += per_size; + num_m--; + } + #ifndef CONFIG_VM_DYNAMIC_MEMORY ARG_UNUSED(this_vm); return ret; diff --git a/subsys/virtualization/vdev/virtio_blk.c b/subsys/virtualization/vdev/virtio_blk.c index d9297d2eb..a7de9b6fb 100644 --- a/subsys/virtualization/vdev/virtio_blk.c +++ b/subsys/virtualization/vdev/virtio_blk.c @@ -240,7 +240,7 @@ static void virtio_blk_do_io(struct virtio_device *dev, virtio_blk_req_done(vbdev, req, VIRTIO_BLK_S_IOERR); } else { - printk("virtio_blk read: start_sector = %lld, num = %d\n", hdr.sector, num_sectors); + //printk("virtio_blk read: start_sector = %lld, num = %d\n", hdr.sector, num_sectors); virtio_blk_req_done(vbdev, req, VIRTIO_BLK_S_OK); } @@ -264,7 +264,7 @@ static void virtio_blk_do_io(struct virtio_device *dev, virtio_blk_req_done(vbdev, req, VIRTIO_BLK_S_IOERR); } else { - printk("virtio_blk write: start_sector = %lld, num = %d\n", hdr.sector, num_sectors); + //printk("virtio_blk write: start_sector = %lld, num = %d\n", hdr.sector, num_sectors); virtio_blk_req_done(vbdev, req, VIRTIO_BLK_S_OK); } @@ -427,17 +427,17 @@ static int virtio_blk_connect(struct virtio_device *dev, if (rc) { k_free(vbdev); printk("Disk ioctl get sector count failed\n"); - return -EFAULT; + return -EFAULT; } - printk("Disk reports %u sectors\n", cmd_buf); + //printk("Disk reports %u sectors\n", cmd_buf); rc = disk_access_ioctl(vbdev->disk_pdrv, DISK_IOCTL_GET_SECTOR_SIZE, &cmd_buf); if (rc) { k_free(vbdev); printk("Disk ioctl get sector size failed\n"); - return -EFAULT; + return -EFAULT; } - printk("Disk reports sector size %u\n", cmd_buf); + //printk("Disk reports sector size %u\n", cmd_buf); dev->emu_data = vbdev; diff --git a/subsys/virtualization/vm.c b/subsys/virtualization/vm.c index 52e52cf66..0d52b5c00 100644 --- a/subsys/virtualization/vm.c +++ b/subsys/virtualization/vm.c @@ -406,9 +406,7 @@ int vm_delete(struct vm *vm) vdev = CONTAINER_OF(d_node, struct virt_dev, vdev_node); if (vdev->dev_pt_flag) { /* remove vdev from vm. */ - /////ret = delete_vm_monopoly_vdev(vm, vdev); - /* @TODO: May need to record the pass through's count*/ - vdev->dev_pt_flag = false; + vm_virt_dev_remove(vm, vdev); } } @@ -479,7 +477,7 @@ int z_parse_new_vm_args(size_t argc, char **argv, struct getopt_state *state, } /** - * @brief Parse run vm args here. get the vmid that which vm need to process. + * @brief Parse run vm args here. get the vmid that which vm need to process. */ int z_parse_run_vm_args(size_t argc, char **argv, struct getopt_state *state) { @@ -515,37 +513,19 @@ int z_list_vms_info(uint16_t vmid) return 0; } -int vm_sysinfo_init(size_t argc, char **argv, struct vm **vm_ptr, struct getopt_state *state, - struct z_vm_info **vm_info_ptr) +int vm_sysinfo_init(size_t argc, char **argv, struct vm *vm_ptr, struct getopt_state *state, + struct z_vm_info *vm_info_ptr) { int ret = 0; struct vm *vm = NULL; struct z_vm_info *vm_info = NULL; - /* allocate vm struct */ - vm = (struct vm*)k_malloc(sizeof(struct vm)); - if (!vm) { - ZVM_LOG_WARN("Allocation memory for VM Error!\n"); - return -ENOMEM; - } - - /* allocate vm_info struct */ - vm_info = (struct z_vm_info *)k_malloc(sizeof(struct z_vm_info)); - if (!vm_info) { - k_free(vm); - ZVM_LOG_WARN("Allocation memory for VM info Error!\n"); - return -ENOMEM; - } - - ret = z_parse_new_vm_args(argc, argv, state, vm_info, vm); + ret = z_parse_new_vm_args(argc, argv, state, vm_info_ptr, vm_ptr); if (ret) { k_free(vm); k_free(vm_info); return ret; } - *vm_ptr = vm; - *vm_info_ptr = vm_info; - return ret; } diff --git a/subsys/virtualization/vm_dev.c b/subsys/virtualization/vm_dev.c index 8309f9884..6448a2c59 100644 --- a/subsys/virtualization/vm_dev.c +++ b/subsys/virtualization/vm_dev.c @@ -20,6 +20,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(ZVM_MODULE_NAME); @@ -39,6 +40,10 @@ static int vm_vdev_mem_add(struct vm *vm, struct virt_dev *vdev) attrs = MT_VM_DEVICE_MEM | MT_S2_ACCESS_OFF; } + if (vdev->vm_vdev_paddr == LINUX_VMCPY_BASE) { + attrs = MT_VM_NORMAL_MEM; + } + return vm_vdev_mem_create(vm->vmem_domain, vdev->vm_vdev_paddr, vdev->vm_vdev_vaddr, vdev->vm_vdev_size, attrs); @@ -85,6 +90,30 @@ struct virt_dev *vm_virt_dev_add(struct vm *vm, const char *dev_name, bool pt_fl return vm_dev; } +int vm_virt_dev_remove(struct vm *vm, struct virt_dev *vm_dev) +{ + struct zvm_dev_lists* vdev_list; + struct virt_dev *chosen_dev = NULL; + struct _dnode *d_node, *ds_node; + + // vm dev list + sys_dlist_remove(&vm_dev->vdev_node); + + // global dev list + vdev_list = get_zvm_dev_lists(); + SYS_DLIST_FOR_EACH_NODE_SAFE(&vdev_list->dev_used_list, d_node, ds_node) { + chosen_dev = CONTAINER_OF(d_node, struct virt_dev, vdev_node); + if(chosen_dev->vm_vdev_paddr == vm_dev->vm_vdev_paddr) { + sys_dlist_remove(&chosen_dev->vdev_node); + sys_dlist_append(&vdev_list->dev_idle_list, &chosen_dev->vdev_node); + break; + } + } + + k_free(vm_dev); + return 0; +} + #define DEV_DATA(dev) \ ((struct virt_device_data *)(dev)->data) @@ -252,6 +281,7 @@ int vm_device_init(struct vm *vm) break; case OS_TYPE_LINUX: ret = vm_init_bdspecific_device(vm); + vm_virt_dev_add(vm, "linux_vm_cpy", true, false, LINUX_VMCPY_BASE, LINUX_VMCPY_BASE, LINUX_VMCPY_SIZE, VM_DEVICE_INVALID_VIRQ, VM_DEVICE_INVALID_VIRQ); break; default: break; diff --git a/subsys/virtualization/vm_manager.c b/subsys/virtualization/vm_manager.c index c890d6c6c..7c852e6a1 100644 --- a/subsys/virtualization/vm_manager.c +++ b/subsys/virtualization/vm_manager.c @@ -32,7 +32,22 @@ int zvm_new_guest(size_t argc, char **argv) return -ENXIO; } - ret = vm_sysinfo_init(argc, argv, &new_vm, state, &vm_info); + /* allocate vm struct */ + new_vm = (struct vm*)k_malloc(sizeof(struct vm)); + if (!new_vm) { + ZVM_LOG_WARN("Allocation memory for VM Error!\n"); + return -ENOMEM; + } + + /* allocate vm_info struct */ + vm_info = (struct z_vm_info *)k_malloc(sizeof(struct z_vm_info)); + if (!vm_info) { + k_free(new_vm); + ZVM_LOG_WARN("Allocation memory for VM info Error!\n"); + return -ENOMEM; + } + + ret = vm_sysinfo_init(argc, argv, new_vm, state, vm_info); if (ret) { return ret; } @@ -91,7 +106,7 @@ int zvm_new_guest(size_t argc, char **argv) switch (new_vm->os->type) { case OS_TYPE_LINUX: - ZVM_PRINTK("|******\t VMEM SIZE: \t %d(M) \t******| \n", + ZVM_PRINTK("|******\t VMEM SIZE: \t %ld(M) \t******| \n", LINUX_VMSYS_SIZE/(1024*1024)); break; case OS_TYPE_ZEPHYR: diff --git a/subsys/virtualization/vm_mm.c b/subsys/virtualization/vm_mm.c index 9d73ad5da..59fb85ccb 100644 --- a/subsys/virtualization/vm_mm.c +++ b/subsys/virtualization/vm_mm.c @@ -680,7 +680,7 @@ void vm_host_memory_read(uint64_t hpa, void *dst, size_t len) } void vm_host_memory_write(uint64_t hpa, void *src, size_t len) -{ +{ size_t len_actual = len; uint64_t *hva; if (len == 1) { @@ -692,13 +692,13 @@ void vm_host_memory_write(uint64_t hpa, void *src, size_t len) } void vm_guest_memory_read(struct vm *vm, uint64_t gpa, void *dst, size_t len) -{ +{ uint64_t hpa; struct vm_mem_partition *vpart; vpart = (struct vm_mem_partition *)k_malloc(sizeof(struct vm_mem_partition)); if (!vpart) { return; - } + } hpa = vm_gpa_to_hpa(vm, gpa, vpart); if(hpa < 0){ printk("vm_guest_memory_read: gpa to hpa failed!\n"); @@ -714,7 +714,7 @@ void vm_guest_memory_write(struct vm *vm, uint64_t gpa, void *src, size_t len) vpart = (struct vm_mem_partition *)k_malloc(sizeof(struct vm_mem_partition)); if (!vpart) { return; - } + } hpa = vm_gpa_to_hpa(vm, gpa, vpart); if(hpa < 0){ printk("vm_guest_memory_write: gpa to hpa failed!\n"); -- Gitee