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.41.0.windows.1