From e0152021206bfa5d6963bba2337f842a544d54b4 Mon Sep 17 00:00:00 2001 From: Alex Chen Date: Wed, 19 Mar 2025 12:38:44 +0800 Subject: [PATCH] QEMU update to version 8.2.0-30 -arm-VirtCCA-CVM-support-UEFI-boot.patch -arm-VirtCCA-qemu-uefi-boot-support-kae.patch -arm-VirtCCA-Compatibility-with-older-versions-of-TMM.patch -arm-VirtCCA-qemu-CoDA-support-UEFI-boot.patch -BUGFIX-Enforce-isolation-for-virtcca_shared_hugepage.patch -backends-VirtCCA-cvm_gpa_start-supports-both-1GB-and.patch signed-off-by: Alex Chen (cherry picked from commit 9eacd1a6df6861b76663e98133adb15059bf65cc) --- ...solation-for-virtcca_shared_hugepage.patch | 43 ++++ arm-VirtCCA-CVM-support-UEFI-boot.patch | 189 ++++++++++++++++++ ...atibility-with-older-versions-of-TMM.patch | 117 +++++++++++ arm-VirtCCA-qemu-CoDA-support-UEFI-boot.patch | 137 +++++++++++++ arm-VirtCCA-qemu-uefi-boot-support-kae.patch | 100 +++++++++ ...-cvm_gpa_start-supports-both-1GB-and.patch | 113 +++++++++++ qemu.spec | 16 +- 7 files changed, 714 insertions(+), 1 deletion(-) create mode 100644 BUGFIX-Enforce-isolation-for-virtcca_shared_hugepage.patch create mode 100644 arm-VirtCCA-CVM-support-UEFI-boot.patch create mode 100644 arm-VirtCCA-Compatibility-with-older-versions-of-TMM.patch create mode 100644 arm-VirtCCA-qemu-CoDA-support-UEFI-boot.patch create mode 100644 arm-VirtCCA-qemu-uefi-boot-support-kae.patch create mode 100644 backends-VirtCCA-cvm_gpa_start-supports-both-1GB-and.patch diff --git a/BUGFIX-Enforce-isolation-for-virtcca_shared_hugepage.patch b/BUGFIX-Enforce-isolation-for-virtcca_shared_hugepage.patch new file mode 100644 index 00000000..2dc1453d --- /dev/null +++ b/BUGFIX-Enforce-isolation-for-virtcca_shared_hugepage.patch @@ -0,0 +1,43 @@ +From 458d90e226d5833661f9257f6af57c14f9b9bdfe Mon Sep 17 00:00:00 2001 +From: gongchangsui +Date: Mon, 17 Mar 2025 02:52:21 -0400 +Subject: [PATCH] BUGFIX: Enforce isolation for virtcca_shared_hugepage + +Add memory isolation enforcement when virtcca hugepage is disabled. + +Signed-off-by: gongchangsui +--- + hw/core/numa.c | 3 ++- + hw/virtio/vhost.c | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/hw/core/numa.c b/hw/core/numa.c +index e7c48dab61..c691578ef5 100644 +--- a/hw/core/numa.c ++++ b/hw/core/numa.c +@@ -728,7 +728,8 @@ void numa_complete_configuration(MachineState *ms) + memory_region_init(ms->ram, OBJECT(ms), mc->default_ram_id, + ms->ram_size); + numa_init_memdev_container(ms, ms->ram); +- if (virtcca_cvm_enabled() && virtcca_shared_hugepage->ram_block) { ++ if (virtcca_cvm_enabled() && virtcca_shared_hugepage && ++ virtcca_shared_hugepage->ram_block) { + virtcca_shared_memory_configuration(ms); + } + } +diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c +index 8b95558013..4bf0b03977 100644 +--- a/hw/virtio/vhost.c ++++ b/hw/virtio/vhost.c +@@ -1617,7 +1617,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, + hdev->log_size = 0; + hdev->log_enabled = false; + hdev->started = false; +- if (virtcca_cvm_enabled()) { ++ if (virtcca_cvm_enabled() && virtcca_shared_hugepage && virtcca_shared_hugepage->ram_block) { + memory_listener_register(&hdev->memory_listener, + &address_space_virtcca_shared_memory); + } else { +-- +2.45.1.windows.1 + diff --git a/arm-VirtCCA-CVM-support-UEFI-boot.patch b/arm-VirtCCA-CVM-support-UEFI-boot.patch new file mode 100644 index 00000000..44f98bd2 --- /dev/null +++ b/arm-VirtCCA-CVM-support-UEFI-boot.patch @@ -0,0 +1,189 @@ +From 9eacd1a6df6861b76663e98133adb15059bf65cc Mon Sep 17 00:00:00 2001 +From: gongchangsui +Date: Mon, 17 Mar 2025 02:40:50 -0400 +Subject: [PATCH] arm: VirtCCA: CVM support UEFI boot + +1. Add UEFI boot support for Confidential VMs. +2. Modify the base memory address of Confidential VMs from 3GB to 1GB. +3. Disable pflash boot support for Confidential VMs; use the`-bios`option to specify`QEMU_EFI.fd`during launch. + +Signed-off-by: gongchangsui +--- + hw/arm/boot.c | 38 ++++++++++++++++++++++++++++++++++++-- + hw/arm/virt.c | 33 ++++++++++++++++++++++++++++++++- + include/hw/arm/boot.h | 3 +++ + 3 files changed, 71 insertions(+), 3 deletions(-) + +diff --git a/hw/arm/boot.c b/hw/arm/boot.c +index 42110b0f18..6b2f46af4d 100644 +--- a/hw/arm/boot.c ++++ b/hw/arm/boot.c +@@ -43,6 +43,9 @@ + + #define BOOTLOADER_MAX_SIZE (4 * KiB) + ++#define UEFI_MAX_SIZE 0x8000000 ++#define UEFI_LOADER_START 0x0 ++#define DTB_MAX 0x200000 + AddressSpace *arm_boot_address_space(ARMCPU *cpu, + const struct arm_boot_info *info) + { +@@ -1155,7 +1158,31 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, + } + } + +-static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info) ++static void arm_setup_confidential_firmware_boot(ARMCPU *cpu, ++ struct arm_boot_info *info, ++ const char *firmware_filename) ++{ ++ ssize_t fw_size; ++ const char *fname; ++ AddressSpace *as = arm_boot_address_space(cpu, info); ++ ++ fname = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware_filename); ++ if (!fname) { ++ error_report("Could not find firmware image '%s'", firmware_filename); ++ exit(EXIT_FAILURE); ++ } ++ ++ fw_size = load_image_targphys_as(firmware_filename, ++ info->firmware_base, ++ info->firmware_max_size, as); ++ ++ if (fw_size <= 0) { ++ error_report("could not load firmware '%s'", firmware_filename); ++ exit(EXIT_FAILURE); ++ } ++} ++ ++static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info, const char *firmware_filename) + { + /* Set up for booting firmware (which might load a kernel via fw_cfg) */ + +@@ -1166,6 +1193,8 @@ static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info) + * DTB to the base of RAM for the bootloader to pick up. + */ + info->dtb_start = info->loader_start; ++ if (info->confidential) ++ tmm_add_ram_region(UEFI_LOADER_START, UEFI_MAX_SIZE, info->dtb_start, DTB_MAX , true); + } + + if (info->kernel_filename) { +@@ -1206,6 +1235,11 @@ static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info) + } + } + ++ 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, ++ (struct kvm_numa_info *)info->numa_info); ++ } + /* + * We will start from address 0 (typically a boot ROM image) in the + * same way as hardware. Leave env->boot_info NULL, so that +@@ -1282,7 +1316,7 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) + + /* Load the kernel. */ + if (!info->kernel_filename || info->firmware_loaded) { +- arm_setup_firmware_boot(cpu, info); ++ arm_setup_firmware_boot(cpu, info, ms->firmware); + } else { + arm_setup_direct_kernel_boot(cpu, info); + } +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 8823f2ed1c..6ffb26e7e6 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -1398,6 +1398,9 @@ static void virt_flash_map1(PFlashCFI01 *flash, + qdev_prop_set_uint32(dev, "num-blocks", size / VIRT_FLASH_SECTOR_SIZE); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + ++ if (virtcca_cvm_enabled()) { ++ return; ++ } + memory_region_add_subregion(sysmem, base, + sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), + 0)); +@@ -1433,6 +1436,10 @@ static void virt_flash_fdt(VirtMachineState *vms, + MachineState *ms = MACHINE(vms); + char *nodename; + ++ if (virtcca_cvm_enabled()) { ++ return; ++ } ++ + if (sysmem == secure_sysmem) { + /* Report both flash devices as a single node in the DT */ + nodename = g_strdup_printf("/flash@%" PRIx64, flashbase); +@@ -1468,6 +1475,23 @@ static void virt_flash_fdt(VirtMachineState *vms, + } + } + ++static bool virt_confidential_firmware_init(VirtMachineState *vms, ++ MemoryRegion *sysmem) ++{ ++ MemoryRegion *fw_ram; ++ hwaddr fw_base = vms->memmap[VIRT_FLASH].base; ++ hwaddr fw_size = vms->memmap[VIRT_FLASH].size; ++ ++ if (!MACHINE(vms)->firmware) { ++ return false; ++ } ++ ++ fw_ram = g_new(MemoryRegion, 1); ++ memory_region_init_ram(fw_ram, NULL, "fw_ram", fw_size, NULL); ++ memory_region_add_subregion(sysmem, fw_base, fw_ram); ++ return true; ++} ++ + static bool virt_firmware_init(VirtMachineState *vms, + MemoryRegion *sysmem, + MemoryRegion *secure_sysmem) +@@ -1486,6 +1510,10 @@ static bool virt_firmware_init(VirtMachineState *vms, + + pflash_blk0 = pflash_cfi01_get_blk(vms->flash[0]); + ++ if (virtcca_cvm_enabled()) { ++ return virt_confidential_firmware_init(vms, sysmem); ++ } ++ + bios_name = MACHINE(vms)->firmware; + if (bios_name) { + char *fname; +@@ -2023,7 +2051,7 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits) + vms->memmap[VIRT_PCIE_MMIO] = (MemMapEntry) { 0x10000000, 0x2edf0000 }; + vms->memmap[VIRT_KAE_DEVICE] = (MemMapEntry) { 0x3edf0000, 0x00200000 }; + +- vms->memmap[VIRT_MEM].base = 3 * GiB; ++ vms->memmap[VIRT_MEM].base = 1 * GiB; + vms->memmap[VIRT_MEM].size = ms->ram_size; + info_report("[qemu] fix VIRT_MEM range 0x%llx - 0x%llx\n", (unsigned long long)(vms->memmap[VIRT_MEM].base), + (unsigned long long)(vms->memmap[VIRT_MEM].base + ms->ram_size)); +@@ -2822,6 +2850,9 @@ static void machvirt_init(MachineState *machine) + vms->bootinfo.get_dtb = machvirt_dtb; + vms->bootinfo.skip_dtb_autoload = true; + vms->bootinfo.firmware_loaded = firmware_loaded; ++ vms->bootinfo.firmware_base = vms->memmap[VIRT_FLASH].base; ++ vms->bootinfo.firmware_max_size = vms->memmap[VIRT_FLASH].size; ++ vms->bootinfo.confidential = virtcca_cvm_enabled(); + vms->bootinfo.psci_conduit = vms->psci_conduit; + arm_load_kernel(ARM_CPU(first_cpu), machine, &vms->bootinfo); + +diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h +index 4491b1f85b..06ca1d90b2 100644 +--- a/include/hw/arm/boot.h ++++ b/include/hw/arm/boot.h +@@ -133,6 +133,9 @@ struct arm_boot_info { + bool secure_board_setup; + + arm_endianness endianness; ++ hwaddr firmware_base; ++ hwaddr firmware_max_size; ++ bool confidential; + }; + + /** +-- +2.45.1.windows.1 + diff --git a/arm-VirtCCA-Compatibility-with-older-versions-of-TMM.patch b/arm-VirtCCA-Compatibility-with-older-versions-of-TMM.patch new file mode 100644 index 00000000..3324a6cb --- /dev/null +++ b/arm-VirtCCA-Compatibility-with-older-versions-of-TMM.patch @@ -0,0 +1,117 @@ +From 5ed17a43a4cc7fc76397d6d8cad8246063b5b2f3 Mon Sep 17 00:00:00 2001 +From: gongchangsui +Date: Mon, 17 Mar 2025 02:43:55 -0400 +Subject: [PATCH] arm: VirtCCA: Compatibility with older versions of TMM and + the kernel + +Since the base memory address of Confidential VMs in QEMU was changed +from 3GB to 1GB, corresponding adjustments are required in both the TMM +and kernel components. To maintain backward compatibility, the following +modifications were implemented: + 1. **TMM Versioning**: The TMM version number was incremented to +reflect the update + 2. **Kernel Interface**: A new interface was exposed in the kernel +to retrieve the TMM version number. + 3. **QEMU Compatibility Logic**: During initialization, QEMU checks +the TMM version via the kernel interface. If the TMM version is**<2.1**(legacy), +QEMU sets the Confidential VM's base memory address to**3GB**. For TMM versions +**2.1**(updated), the address is configured to**1GB**to align with the new memory layout +This approach ensures seamless backward compatibility while transitioning +to the revised memory addressing scheme. + +Signed-off-by: gongchangsui +--- + accel/kvm/kvm-all.c | 3 +-- + hw/arm/boot.c | 9 +++++++++ + hw/arm/virt.c | 9 +++++++-- + linux-headers/asm-arm64/kvm.h | 2 ++ + linux-headers/linux/kvm.h | 3 +++ + 5 files changed, 22 insertions(+), 4 deletions(-) + +diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c +index a8e29f148e..38a48cc031 100644 +--- a/accel/kvm/kvm-all.c ++++ b/accel/kvm/kvm-all.c +@@ -2390,6 +2390,7 @@ static int kvm_init(MachineState *ms) + qemu_mutex_init(&kml_slots_lock); + + s = KVM_STATE(ms->accelerator); ++ kvm_state = s; + + /* + * On systems where the kernel can support different base page +@@ -2609,8 +2610,6 @@ static int kvm_init(MachineState *ms) + #endif + } + +- kvm_state = s; +- + ret = kvm_arch_init(ms, s); + if (ret < 0) { + goto err; +diff --git a/hw/arm/boot.c b/hw/arm/boot.c +index 6b2f46af4d..ca9f69fd3d 100644 +--- a/hw/arm/boot.c ++++ b/hw/arm/boot.c +@@ -1162,6 +1162,15 @@ static void arm_setup_confidential_firmware_boot(ARMCPU *cpu, + struct arm_boot_info *info, + const char *firmware_filename) + { ++ uint64_t tmi_version = 0; ++ if (kvm_ioctl(kvm_state, KVM_GET_TMI_VERSION, &tmi_version) < 0) { ++ error_report("please check the kernel version!"); ++ exit(EXIT_FAILURE); ++ } ++ if (tmi_version < MIN_TMI_VERSION_FOR_UEFI_BOOTED_CVM) { ++ error_report("please check the tmi version!"); ++ exit(EXIT_FAILURE); ++ } + ssize_t fw_size; + const char *fname; + AddressSpace *as = arm_boot_address_space(cpu, info); +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 6ffb26e7e6..39dfec0877 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -2050,8 +2050,13 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits) + /* support kae vf device tree nodes */ + vms->memmap[VIRT_PCIE_MMIO] = (MemMapEntry) { 0x10000000, 0x2edf0000 }; + vms->memmap[VIRT_KAE_DEVICE] = (MemMapEntry) { 0x3edf0000, 0x00200000 }; +- +- vms->memmap[VIRT_MEM].base = 1 * GiB; ++ uint64_t tmi_version = 0; ++ if (kvm_ioctl(kvm_state, KVM_GET_TMI_VERSION, &tmi_version) < 0) { ++ warn_report("can not get tmi version"); ++ } ++ if (tmi_version < MIN_TMI_VERSION_FOR_UEFI_BOOTED_CVM) { ++ vms->memmap[VIRT_MEM].base = 3 * GiB; ++ } + vms->memmap[VIRT_MEM].size = ms->ram_size; + info_report("[qemu] fix VIRT_MEM range 0x%llx - 0x%llx\n", (unsigned long long)(vms->memmap[VIRT_MEM].base), + (unsigned long long)(vms->memmap[VIRT_MEM].base + ms->ram_size)); +diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h +index 552fdcb18f..d69a71cbec 100644 +--- a/linux-headers/asm-arm64/kvm.h ++++ b/linux-headers/asm-arm64/kvm.h +@@ -597,4 +597,6 @@ struct kvm_cap_arm_tmm_populate_region_args { + + #endif + ++#define MIN_TMI_VERSION_FOR_UEFI_BOOTED_CVM 0x20001 ++ + #endif /* __ARM_KVM_H__ */ +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 84cec64b88..7a08f9b1e9 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -2422,4 +2422,7 @@ struct kvm_s390_zpci_op { + /* flags for kvm_s390_zpci_op->u.reg_aen.flags */ + #define KVM_S390_ZPCIOP_REGAEN_HOST (1 << 0) + ++/* get tmi version */ ++#define KVM_GET_TMI_VERSION _IOR(KVMIO, 0xd2, uint64_t) ++ + #endif /* __LINUX_KVM_H */ +-- +2.45.1.windows.1 + diff --git a/arm-VirtCCA-qemu-CoDA-support-UEFI-boot.patch b/arm-VirtCCA-qemu-CoDA-support-UEFI-boot.patch new file mode 100644 index 00000000..27979797 --- /dev/null +++ b/arm-VirtCCA-qemu-CoDA-support-UEFI-boot.patch @@ -0,0 +1,137 @@ +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.45.1.windows.1 + diff --git a/arm-VirtCCA-qemu-uefi-boot-support-kae.patch b/arm-VirtCCA-qemu-uefi-boot-support-kae.patch new file mode 100644 index 00000000..9d649b45 --- /dev/null +++ b/arm-VirtCCA-qemu-uefi-boot-support-kae.patch @@ -0,0 +1,100 @@ +From 5bffeb311c969a0e05106e4bf54282431c5ba907 Mon Sep 17 00:00:00 2001 +From: gongchangsui +Date: Mon, 17 Mar 2025 02:42:43 -0400 +Subject: [PATCH] arm: VirtCCA: qemu uefi boot support kae + +This commit introduces modifications to enable KAE functionality +during UEFI boot in cVMs. Additionally,the ACPI feature must be +configured in cVM. + +Signed-off-by: gongchangsui +--- + hw/arm/virt-acpi-build.c | 58 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 58 insertions(+) + +diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c +index 076781423b..f78331d69f 100644 +--- a/hw/arm/virt-acpi-build.c ++++ b/hw/arm/virt-acpi-build.c +@@ -58,6 +58,7 @@ + #include "migration/vmstate.h" + #include "hw/acpi/ghes.h" + #include "hw/acpi/viot.h" ++#include "kvm_arm.h" + + #define ARM_SPI_BASE 32 + +@@ -405,6 +406,54 @@ static void acpi_dsdt_add_virtio(Aml *scope, + } + } + ++static void acpi_dsdt_add_hisi_sec(Aml *scope, ++ const MemMapEntry *virtio_mmio_memmap, ++ int dev_id) ++{ ++ hwaddr size = 0x10000; ++ ++ /* ++ * Calculate the base address for the sec device node. ++ * Each device group contains one sec device and one hpre device,spaced by 2 * size. ++ */ ++ hwaddr base = virtio_mmio_memmap->base + dev_id * 2 * size; ++ ++ Aml *dev = aml_device("SE%02u", dev_id); ++ aml_append(dev, aml_name_decl("_HID", aml_string("SEC07"))); ++ aml_append(dev, aml_name_decl("_UID", aml_int(dev_id))); ++ aml_append(dev, aml_name_decl("_CCA", aml_int(1))); ++ ++ Aml *crs = aml_resource_template(); ++ ++ aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE)); ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ aml_append(scope, dev); ++} ++ ++static void acpi_dsdt_add_hisi_hpre(Aml *scope, ++ const MemMapEntry *virtio_mmio_memmap, ++ int dev_id) ++{ ++ hwaddr size = 0x10000; ++ ++ /* ++ * Calculate the base address for the hpre device node. ++ * Each hpre device follows the corresponding sec device by an additional offset of size. ++ */ ++ hwaddr base = virtio_mmio_memmap->base + dev_id * 2 * size + size; ++ ++ Aml *dev = aml_device("HP%02u", dev_id); ++ aml_append(dev, aml_name_decl("_HID", aml_string("HPRE07"))); ++ aml_append(dev, aml_name_decl("_UID", aml_int(dev_id))); ++ aml_append(dev, aml_name_decl("_CCA", aml_int(1))); ++ ++ Aml *crs = aml_resource_template(); ++ ++ aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE)); ++ aml_append(dev, aml_name_decl("_CRS", crs)); ++ aml_append(scope, dev); ++} ++ + static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, + uint32_t irq, VirtMachineState *vms) + { +@@ -1201,6 +1250,15 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) + acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO], + (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS); + acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms); ++ ++ if (virtcca_cvm_enabled()) { ++ int kae_num = tmm_get_kae_num(); ++ for (int i = 0; i < kae_num; i++) { ++ acpi_dsdt_add_hisi_sec(scope, &memmap[VIRT_KAE_DEVICE], i); ++ acpi_dsdt_add_hisi_hpre(scope, &memmap[VIRT_KAE_DEVICE], i); ++ } ++ } ++ + if (vms->acpi_dev) { + build_ged_aml(scope, "\\_SB."GED_DEVICE, + HOTPLUG_HANDLER(vms->acpi_dev), +-- +2.45.1.windows.1 + diff --git a/backends-VirtCCA-cvm_gpa_start-supports-both-1GB-and.patch b/backends-VirtCCA-cvm_gpa_start-supports-both-1GB-and.patch new file mode 100644 index 00000000..22712ac3 --- /dev/null +++ b/backends-VirtCCA-cvm_gpa_start-supports-both-1GB-and.patch @@ -0,0 +1,113 @@ +From bc08940ad3c75da49e05c596f79e9e0164573709 Mon Sep 17 00:00:00 2001 +From: gongchangsui +Date: Mon, 17 Mar 2025 02:56:40 -0400 +Subject: [PATCH] backends: VirtCCA: cvm_gpa_start supports both 1GB and 3GB + +For TMM versions 2.1 and above, `cvm_gpa_start` is 1GB, while for +versions prior to 2.1, `cvm_gpa_start` is 3GB. Shared huge page memory +supports both `cvm_gpa_start` values. + +Signed-off-by: gongchangsui +--- + backends/hostmem-file.c | 17 ++++++++++++++--- + hw/arm/virt.c | 1 + + hw/core/numa.c | 2 +- + include/exec/memory.h | 11 +++++++---- + 4 files changed, 23 insertions(+), 8 deletions(-) + +diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c +index 891fe4ac4a..ce63a372a3 100644 +--- a/backends/hostmem-file.c ++++ b/backends/hostmem-file.c +@@ -27,6 +27,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE) + + bool virtcca_shared_hugepage_mapped = false; + uint64_t virtcca_cvm_ram_size = 0; ++uint64_t virtcca_cvm_gpa_start = 0; + + struct HostMemoryBackendFile { + HostMemoryBackend parent_obj; +@@ -101,8 +102,16 @@ virtcca_shared_backend_memory_alloc(char *mem_path, uint32_t ram_flags, Error ** + error_report("parse virtcca share memory path failed"); + exit(1); + } +- if (virtcca_cvm_ram_size >= VIRTCCA_SHARED_HUGEPAGE_MAX_SIZE) { +- size = VIRTCCA_SHARED_HUGEPAGE_MAX_SIZE; ++ ++ /* ++ * 1) CVM_GPA_START = 3GB --> fix size = 1GB ++ * 2) CVM_GPA_START = 1GB && ram_size >= 3GB --> size = 3GB ++ * 3) CVM_GPA_START = 1GB && ram_size < 3GB --> size = ram_size ++ */ ++ if (virtcca_cvm_gpa_start != DEFAULT_VM_GPA_START) { ++ size = VIRTCCA_SHARED_HUGEPAGE_ADDR_LIMIT - virtcca_cvm_gpa_start; ++ } else if (virtcca_cvm_ram_size >= VIRTCCA_SHARED_HUGEPAGE_ADDR_LIMIT - DEFAULT_VM_GPA_START) { ++ size = VIRTCCA_SHARED_HUGEPAGE_ADDR_LIMIT - DEFAULT_VM_GPA_START; + } + + virtcca_shared_hugepage = g_new(MemoryRegion, 1); +@@ -172,7 +181,9 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) + fb->mem_path, fb->offset, errp); + g_free(name); + +- if (virtcca_cvm_enabled() && backend->share && !virtcca_shared_hugepage_mapped) { ++ if (virtcca_cvm_enabled() && backend->share && ++ (strcmp(fb->mem_path, "/dev/shm") != 0) && ++ !virtcca_shared_hugepage_mapped) { + virtcca_shared_backend_memory_alloc(fb->mem_path, ram_flags, errp); + } + #endif +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 6c5611826c..3c31d3667e 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -2063,6 +2063,7 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits) + if (tmi_version < MIN_TMI_VERSION_FOR_UEFI_BOOTED_CVM) { + vms->memmap[VIRT_MEM].base = 3 * GiB; + } ++ virtcca_cvm_gpa_start = vms->memmap[VIRT_MEM].base; + vms->memmap[VIRT_MEM].size = ms->ram_size; + info_report("[qemu] fix VIRT_MEM range 0x%llx - 0x%llx\n", (unsigned long long)(vms->memmap[VIRT_MEM].base), + (unsigned long long)(vms->memmap[VIRT_MEM].base + ms->ram_size)); +diff --git a/hw/core/numa.c b/hw/core/numa.c +index c691578ef5..98d896e687 100644 +--- a/hw/core/numa.c ++++ b/hw/core/numa.c +@@ -655,7 +655,7 @@ static void virtcca_shared_memory_configuration(MachineState *ms) + memory_region_init_alias(alias_mr, NULL, "alias-mr", virtcca_shared_hugepage, + 0, int128_get64(virtcca_shared_hugepage->size)); + memory_region_add_subregion(address_space_virtcca_shared_memory.root, +- VIRTCCA_GPA_START, alias_mr); ++ virtcca_cvm_gpa_start, alias_mr); + } + + void numa_complete_configuration(MachineState *ms) +diff --git a/include/exec/memory.h b/include/exec/memory.h +index 33778f5c64..c14dc69d27 100644 +--- a/include/exec/memory.h ++++ b/include/exec/memory.h +@@ -243,14 +243,17 @@ typedef struct IOMMUTLBEvent { + /* RAM FD is opened read-only */ + #define RAM_READONLY_FD (1 << 11) + +-/* The GPA range of the VirtCCA bounce buffer is from 1GB to 4GB. */ +-#define VIRTCCA_SHARED_HUGEPAGE_MAX_SIZE 0xc0000000ULL ++/* The address limit of the VirtCCA bounce buffer is 4GB. */ ++#define VIRTCCA_SHARED_HUGEPAGE_ADDR_LIMIT 0x100000000ULL + + /* The VirtCCA shared hugepage memory granularity is 1GB */ + #define VIRTCCA_SHARED_HUGEPAGE_ALIGN 0x40000000ULL + +-/* The GPA starting address of the VirtCCA CVM is 1GB */ +-#define VIRTCCA_GPA_START 0x40000000ULL ++/* The default GPA starting address of VM is 1GB */ ++#define DEFAULT_VM_GPA_START 0x40000000ULL ++ ++/* The GPA starting address of the VirtCCA CVM is 1GB or 3GB */ ++extern uint64_t virtcca_cvm_gpa_start; + + extern uint64_t virtcca_cvm_ram_size; + +-- +2.45.1.windows.1 + diff --git a/qemu.spec b/qemu.spec index c129e8ee..429fb94d 100644 --- a/qemu.spec +++ b/qemu.spec @@ -3,7 +3,7 @@ Name: qemu Version: 8.2.0 -Release: 29 +Release: 30 Epoch: 11 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -622,6 +622,12 @@ Patch0605: target-i386-kvm-Support-to-get-and-enable-extensions.patch Patch0606: target-i386-csv-Request-to-set-private-memory-of-CSV.patch Patch0607: target-i386-csv-Support-load-kernel-hashes-for-CSV3-.patch Patch0608: target-i386-csv-Support-inject-secret-for-CSV3-guest.patch +Patch0609: arm-VirtCCA-CVM-support-UEFI-boot.patch +Patch0610: arm-VirtCCA-qemu-uefi-boot-support-kae.patch +Patch0611: arm-VirtCCA-Compatibility-with-older-versions-of-TMM.patch +Patch0612: arm-VirtCCA-qemu-CoDA-support-UEFI-boot.patch +Patch0613: BUGFIX-Enforce-isolation-for-virtcca_shared_hugepage.patch +Patch0614: backends-VirtCCA-cvm_gpa_start-supports-both-1GB-and.patch BuildRequires: flex BuildRequires: gcc @@ -1220,6 +1226,14 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Wed Mar 19 2025 Alex Chen - 11:8.2.0-30 +- arm-VirtCCA-CVM-support-UEFI-boot.patch +- arm-VirtCCA-qemu-uefi-boot-support-kae.patch +- arm-VirtCCA-Compatibility-with-older-versions-of-TMM.patch +- arm-VirtCCA-qemu-CoDA-support-UEFI-boot.patch +- BUGFIX-Enforce-isolation-for-virtcca_shared_hugepage.patch +- backends-VirtCCA-cvm_gpa_start-supports-both-1GB-and.patch + * Fri Feb 21 2025 Jiabo Feng - 11:8.2.0-29 - target/i386: csv: Support inject secret for CSV3 guest only if the extension is enabled - target/i386: csv: Support load kernel hashes for CSV3 guest only if the extension is enabled -- Gitee