From 0119389040e4d78c6238875b812827d4f07b5f0f Mon Sep 17 00:00:00 2001 From: gongchangsui Date: Mon, 17 Mar 2025 02:51:16 -0400 Subject: [PATCH] arm: VirtCCA: qemu CoDA support UEFI boot 1. Expose PCIe MMIO region from QEMU memory map. 2. Refactor struct kvm_user_data data_start and data_size represent the address base and size of the MMIO in UEFI boot modedata_start and data_size represent the address base and size of the DTB in direct boot mode. Signed-off-by: gongchangsui --- accel/kvm/kvm-all.c | 8 ++++---- hw/arm/boot.c | 10 ++++++---- hw/arm/virt.c | 6 ++++++ linux-headers/linux/kvm.h | 12 +++++++++--- target/arm/kvm_arm.h | 2 ++ 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 38a48cc031..57c6718b77 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -3527,7 +3527,7 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target) return r; } -int kvm_load_user_data(hwaddr loader_start, hwaddr image_end, hwaddr initrd_start, hwaddr dtb_end, hwaddr ram_size, +int kvm_load_user_data(hwaddr loader_start, hwaddr dtb_info, hwaddr data_start, hwaddr data_size, hwaddr ram_size, struct kvm_numa_info *numa_info) { KVMState *state = kvm_state; @@ -3535,9 +3535,9 @@ int kvm_load_user_data(hwaddr loader_start, hwaddr image_end, hwaddr initrd_star int ret; data.loader_start = loader_start; - data.image_end = image_end; - data.initrd_start = initrd_start; - data.dtb_end = dtb_end; + data.dtb_info = dtb_info; + data.data_start = data_start; + data.data_size = data_size; data.ram_size = ram_size; memcpy(&data.numa_info, numa_info, sizeof(struct kvm_numa_info)); diff --git a/hw/arm/boot.c b/hw/arm/boot.c index ca9f69fd3d..a3e0dbb68c 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -1149,10 +1149,10 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, if (kvm_enabled() && virtcca_cvm_enabled()) { if (info->dtb_limit == 0) { - info->dtb_limit = info->dtb_start + 0x200000; + info->dtb_limit = info->dtb_start + DTB_MAX; } - kvm_load_user_data(info->loader_start, image_high_addr, info->initrd_start, - info->dtb_limit, info->ram_size, (struct kvm_numa_info *)info->numa_info); + kvm_load_user_data(info->loader_start, 0x1, info->dtb_start, + info->dtb_limit - info->dtb_start, info->ram_size, (struct kvm_numa_info *)info->numa_info); tmm_add_ram_region(info->loader_start, image_high_addr - info->loader_start, info->initrd_start, info->dtb_limit - info->initrd_start, true); } @@ -1193,6 +1193,7 @@ static void arm_setup_confidential_firmware_boot(ARMCPU *cpu, static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info, const char *firmware_filename) { + hwaddr mmio_start, mmio_size; /* Set up for booting firmware (which might load a kernel via fw_cfg) */ if (have_dtb(info)) { @@ -1246,7 +1247,8 @@ static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info, con if (info->confidential) { arm_setup_confidential_firmware_boot(cpu, info, firmware_filename); - kvm_load_user_data(UEFI_LOADER_START, UEFI_MAX_SIZE, info->loader_start, info->loader_start + DTB_MAX, info->ram_size, + virtcca_kvm_get_mmio_addr(&mmio_start, &mmio_size); + kvm_load_user_data(info->loader_start, DTB_MAX, mmio_start, mmio_size, info->ram_size, (struct kvm_numa_info *)info->numa_info); } /* diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 39dfec0877..6c5611826c 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -176,6 +176,12 @@ static const MemMapEntry base_memmap[] = { [VIRT_MEM] = { GiB, LEGACY_RAMLIMIT_BYTES }, }; +void virtcca_kvm_get_mmio_addr(hwaddr *mmio_start, hwaddr *mmio_size) +{ + *mmio_start = base_memmap[VIRT_PCIE_MMIO].base; + *mmio_size = base_memmap[VIRT_PCIE_MMIO].size; +} + /* * Highmem IO Regions: This memory map is floating, located after the RAM. * Each MemMapEntry base (GPA) will be dynamically computed, depending on the diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 7a08f9b1e9..c9ec7f862a 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -1510,9 +1510,15 @@ struct kvm_numa_info { struct kvm_user_data { __u64 loader_start; - __u64 image_end; - __u64 initrd_start; - __u64 dtb_end; + /* + * When the lowest bit of dtb_info is 0, the value of dtb_info represents the size of the DTB, + * and data_start and data_size represent the address base and size of the MMIO. + * When the lowest bit of dtb_info is 1, data_start and data_size represent the address base + * and size of the DTB. + */ + __u64 dtb_info; + __u64 data_start; + __u64 data_size; __u64 ram_size; struct kvm_numa_info numa_info; }; diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 31457a57f7..62fbb713f4 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -73,6 +73,8 @@ int kvm_arm_vcpu_finalize(CPUState *cs, int feature); void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group, uint64_t attr, int dev_fd, uint64_t addr_ormask); +void virtcca_kvm_get_mmio_addr(hwaddr *mmio_start, hwaddr *mmio_size); + /** * kvm_arm_init_cpreg_list: * @cpu: ARMCPU -- 2.41.0.windows.1