From f2ed4aa86939b8578fd8a60dacb2727dec2cc139 Mon Sep 17 00:00:00 2001 From: Jiabo Feng Date: Sat, 30 Nov 2024 08:43:54 +0800 Subject: [PATCH] QEMU update to version 8.2.0-25: - hw/arm/virt:Keep Guest L1 cache type consistent with KVM - cvm : Add support for TEE-based national encryption acceleration. - Add virtCCA Coda annotation Adjust the position of the security device - target/i386: sev: Add support for reuse ASID for different CSV guests - target/i386: sev: Fix incompatibility between SEV and CSV on the GET_ID API - hw/cxl: Ensure there is enough data for the header in cmd_ccls_set_lsa() - hw/pci: Add parenthesis to PCI_BUILD_BDF macro - hw/audio/hda: free timer on exit - meson.build: Remove ncurses workaround for OpenBSD - ui/console-vc: Silence warning about sprintf() on OpenBSD - ui: remove break after g_assert_not_reached() - s390x/sclp: Simplify get_sclp_device() - hw/vfio/hct: qemu startup terminate once error happened in hct - hw/vfio/hct: fix ccp_index error caused by uninitialized buf - hw/vfio/hct: update support ccp count to 48. - hw/vfio: add device hct based on vfio. Signed-off-by: Jiabo Feng (cherry picked from commit 702a9cc4e262a50f7aa6f7c9549fbc13d4cd0770) --- Add-virtCCA-Coda-annotation.patch | 39 + ...for-TEE-based-national-encryption-ac.patch | 294 ++++++++ ...-Guest-L1-cache-type-consistent-with.patch | 671 ++++++++++++++++++ hw-audio-hda-free-timer-on-exit.patch | 36 + ...ere-is-enough-data-for-the-header-in.patch | 37 + ...d-parenthesis-to-PCI_BUILD_BDF-macro.patch | 52 ++ hw-vfio-add-device-hct-based-on-vfio.patch | 593 ++++++++++++++++ ...ccp_index-error-caused-by-uninitiali.patch | 28 + ...-startup-terminate-once-error-happen.patch | 79 +++ ...o-hct-update-support-ccp-count-to-48.patch | 57 ++ ...emove-ncurses-workaround-for-OpenBSD.patch | 51 ++ qemu.spec | 36 +- s390x-sclp-Simplify-get_sclp_device.patch | 48 ++ ...Add-support-for-reuse-ASID-for-diffe.patch | 177 +++++ ...Fix-incompatibility-between-SEV-and-.patch | 36 + ...lence-warning-about-sprintf-on-OpenB.patch | 52 ++ ...ove-break-after-g_assert_not_reached.patch | 48 ++ 17 files changed, 2333 insertions(+), 1 deletion(-) create mode 100644 Add-virtCCA-Coda-annotation.patch create mode 100644 cvm-Add-support-for-TEE-based-national-encryption-ac.patch create mode 100644 hw-arm-virt-Keep-Guest-L1-cache-type-consistent-with.patch create mode 100644 hw-audio-hda-free-timer-on-exit.patch create mode 100644 hw-cxl-Ensure-there-is-enough-data-for-the-header-in.patch create mode 100644 hw-pci-Add-parenthesis-to-PCI_BUILD_BDF-macro.patch create mode 100644 hw-vfio-add-device-hct-based-on-vfio.patch create mode 100644 hw-vfio-hct-fix-ccp_index-error-caused-by-uninitiali.patch create mode 100644 hw-vfio-hct-qemu-startup-terminate-once-error-happen.patch create mode 100644 hw-vfio-hct-update-support-ccp-count-to-48.patch create mode 100644 meson.build-Remove-ncurses-workaround-for-OpenBSD.patch create mode 100644 s390x-sclp-Simplify-get_sclp_device.patch create mode 100644 target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch create mode 100644 target-i386-sev-Fix-incompatibility-between-SEV-and-.patch create mode 100644 ui-console-vc-Silence-warning-about-sprintf-on-OpenB.patch create mode 100644 ui-remove-break-after-g_assert_not_reached.patch diff --git a/Add-virtCCA-Coda-annotation.patch b/Add-virtCCA-Coda-annotation.patch new file mode 100644 index 0000000..607c81d --- /dev/null +++ b/Add-virtCCA-Coda-annotation.patch @@ -0,0 +1,39 @@ +From 0cf5a4c56d34542bcc2f646446bf54828a51a014 Mon Sep 17 00:00:00 2001 +From: yangxiangkai +Date: Tue, 12 Nov 2024 09:03:51 +0800 +Subject: [PATCH] Add virtCCA Coda annotation Adjust the position of the + security device Signed-off-by: yangxiangkai + +--- + hw/arm/virt.c | 1 + + linux-headers/linux/vfio.h | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index e73a795d3d..a744393f6e 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -162,6 +162,7 @@ static const MemMapEntry base_memmap[] = { + [VIRT_PVTIME] = { 0x090a0000, 0x00010000 }, + [VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 }, + [VIRT_CPUHP_ACPI] = { 0x090c0000, ACPI_CPU_HOTPLUG_REG_LEN}, ++ /* In the virtCCA scenario, this space is used for MSI interrupt mapping */ + [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, + [VIRT_CPUFREQ] = { 0x0b000000, 0x00010000 }, + /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ +diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h +index c27a43d74b..5b1e2871af 100644 +--- a/linux-headers/linux/vfio.h ++++ b/linux-headers/linux/vfio.h +@@ -225,7 +225,7 @@ struct vfio_device_info { + #define VFIO_DEVICE_FLAGS_FSL_MC (1 << 6) /* vfio-fsl-mc device */ + #define VFIO_DEVICE_FLAGS_CAPS (1 << 7) /* Info supports caps */ + #define VFIO_DEVICE_FLAGS_CDX (1 << 8) /* vfio-cdx device */ +-#define VFIO_DEVICE_FLAGS_SECURE (1 << 9) /* secure pci device */ ++#define VFIO_DEVICE_FLAGS_SECURE (1 << 15) /* secure pci device */ + __u32 num_regions; /* Max region index + 1 */ + __u32 num_irqs; /* Max IRQ index + 1 */ + __u32 cap_offset; /* Offset within info struct of first cap */ +-- +2.41.0.windows.1 + diff --git a/cvm-Add-support-for-TEE-based-national-encryption-ac.patch b/cvm-Add-support-for-TEE-based-national-encryption-ac.patch new file mode 100644 index 0000000..2afbccc --- /dev/null +++ b/cvm-Add-support-for-TEE-based-national-encryption-ac.patch @@ -0,0 +1,294 @@ +From dffc0f55d93ececee55a8548d7dab227ee76b234 Mon Sep 17 00:00:00 2001 +From: liupingwei +Date: Thu, 24 Oct 2024 19:05:58 +0800 +Subject: [PATCH] cvm : Add support for TEE-based national encryption + acceleration. + +This commit enables the use of TEE for national encryption acceleration +in cvm and speeds up OpenSSL encrption /decryption operations. + +Signed-off-by: liupingwei +--- + hw/arm/virt.c | 61 ++++++++++++++++++++++++++++++- + include/hw/arm/virt.h | 1 + + linux-headers/asm-arm64/kvm.h | 10 ++++++ + qapi/qom.json | 1 + + target/arm/kvm-tmm.c | 68 +++++++++++++++++++++++++++++++++-- + target/arm/kvm_arm.h | 4 +++ + 6 files changed, 142 insertions(+), 3 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index e73a795d3d..248788db03 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -1967,6 +1967,10 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits) + "kvm-type", &error_abort); + + if (!strcmp(kvm_type, "cvm")) { ++ /* 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 = 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), +@@ -2380,6 +2384,56 @@ out: + return; + } + ++static void fdt_add_hisi_sec_nodes(const VirtMachineState *vms, int dev_id) ++{ ++ const MachineState *ms = MACHINE(vms); ++ 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 = vms->memmap[VIRT_KAE_DEVICE].base + dev_id * 2 * size; ++ char *nodename; ++ ++ tmm_set_sec_addr(base, dev_id); ++ ++ nodename = g_strdup_printf("/hisi-sec@%" PRIx64, base); ++ qemu_fdt_add_subnode(ms->fdt, nodename); ++ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "hisilicon,hip07-sec-vf"); ++ qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); ++ g_free(nodename); ++} ++ ++static void fdt_add_hisi_hpre_nodes(const VirtMachineState *vms, int dev_id) ++{ ++ const MachineState *ms = MACHINE(vms); ++ 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 = vms->memmap[VIRT_KAE_DEVICE].base + dev_id * 2 * size + size; ++ char *nodename; ++ ++ tmm_set_hpre_addr(base, dev_id); ++ ++ nodename = g_strdup_printf("/hisi-hpre@%" PRIx64, base); ++ qemu_fdt_add_subnode(ms->fdt, nodename); ++ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "hisilicon,hip07-hpre-vf"); ++ qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); ++ g_free(nodename); ++} ++ ++static void fdt_add_all_hisi_nodes(const VirtMachineState *vms, int dev_id) ++{ ++ for (int i = 0; i < dev_id; i++) { ++ fdt_add_hisi_sec_nodes(vms, i); ++ fdt_add_hisi_hpre_nodes(vms, i); ++ } ++} ++ + static void machvirt_init(MachineState *machine) + { + VirtMachineState *vms = VIRT_MACHINE(machine); +@@ -2530,14 +2584,19 @@ static void machvirt_init(MachineState *machine) + } + } + ++ create_fdt(vms); ++ + if (virtcca_cvm_enabled()) { ++ int kae_num = tmm_get_kae_num(); ++ fdt_add_all_hisi_nodes(vms, kae_num); ++ + int ret = kvm_arm_tmm_init(machine->cgs, &error_fatal); + if (ret != 0) { + error_report("fail to initialize TMM"); + exit(1); + } + } +- create_fdt(vms); ++ + qemu_log("cpu init start\n"); + + cpu_class = object_class_by_name(machine->cpu_type); +diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h +index 27f5333772..76a0d3fa5b 100644 +--- a/include/hw/arm/virt.h ++++ b/include/hw/arm/virt.h +@@ -66,6 +66,7 @@ enum { + VIRT_FW_CFG, + VIRT_PCIE, + VIRT_PCIE_MMIO, ++ VIRT_KAE_DEVICE, + VIRT_PCIE_PIO, + VIRT_PCIE_ECAM, + VIRT_PLATFORM_BUS, +diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h +index 2b040b5d60..552fdcb18f 100644 +--- a/linux-headers/asm-arm64/kvm.h ++++ b/linux-headers/asm-arm64/kvm.h +@@ -541,6 +541,9 @@ struct reg_mask_range { + #define KVM_CAP_ARM_TMM_CFG_SVE 2 + #define KVM_CAP_ARM_TMM_CFG_DBG 3 + #define KVM_CAP_ARM_TMM_CFG_PMU 4 ++#define KVM_CAP_ARM_TMM_CFG_KAE 5 ++ ++#define KVM_ARM_TMM_MAX_KAE_VF_NUM 11 + + struct kvm_cap_arm_tmm_config_item { + __u32 cfg; +@@ -570,6 +573,13 @@ struct kvm_cap_arm_tmm_config_item { + struct { + __u32 num_pmu_cntrs; + }; ++ ++ /* cfg == KVM_CAP_ARM_TMM_CFG_KAE */ ++ struct { ++ __u32 kae_vf_num; ++ __u64 sec_addr[KVM_ARM_TMM_MAX_KAE_VF_NUM]; ++ __u64 hpre_addr[KVM_ARM_TMM_MAX_KAE_VF_NUM]; ++ }; + /* Fix the size of the union */ + __u8 reserved[256]; + }; +diff --git a/qapi/qom.json b/qapi/qom.json +index 213edd8db2..293d727a04 100644 +--- a/qapi/qom.json ++++ b/qapi/qom.json +@@ -921,6 +921,7 @@ + { 'struct': 'TmmGuestProperties', + 'data': { '*sve-vector-length': 'uint32', + '*num-pmu-counters': 'uint32', ++ '*kae': 'uint32', + '*measurement-algo': 'TmmGuestMeasurementAlgo' } } + + ## +diff --git a/target/arm/kvm-tmm.c b/target/arm/kvm-tmm.c +index efe2ca0006..ea6bcc0f40 100644 +--- a/target/arm/kvm-tmm.c ++++ b/target/arm/kvm-tmm.c +@@ -19,13 +19,20 @@ + #include "sysemu/kvm.h" + #include "sysemu/runstate.h" + #include "hw/loader.h" ++#include "linux-headers/asm-arm64/kvm.h" + + #define TYPE_TMM_GUEST "tmm-guest" + OBJECT_DECLARE_SIMPLE_TYPE(TmmGuest, TMM_GUEST) + + #define TMM_PAGE_SIZE qemu_real_host_page_size() +-#define TMM_MAX_PMU_CTRS 0x20 +-#define TMM_MAX_CFG 5 ++#define TMM_MAX_PMU_CTRS 0x20 ++#define TMM_MAX_CFG 6 ++ ++typedef struct { ++ uint32_t kae_vf_num; ++ hwaddr sec_addr[KVM_ARM_TMM_MAX_KAE_VF_NUM]; ++ hwaddr hpre_addr[KVM_ARM_TMM_MAX_KAE_VF_NUM]; ++} KaeDeviceInfo; + + struct TmmGuest { + ConfidentialGuestSupport parent_obj; +@@ -33,6 +40,7 @@ struct TmmGuest { + TmmGuestMeasurementAlgo measurement_algo; + uint32_t sve_vl; + uint32_t num_pmu_cntrs; ++ KaeDeviceInfo kae_device_info; + }; + + typedef struct { +@@ -92,6 +100,17 @@ static int tmm_configure_one(TmmGuest *guest, uint32_t cfg, Error **errp) + args.num_pmu_cntrs = guest->num_pmu_cntrs; + cfg_str = "PMU"; + break; ++ case KVM_CAP_ARM_TMM_CFG_KAE: ++ if (!guest->kae_device_info.kae_vf_num) { ++ return 0; ++ } ++ args.kae_vf_num= guest->kae_device_info.kae_vf_num; ++ for (int i = 0; i < guest->kae_device_info.kae_vf_num; i++) { ++ args.sec_addr[i] = guest->kae_device_info.sec_addr[i]; ++ args.hpre_addr[i] = guest->kae_device_info.hpre_addr[i]; ++ } ++ cfg_str = "KAE"; ++ break; + default: + g_assert_not_reached(); + } +@@ -289,6 +308,47 @@ static void tmm_set_measurement_algo(Object *obj, int algo, Error **errp G_GNUC_ + guest->measurement_algo = algo; + } + ++static void tmm_get_kae_vf_num(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ TmmGuest *guest = TMM_GUEST(obj); ++ ++ visit_type_uint32(v, name, &guest->kae_device_info.kae_vf_num, errp); ++} ++ ++static void tmm_set_kae_vf_num(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ TmmGuest *guest = TMM_GUEST(obj); ++ uint32_t value; ++ ++ if (!visit_type_uint32(v, name, &value, errp)) { ++ return; ++ } ++ ++ if (value > KVM_ARM_TMM_MAX_KAE_VF_NUM) { ++ error_setg(errp, "invalid number of kae vfs"); ++ return; ++ } ++ ++ guest->kae_device_info.kae_vf_num = value; ++} ++ ++int tmm_get_kae_num(void) ++{ ++ return tmm_guest->kae_device_info.kae_vf_num; ++} ++ ++void tmm_set_sec_addr(hwaddr base, int num) ++{ ++ tmm_guest->kae_device_info.sec_addr[num] = base; ++} ++ ++void tmm_set_hpre_addr(hwaddr base, int num) ++{ ++ tmm_guest->kae_device_info.hpre_addr[num] = base; ++} ++ + static void tmm_guest_class_init(ObjectClass *oc, void *data) + { + object_class_property_add_enum(oc, "measurement-algo", +@@ -314,6 +374,10 @@ static void tmm_guest_class_init(ObjectClass *oc, void *data) + NULL, NULL); + object_class_property_set_description(oc, "num-pmu-counters", + "Number of PMU counters"); ++ object_class_property_add(oc, "kae", "uint32", tmm_get_kae_vf_num, ++ tmm_set_kae_vf_num, NULL, NULL); ++ object_class_property_set_description(oc, "kae", ++ "Number of KAE virtual functions. 0 disables KAE (the default)"); + } + + static void tmm_guest_instance_init(Object *obj) +diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h +index d6c7139f4a..31457a57f7 100644 +--- a/target/arm/kvm_arm.h ++++ b/target/arm/kvm_arm.h +@@ -390,6 +390,10 @@ int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level); + + void tmm_add_ram_region(hwaddr base1, hwaddr len1, hwaddr base2, hwaddr len2, bool populate); + ++int tmm_get_kae_num(void); ++void tmm_set_sec_addr(hwaddr base, int num); ++void tmm_set_hpre_addr(hwaddr base, int num); ++ + int kvm_arm_tmm_init(ConfidentialGuestSupport *cgs, Error **errp); + bool kvm_arm_tmm_enabled(void); + +-- +2.41.0.windows.1 + diff --git a/hw-arm-virt-Keep-Guest-L1-cache-type-consistent-with.patch b/hw-arm-virt-Keep-Guest-L1-cache-type-consistent-with.patch new file mode 100644 index 0000000..592ff9b --- /dev/null +++ b/hw-arm-virt-Keep-Guest-L1-cache-type-consistent-with.patch @@ -0,0 +1,671 @@ +From 6060f8cad07a3d2a49795fef19d585a9d205ecef Mon Sep 17 00:00:00 2001 +From: Jia Qingtong +Date: Tue, 24 Sep 2024 18:24:33 +0800 +Subject: [PATCH] hw/arm/virt:Keep Guest L1 cache type consistent with KVM + +Linux KVM normalize the cache configuration and expose a +fabricated CLIDR_EL1 value to guest, where L1 cache type +could be unified or seperate instruction cache and data +cache. Let's keep guest L1 cache type consistent with +KVM by checking the guest visable CLIDR_EL1, which can +avoid abnormal issue in guest when it's probing cache +info conbined CLIDR_EL1 with ACPI PPTT and DT. + +Signed-off-by: Yanan Wang +Signed-off-by: lishusen +--- + hw/acpi/aml-build.c | 165 ++--------------------------------- + hw/arm/virt-acpi-build.c | 167 ++++++++++++++++++++++++++++++++++++ + hw/arm/virt.c | 86 +++++++++++++++---- + include/hw/acpi/aml-build.h | 54 ++---------- + include/hw/arm/virt.h | 60 +++++++++++++ + 5 files changed, 306 insertions(+), 226 deletions(-) + +diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c +index bf9c59f544..0d4994bafe 100644 +--- a/hw/acpi/aml-build.c ++++ b/hw/acpi/aml-build.c +@@ -47,7 +47,7 @@ static void build_prepend_byte(GArray *array, uint8_t val) + g_array_prepend_val(array, val); + } + +-static void build_append_byte(GArray *array, uint8_t val) ++void build_append_byte(GArray *array, uint8_t val) + { + g_array_append_val(array, val); + } +@@ -1990,10 +1990,10 @@ void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms, + * ACPI spec, Revision 6.3 + * 5.2.29.1 Processor hierarchy node structure (Type 0) + */ +-static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, +- uint32_t parent, uint32_t id, +- uint32_t *priv_rsrc, +- uint32_t priv_num) ++void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, ++ uint32_t parent, uint32_t id, ++ uint32_t *priv_rsrc, ++ uint32_t priv_num) + { + int i; + +@@ -2016,161 +2016,6 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, + } + } + +-/* +- * ACPI spec, Revision 6.3 +- * 5.2.29.2 Cache Type Structure (Type 1) +- */ +-static void build_cache_hierarchy_node(GArray *tbl, uint32_t next_level, +- uint32_t cache_type) +-{ +- build_append_byte(tbl, 1); +- build_append_byte(tbl, 24); +- build_append_int_noprefix(tbl, 0, 2); +- build_append_int_noprefix(tbl, 127, 4); +- build_append_int_noprefix(tbl, next_level, 4); +- +- switch (cache_type) { +- case ARM_L1D_CACHE: /* L1 dcache info */ +- build_append_int_noprefix(tbl, ARM_L1DCACHE_SIZE, 4); +- build_append_int_noprefix(tbl, ARM_L1DCACHE_SETS, 4); +- build_append_byte(tbl, ARM_L1DCACHE_ASSOCIATIVITY); +- build_append_byte(tbl, ARM_L1DCACHE_ATTRIBUTES); +- build_append_int_noprefix(tbl, ARM_L1DCACHE_LINE_SIZE, 2); +- break; +- case ARM_L1I_CACHE: /* L1 icache info */ +- build_append_int_noprefix(tbl, ARM_L1ICACHE_SIZE, 4); +- build_append_int_noprefix(tbl, ARM_L1ICACHE_SETS, 4); +- build_append_byte(tbl, ARM_L1ICACHE_ASSOCIATIVITY); +- build_append_byte(tbl, ARM_L1ICACHE_ATTRIBUTES); +- build_append_int_noprefix(tbl, ARM_L1ICACHE_LINE_SIZE, 2); +- break; +- case ARM_L2_CACHE: /* L2 cache info */ +- build_append_int_noprefix(tbl, ARM_L2CACHE_SIZE, 4); +- build_append_int_noprefix(tbl, ARM_L2CACHE_SETS, 4); +- build_append_byte(tbl, ARM_L2CACHE_ASSOCIATIVITY); +- build_append_byte(tbl, ARM_L2CACHE_ATTRIBUTES); +- build_append_int_noprefix(tbl, ARM_L2CACHE_LINE_SIZE, 2); +- break; +- case ARM_L3_CACHE: /* L3 cache info */ +- build_append_int_noprefix(tbl, ARM_L3CACHE_SIZE, 4); +- build_append_int_noprefix(tbl, ARM_L3CACHE_SETS, 4); +- build_append_byte(tbl, ARM_L3CACHE_ASSOCIATIVITY); +- build_append_byte(tbl, ARM_L3CACHE_ATTRIBUTES); +- build_append_int_noprefix(tbl, ARM_L3CACHE_LINE_SIZE, 2); +- break; +- default: +- build_append_int_noprefix(tbl, 0, 4); +- build_append_int_noprefix(tbl, 0, 4); +- build_append_byte(tbl, 0); +- build_append_byte(tbl, 0); +- build_append_int_noprefix(tbl, 0, 2); +- } +-} +- +-/* +- * ACPI spec, Revision 6.3 +- * 5.2.29 Processor Properties Topology Table (PPTT) +- */ +-void build_pptt_arm(GArray *table_data, BIOSLinker *linker, MachineState *ms, +- const char *oem_id, const char *oem_table_id) +-{ +- MachineClass *mc = MACHINE_GET_CLASS(ms); +- GQueue *list = g_queue_new(); +- guint pptt_start = table_data->len; +- guint parent_offset; +- guint length, i; +- int uid = 0; +- int socket; +- AcpiTable table = { .sig = "PPTT", .rev = 2, +- .oem_id = oem_id, .oem_table_id = oem_table_id }; +- +- acpi_table_begin(&table, table_data); +- +- for (socket = 0; socket < ms->smp.sockets; socket++) { +- uint32_t l3_cache_offset = table_data->len - pptt_start; +- build_cache_hierarchy_node(table_data, 0, ARM_L3_CACHE); +- +- g_queue_push_tail(list, +- GUINT_TO_POINTER(table_data->len - pptt_start)); +- build_processor_hierarchy_node( +- table_data, +- /* +- * Physical package - represents the boundary +- * of a physical package +- */ +- (1 << 0), +- 0, socket, &l3_cache_offset, 1); +- } +- +- if (mc->smp_props.clusters_supported) { +- length = g_queue_get_length(list); +- for (i = 0; i < length; i++) { +- int cluster; +- +- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); +- for (cluster = 0; cluster < ms->smp.clusters; cluster++) { +- g_queue_push_tail(list, +- GUINT_TO_POINTER(table_data->len - pptt_start)); +- build_processor_hierarchy_node( +- table_data, +- (0 << 0), /* not a physical package */ +- parent_offset, cluster, NULL, 0); +- } +- } +- } +- +- length = g_queue_get_length(list); +- for (i = 0; i < length; i++) { +- int core; +- +- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); +- for (core = 0; core < ms->smp.cores; core++) { +- uint32_t priv_rsrc[3] = {}; +- priv_rsrc[0] = table_data->len - pptt_start; /* L2 cache offset */ +- build_cache_hierarchy_node(table_data, 0, ARM_L2_CACHE); +- +- priv_rsrc[1] = table_data->len - pptt_start; /* L1 dcache offset */ +- build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1D_CACHE); +- +- priv_rsrc[2] = table_data->len - pptt_start; /* L1 icache offset */ +- build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1I_CACHE); +- +- if (ms->smp.threads > 1) { +- g_queue_push_tail(list, +- GUINT_TO_POINTER(table_data->len - pptt_start)); +- build_processor_hierarchy_node( +- table_data, +- (0 << 0), /* not a physical package */ +- parent_offset, core, priv_rsrc, 3); +- } else { +- build_processor_hierarchy_node( +- table_data, +- (1 << 1) | /* ACPI Processor ID valid */ +- (1 << 3), /* Node is a Leaf */ +- parent_offset, uid++, priv_rsrc, 3); +- } +- } +- } +- +- length = g_queue_get_length(list); +- for (i = 0; i < length; i++) { +- int thread; +- +- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); +- for (thread = 0; thread < ms->smp.threads; thread++) { +- build_processor_hierarchy_node( +- table_data, +- (1 << 1) | /* ACPI Processor ID valid */ +- (1 << 2) | /* Processor is a Thread */ +- (1 << 3), /* Node is a Leaf */ +- parent_offset, uid++, NULL, 0); +- } +- } +- +- g_queue_free(list); +- acpi_table_end(linker, &table); +-} +- + /* + * ACPI spec, Revision 6.3 + * 5.2.29 Processor Properties Topology Table (PPTT) +diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c +index 179600d4fe..86984b7167 100644 +--- a/hw/arm/virt-acpi-build.c ++++ b/hw/arm/virt-acpi-build.c +@@ -63,6 +63,173 @@ + + #define ACPI_BUILD_TABLE_SIZE 0x20000 + ++/* ++ * ACPI spec, Revision 6.3 ++ * 5.2.29.2 Cache Type Structure (Type 1) ++ */ ++static void build_cache_hierarchy_node(GArray *tbl, uint32_t next_level, ++ uint32_t cache_type) ++{ ++ build_append_byte(tbl, 1); ++ build_append_byte(tbl, 24); ++ build_append_int_noprefix(tbl, 0, 2); ++ build_append_int_noprefix(tbl, 127, 4); ++ build_append_int_noprefix(tbl, next_level, 4); ++ ++ switch (cache_type) { ++ case ARM_L1D_CACHE: /* L1 dcache info */ ++ build_append_int_noprefix(tbl, ARM_L1DCACHE_SIZE, 4); ++ build_append_int_noprefix(tbl, ARM_L1DCACHE_SETS, 4); ++ build_append_byte(tbl, ARM_L1DCACHE_ASSOCIATIVITY); ++ build_append_byte(tbl, ARM_L1DCACHE_ATTRIBUTES); ++ build_append_int_noprefix(tbl, ARM_L1DCACHE_LINE_SIZE, 2); ++ break; ++ case ARM_L1I_CACHE: /* L1 icache info */ ++ build_append_int_noprefix(tbl, ARM_L1ICACHE_SIZE, 4); ++ build_append_int_noprefix(tbl, ARM_L1ICACHE_SETS, 4); ++ build_append_byte(tbl, ARM_L1ICACHE_ASSOCIATIVITY); ++ build_append_byte(tbl, ARM_L1ICACHE_ATTRIBUTES); ++ build_append_int_noprefix(tbl, ARM_L1ICACHE_LINE_SIZE, 2); ++ break; ++ case ARM_L1_CACHE: /* L1 cache info */ ++ build_append_int_noprefix(tbl, ARM_L1CACHE_SIZE, 4); ++ build_append_int_noprefix(tbl, ARM_L1CACHE_SETS, 4); ++ build_append_byte(tbl, ARM_L1CACHE_ASSOCIATIVITY); ++ build_append_byte(tbl, ARM_L1CACHE_ATTRIBUTES); ++ build_append_int_noprefix(tbl, ARM_L1CACHE_LINE_SIZE, 2); ++ break; ++ case ARM_L2_CACHE: /* L2 cache info */ ++ build_append_int_noprefix(tbl, ARM_L2CACHE_SIZE, 4); ++ build_append_int_noprefix(tbl, ARM_L2CACHE_SETS, 4); ++ build_append_byte(tbl, ARM_L2CACHE_ASSOCIATIVITY); ++ build_append_byte(tbl, ARM_L2CACHE_ATTRIBUTES); ++ build_append_int_noprefix(tbl, ARM_L2CACHE_LINE_SIZE, 2); ++ break; ++ case ARM_L3_CACHE: /* L3 cache info */ ++ build_append_int_noprefix(tbl, ARM_L3CACHE_SIZE, 4); ++ build_append_int_noprefix(tbl, ARM_L3CACHE_SETS, 4); ++ build_append_byte(tbl, ARM_L3CACHE_ASSOCIATIVITY); ++ build_append_byte(tbl, ARM_L3CACHE_ATTRIBUTES); ++ build_append_int_noprefix(tbl, ARM_L3CACHE_LINE_SIZE, 2); ++ break; ++ default: ++ build_append_int_noprefix(tbl, 0, 4); ++ build_append_int_noprefix(tbl, 0, 4); ++ build_append_byte(tbl, 0); ++ build_append_byte(tbl, 0); ++ build_append_int_noprefix(tbl, 0, 2); ++ } ++} ++ ++/* ++ * ACPI spec, Revision 6.3 ++ * 5.2.29 Processor Properties Topology Table (PPTT) ++ */ ++static void build_pptt_arm(GArray *table_data, BIOSLinker *linker, MachineState *ms, ++ const char *oem_id, const char *oem_table_id) ++{ ++ MachineClass *mc = MACHINE_GET_CLASS(ms); ++ GQueue *list = g_queue_new(); ++ guint pptt_start = table_data->len; ++ guint parent_offset; ++ guint length, i; ++ int uid = 0; ++ int socket; ++ AcpiTable table = { .sig = "PPTT", .rev = 2, ++ .oem_id = oem_id, .oem_table_id = oem_table_id }; ++ bool unified_l1 = cpu_l1_cache_unified(0); ++ ++ acpi_table_begin(&table, table_data); ++ ++ for (socket = 0; socket < ms->smp.sockets; socket++) { ++ uint32_t l3_cache_offset = table_data->len - pptt_start; ++ build_cache_hierarchy_node(table_data, 0, ARM_L3_CACHE); ++ ++ g_queue_push_tail(list, ++ GUINT_TO_POINTER(table_data->len - pptt_start)); ++ build_processor_hierarchy_node( ++ table_data, ++ /* ++ * Physical package - represents the boundary ++ * of a physical package ++ */ ++ (1 << 0), ++ 0, socket, &l3_cache_offset, 1); ++ } ++ ++ if (mc->smp_props.clusters_supported) { ++ length = g_queue_get_length(list); ++ for (i = 0; i < length; i++) { ++ int cluster; ++ ++ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); ++ for (cluster = 0; cluster < ms->smp.clusters; cluster++) { ++ g_queue_push_tail(list, ++ GUINT_TO_POINTER(table_data->len - pptt_start)); ++ build_processor_hierarchy_node( ++ table_data, ++ (0 << 0), /* not a physical package */ ++ parent_offset, cluster, NULL, 0); ++ } ++ } ++ } ++ ++ length = g_queue_get_length(list); ++ for (i = 0; i < length; i++) { ++ int core; ++ ++ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); ++ for (core = 0; core < ms->smp.cores; core++) { ++ uint32_t priv_rsrc[3] = {}; ++ priv_rsrc[0] = table_data->len - pptt_start; /* L2 cache offset */ ++ build_cache_hierarchy_node(table_data, 0, ARM_L2_CACHE); ++ ++ if (unified_l1) { ++ priv_rsrc[1] = table_data->len - pptt_start; /* L1 cache offset */ ++ build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1_CACHE); ++ } else { ++ priv_rsrc[1] = table_data->len - pptt_start; /* L1 dcache offset */ ++ build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1D_CACHE); ++ priv_rsrc[2] = table_data->len - pptt_start; /* L1 icache offset */ ++ build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1I_CACHE); ++ } ++ ++ if (ms->smp.threads > 1) { ++ g_queue_push_tail(list, ++ GUINT_TO_POINTER(table_data->len - pptt_start)); ++ build_processor_hierarchy_node( ++ table_data, ++ (0 << 0), /* not a physical package */ ++ parent_offset, core, priv_rsrc, 3); ++ } else { ++ build_processor_hierarchy_node( ++ table_data, ++ (1 << 1) | /* ACPI Processor ID valid */ ++ (1 << 3), /* Node is a Leaf */ ++ parent_offset, uid++, priv_rsrc, 3); ++ } ++ } ++ } ++ ++ length = g_queue_get_length(list); ++ for (i = 0; i < length; i++) { ++ int thread; ++ ++ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); ++ for (thread = 0; thread < ms->smp.threads; thread++) { ++ build_processor_hierarchy_node( ++ table_data, ++ (1 << 1) | /* ACPI Processor ID valid */ ++ (1 << 2) | /* Processor is a Thread */ ++ (1 << 3), /* Node is a Leaf */ ++ parent_offset, uid++, NULL, 0); ++ } ++ } ++ ++ g_queue_free(list); ++ acpi_table_end(linker, &table); ++} ++ + static void acpi_dsdt_add_psd(Aml *dev, int cpus) + { + Aml *pkg; +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index e31c289968..a9efcec85e 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -401,6 +401,39 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms) + INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags); + } + ++/* ++ * In CLIDR_EL1 exposed to guest by the hypervisor, L1 cache type ++ * maybe unified or seperate ins and data. We need to read the ++ * guest visable CLIDR_EL1 and check L1 cache type. ++ */ ++bool cpu_l1_cache_unified(int cpu) ++{ ++ bool unified = false; ++ uint64_t clidr; ++ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu)); ++ CPUState *cs = CPU(armcpu); ++ int ret; ++ ++ if (kvm_enabled()) { ++ struct kvm_one_reg reg = { ++ .id = ARM64_REG_CLIDR_EL1, ++ .addr = (uintptr_t)&clidr ++ }; ++ ++ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); ++ if (ret) { ++ error_setg(&error_fatal, "Get vCPU clidr from KVM failed:%d", ret); ++ return unified; ++ } ++ ++ if (CLIDR_CTYPE(clidr, 1) == CTYPE_UNIFIED) { ++ unified = true; ++ } ++ } ++ ++ return unified; ++} ++ + static void fdt_add_l3cache_nodes(const VirtMachineState *vms) + { + int i; +@@ -415,9 +448,10 @@ static void fdt_add_l3cache_nodes(const VirtMachineState *vms) + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cache"); + qemu_fdt_setprop_string(ms->fdt, nodename, "cache-unified", "true"); + qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-level", 3); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", 0x2000000); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", 128); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", 2048); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", ARM_L3CACHE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", ++ ARM_L3CACHE_LINE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", ARM_L3CACHE_SETS); + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", + qemu_fdt_alloc_phandle(ms->fdt)); + g_free(nodename); +@@ -436,10 +470,12 @@ static void fdt_add_l2cache_nodes(const VirtMachineState *vms) + char *nodename = g_strdup_printf("/cpus/l2-cache%d", cpu); + + qemu_fdt_add_subnode(ms->fdt, nodename); ++ qemu_fdt_setprop_string(ms->fdt, nodename, "cache-unified", "true"); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cache"); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", 0x80000); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", 64); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", 1024); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", ARM_L2CACHE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", ++ ARM_L2CACHE_LINE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", ARM_L2CACHE_SETS); + qemu_fdt_setprop_phandle(ms->fdt, nodename, "next-level-cache", + next_path); + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", +@@ -453,18 +489,32 @@ static void fdt_add_l2cache_nodes(const VirtMachineState *vms) + static void fdt_add_l1cache_prop(const VirtMachineState *vms, + char *nodename, int cpu) + { +- const MachineState *ms = MACHINE(vms); +- char *cachename = g_strdup_printf("/cpus/l2-cache%d", cpu); +- +- qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-size", 0x10000); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-line-size", 64); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-sets", 256); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-size", 0x10000); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-line-size", 64); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-sets", 256); +- qemu_fdt_setprop_phandle(ms->fdt, nodename, "next-level-cache", +- cachename); +- g_free(cachename); ++ const MachineState *ms = MACHINE(vms); ++ char *next_path = g_strdup_printf("/cpus/l2-cache%d", cpu); ++ bool unified_l1 = cpu_l1_cache_unified(0); ++ ++ if (unified_l1) { ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", ARM_L1CACHE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", ++ ARM_L1CACHE_LINE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", ARM_L1CACHE_SETS); ++ } else { ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-size", ++ ARM_L1DCACHE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-line-size", ++ ARM_L1DCACHE_LINE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-sets", ++ ARM_L1DCACHE_SETS); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-size", ++ ARM_L1ICACHE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-line-size", ++ ARM_L1ICACHE_LINE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-sets", ++ ARM_L1ICACHE_SETS); ++ } ++ qemu_fdt_setprop_phandle(ms->fdt, nodename, "next-level-cache", next_path); ++ ++ g_free(next_path); + } + + static void fdt_add_cpu_nodes(const VirtMachineState *vms) +diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h +index 7281c281f6..91f9cbf4f1 100644 +--- a/include/hw/acpi/aml-build.h ++++ b/include/hw/acpi/aml-build.h +@@ -221,51 +221,6 @@ struct AcpiBuildTables { + BIOSLinker *linker; + } AcpiBuildTables; + +-/* Definitions of the hardcoded cache info*/ +- +-typedef enum { +- ARM_L1D_CACHE, +- ARM_L1I_CACHE, +- ARM_L2_CACHE, +- ARM_L3_CACHE +-} ArmCacheType; +- +-/* L1 data cache: */ +-#define ARM_L1DCACHE_SIZE 65536 +-#define ARM_L1DCACHE_SETS 256 +-#define ARM_L1DCACHE_ASSOCIATIVITY 4 +-#define ARM_L1DCACHE_ATTRIBUTES 2 +-#define ARM_L1DCACHE_LINE_SIZE 64 +- +-/* L1 instruction cache: */ +-#define ARM_L1ICACHE_SIZE 65536 +-#define ARM_L1ICACHE_SETS 256 +-#define ARM_L1ICACHE_ASSOCIATIVITY 4 +-#define ARM_L1ICACHE_ATTRIBUTES 4 +-#define ARM_L1ICACHE_LINE_SIZE 64 +- +-/* Level 2 unified cache: */ +-#define ARM_L2CACHE_SIZE 524288 +-#define ARM_L2CACHE_SETS 1024 +-#define ARM_L2CACHE_ASSOCIATIVITY 8 +-#define ARM_L2CACHE_ATTRIBUTES 10 +-#define ARM_L2CACHE_LINE_SIZE 64 +- +-/* Level 3 unified cache: */ +-#define ARM_L3CACHE_SIZE 33554432 +-#define ARM_L3CACHE_SETS 2048 +-#define ARM_L3CACHE_ASSOCIATIVITY 15 +-#define ARM_L3CACHE_ATTRIBUTES 10 +-#define ARM_L3CACHE_LINE_SIZE 128 +- +-struct offset_status { +- uint32_t parent; +- uint32_t l2_offset; +- uint32_t l1d_offset; +- uint32_t l1i_offset; +-}; +- +- + typedef + struct CrsRangeEntry { + uint64_t base; +@@ -460,6 +415,7 @@ Aml *aml_sizeof(Aml *arg); + Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target); + Aml *aml_object_type(Aml *object); + ++void build_append_byte(GArray *array, uint8_t val); + void build_append_int_noprefix(GArray *table, uint64_t value, int size); + + typedef struct AcpiTable { +@@ -537,10 +493,12 @@ void build_srat_memory(GArray *table_data, uint64_t base, + void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms, + const char *oem_id, const char *oem_table_id); + +-void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, +- const char *oem_id, const char *oem_table_id); ++void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, ++ uint32_t parent, uint32_t id, ++ uint32_t *priv_rsrc, ++ uint32_t priv_num); + +-void build_pptt_arm(GArray *table_data, BIOSLinker *linker, MachineState *ms, ++void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, + const char *oem_id, const char *oem_table_id); + + void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f, +diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h +index 76a0d3fa5b..4b7dc61c24 100644 +--- a/include/hw/arm/virt.h ++++ b/include/hw/arm/virt.h +@@ -47,6 +47,65 @@ + /* See Linux kernel arch/arm64/include/asm/pvclock-abi.h */ + #define PVTIME_SIZE_PER_CPU 64 + ++/* ARM CLIDR_EL1 related definitions */ ++/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */ ++#define CTYPE_NONE 0b000 ++#define CTYPE_INS 0b001 ++#define CTYPE_DATA 0b010 ++#define CTYPE_INS_DATA 0b011 ++#define CTYPE_UNIFIED 0b100 ++ ++#define ARM64_REG_CLIDR_EL1 ARM64_SYS_REG(3, 1, 0, 0, 1) ++ ++#define CLIDR_CTYPE_SHIFT(level) (3 * (level - 1)) ++#define CLIDR_CTYPE_MASK(level) (7 << CLIDR_CTYPE_SHIFT(level)) ++#define CLIDR_CTYPE(clidr, level) \ ++ (((clidr) & CLIDR_CTYPE_MASK(level)) >> CLIDR_CTYPE_SHIFT(level)) ++ ++/* L1 data cache */ ++#define ARM_L1DCACHE_SIZE 65536 ++#define ARM_L1DCACHE_SETS 256 ++#define ARM_L1DCACHE_ASSOCIATIVITY 4 ++#define ARM_L1DCACHE_ATTRIBUTES 2 ++#define ARM_L1DCACHE_LINE_SIZE 64 ++ ++/* L1 instruction cache */ ++#define ARM_L1ICACHE_SIZE 65536 ++#define ARM_L1ICACHE_SETS 256 ++#define ARM_L1ICACHE_ASSOCIATIVITY 4 ++#define ARM_L1ICACHE_ATTRIBUTES 4 ++#define ARM_L1ICACHE_LINE_SIZE 64 ++ ++/* L1 unified cache */ ++#define ARM_L1CACHE_SIZE 131072 ++#define ARM_L1CACHE_SETS 256 ++#define ARM_L1CACHE_ASSOCIATIVITY 4 ++#define ARM_L1CACHE_ATTRIBUTES 10 ++#define ARM_L1CACHE_LINE_SIZE 128 ++ ++/* L2 unified cache */ ++#define ARM_L2CACHE_SIZE 524288 ++#define ARM_L2CACHE_SETS 1024 ++#define ARM_L2CACHE_ASSOCIATIVITY 8 ++#define ARM_L2CACHE_ATTRIBUTES 10 ++#define ARM_L2CACHE_LINE_SIZE 64 ++ ++/* L3 unified cache */ ++#define ARM_L3CACHE_SIZE 33554432 ++#define ARM_L3CACHE_SETS 2048 ++#define ARM_L3CACHE_ASSOCIATIVITY 15 ++#define ARM_L3CACHE_ATTRIBUTES 10 ++#define ARM_L3CACHE_LINE_SIZE 128 ++ ++/* Definitions of the hardcoded cache info */ ++typedef enum { ++ ARM_L1D_CACHE, ++ ARM_L1I_CACHE, ++ ARM_L1_CACHE, ++ ARM_L2_CACHE, ++ ARM_L3_CACHE ++} ArmCacheType; ++ + enum { + VIRT_FLASH, + VIRT_MEM, +@@ -194,6 +253,7 @@ OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE) + + void virt_acpi_setup(VirtMachineState *vms); + bool virt_is_acpi_enabled(VirtMachineState *vms); ++bool cpu_l1_cache_unified(int cpu); + + /* Return number of redistributors that fit in the specified region */ + static uint32_t virt_redist_capacity(VirtMachineState *vms, int region) +-- +2.41.0.windows.1 + diff --git a/hw-audio-hda-free-timer-on-exit.patch b/hw-audio-hda-free-timer-on-exit.patch new file mode 100644 index 0000000..e08e69c --- /dev/null +++ b/hw-audio-hda-free-timer-on-exit.patch @@ -0,0 +1,36 @@ +From 28bf94c86d3914b8b517dae483d1d69b3afabacc Mon Sep 17 00:00:00 2001 +From: qihao_yewu +Date: Tue, 5 Nov 2024 07:03:48 -0500 +Subject: [PATCH] hw/audio/hda: free timer on exit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from f27206ceedbe2efae37c8d143c5eb2db05251508 + +Fixes: 280c1e1cd ("audio/hda: create millisecond timers that handle IO") + +Signed-off-by: Marc-André Lureau +Reviewed-by: Akihiko Odaki +Message-ID: <20241008125028.1177932-2-marcandre.lureau@redhat.com> +Signed-off-by: qihao_yewu +--- + hw/audio/hda-codec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c +index 0bc20d49f6..19f401cabe 100644 +--- a/hw/audio/hda-codec.c ++++ b/hw/audio/hda-codec.c +@@ -751,7 +751,7 @@ static void hda_audio_exit(HDACodecDevice *hda) + continue; + } + if (a->use_timer) { +- timer_del(st->buft); ++ timer_free(st->buft); + } + if (st->output) { + AUD_close_out(&a->card, st->voice.out); +-- +2.41.0.windows.1 + diff --git a/hw-cxl-Ensure-there-is-enough-data-for-the-header-in.patch b/hw-cxl-Ensure-there-is-enough-data-for-the-header-in.patch new file mode 100644 index 0000000..0a7e3a2 --- /dev/null +++ b/hw-cxl-Ensure-there-is-enough-data-for-the-header-in.patch @@ -0,0 +1,37 @@ +From 830009038a73e496598c26679b7e30d7e931a1cf Mon Sep 17 00:00:00 2001 +From: Jonathan Cameron +Date: Fri, 1 Nov 2024 13:39:16 +0000 +Subject: [PATCH] hw/cxl: Ensure there is enough data for the header in + cmd_ccls_set_lsa() + +The properties of the requested set command cannot be established if +len_in is less than the size of the header. + +Reported-by: Esifiel +Signed-off-by: Jonathan Cameron +Message-Id: <20241101133917.27634-10-Jonathan.Cameron@huawei.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Zhongrui Tang +--- + hw/cxl/cxl-mailbox-utils.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c +index 6eff56fb1b..9f2304389b 100644 +--- a/hw/cxl/cxl-mailbox-utils.c ++++ b/hw/cxl/cxl-mailbox-utils.c +@@ -897,8 +897,8 @@ static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd, + const size_t hdr_len = offsetof(struct set_lsa_pl, data); + + *len_out = 0; +- if (!len_in) { +- return CXL_MBOX_SUCCESS; ++ if (len_in < hdr_len) { ++ return CXL_MBOX_INVALID_PAYLOAD_LENGTH; + } + + if (set_lsa_payload->offset + len_in > cvc->get_lsa_size(ct3d) + hdr_len) { +-- +2.41.0.windows.1 + diff --git a/hw-pci-Add-parenthesis-to-PCI_BUILD_BDF-macro.patch b/hw-pci-Add-parenthesis-to-PCI_BUILD_BDF-macro.patch new file mode 100644 index 0000000..19bbcf6 --- /dev/null +++ b/hw-pci-Add-parenthesis-to-PCI_BUILD_BDF-macro.patch @@ -0,0 +1,52 @@ +From 3c108b874b8b142a42939d785d6706a44e7035d7 Mon Sep 17 00:00:00 2001 +From: Roque Arcudia Hernandez +Date: Fri, 1 Nov 2024 21:59:23 +0000 +Subject: [PATCH] hw/pci: Add parenthesis to PCI_BUILD_BDF macro +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The bus parameter in the macro PCI_BUILD_BDF is not surrounded by +parenthesis. This can create a compile error when warnings are +treated as errors or can potentially create runtime errors due to the +operator precedence. + +For instance: + + file.c:x:32: error: suggest parentheses around '-' inside '<<' + [-Werror=parentheses] + 171 | uint16_t bdf = PCI_BUILD_BDF(a - b, sdev->devfn); + | ~~^~~ + include/hw/pci/pci.h:19:41: note: in definition of macro + 'PCI_BUILD_BDF' + 19 | #define PCI_BUILD_BDF(bus, devfn) ((bus << 8) | (devfn)) + | ^~~ + cc1: all warnings being treated as errors + +Signed-off-by: Roque Arcudia Hernandez +Reviewed-by: Nabih Estefan +Message-Id: <20241101215923.3399311-1-roqueh@google.com> +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Zhongrui Tang +--- + include/hw/pci/pci.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h +index fa6313aabc..7cf7b5619a 100644 +--- a/include/hw/pci/pci.h ++++ b/include/hw/pci/pci.h +@@ -15,7 +15,7 @@ extern bool pci_available; + #define PCI_BUS_NUM(x) (((x) >> 8) & 0xff) + #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) + #define PCI_FUNC(devfn) ((devfn) & 0x07) +-#define PCI_BUILD_BDF(bus, devfn) ((bus << 8) | (devfn)) ++#define PCI_BUILD_BDF(bus, devfn) (((bus) << 8) | (devfn)) + #define PCI_BDF_TO_DEVFN(x) ((x) & 0xff) + #define PCI_BUS_MAX 256 + #define PCI_DEVFN_MAX 256 +-- +2.41.0.windows.1 + diff --git a/hw-vfio-add-device-hct-based-on-vfio.patch b/hw-vfio-add-device-hct-based-on-vfio.patch new file mode 100644 index 0000000..bd0c9cf --- /dev/null +++ b/hw-vfio-add-device-hct-based-on-vfio.patch @@ -0,0 +1,593 @@ +From ebafa8d737b5f08e787803375d6e942ecdaef1a9 Mon Sep 17 00:00:00 2001 +From: Yabin Li +Date: Fri, 4 Aug 2023 21:09:08 +0800 +Subject: [PATCH] hw/vfio: add device hct based on vfio. + +add hct device based on vfio, used to simulate ccp devices + +Signed-off-by: Yabin Li +Signed-off-by: yangdepei +--- + hw/vfio/Kconfig | 6 + + hw/vfio/hct.c | 543 ++++++++++++++++++++++++++++++++++++++++++++ + hw/vfio/meson.build | 1 + + 3 files changed, 550 insertions(+) + create mode 100644 hw/vfio/hct.c + +diff --git a/hw/vfio/Kconfig b/hw/vfio/Kconfig +index 7cdba0560a..5f0d3c2d2b 100644 +--- a/hw/vfio/Kconfig ++++ b/hw/vfio/Kconfig +@@ -41,3 +41,9 @@ config VFIO_IGD + bool + default y if PC_PCI + depends on VFIO_PCI ++ ++config VFIO_HCT ++ bool ++ default y ++ select VFIO ++ depends on LINUX && PCI +diff --git a/hw/vfio/hct.c b/hw/vfio/hct.c +new file mode 100644 +index 0000000000..476e86c61d +--- /dev/null ++++ b/hw/vfio/hct.c +@@ -0,0 +1,543 @@ ++/* ++ * vfio based mediated ccp(hct) assignment support ++ * ++ * Copyright 2023 HYGON Corp. ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or (at ++ * your option) any later version. See the COPYING file in the top-level ++ * directory. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "qemu/osdep.h" ++#include "qemu/queue.h" ++#include "qemu/main-loop.h" ++#include "qemu/log.h" ++#include "trace.h" ++#include "hw/pci/pci.h" ++#include "hw/vfio/pci.h" ++#include "qemu/range.h" ++#include "sysemu/kvm.h" ++#include "hw/pci/msi.h" ++#include "qemu/error-report.h" ++#include "qapi/error.h" ++#include "hw/qdev-properties.h" ++ ++#define MAX_CCP_CNT 16 ++#define PAGE_SIZE 4096 ++#define HCT_SHARED_MEMORY_SIZE (PAGE_SIZE * MAX_CCP_CNT) ++#define CCP_INDEX_BYTES 4 ++#define PATH_MAX 4096 ++#define TYPE_HCT_DEV "hct" ++#define PCI_HCT_DEV(obj) OBJECT_CHECK(HCTDevState, (obj), TYPE_HCT_DEV) ++#define HCT_MMIO_SIZE (1 << 20) ++#define HCT_MAX_PASID (1 << 8) ++ ++#define PCI_VENDOR_ID_HYGON_CCP 0x1d94 ++#define PCI_DEVICE_ID_HYGON_CCP 0x1468 ++ ++#define HCT_SHARE_DEV "/dev/hct_share" ++ ++#define HCT_VERSION_STRING "0.2" ++#define DEF_VERSION_STRING "0.1" ++#define VERSION_SIZE 16 ++ ++#define HCT_SHARE_IOC_TYPE 'C' ++#define HCT_SHARE_OP_TYPE 0x01 ++#define HCT_SHARE_OP _IOWR(HCT_SHARE_IOC_TYPE, \ ++ HCT_SHARE_OP_TYPE, \ ++ struct hct_dev_ctrl) ++#define HCT_SHARE_OP_DMA_MAP 0x01 ++#define HCT_SHARE_OP_GET_ID 0x03 ++#define HCT_SHARE_OP_GET_PASID 0x04 ++#define HCT_SHARE_OP_DMA_UNMAP 0x05 ++#define HCT_SHARE_OP_GET_VERSION 0x06 ++ ++/* BARS */ ++#define HCT_REG_BAR_IDX 2 ++#define HCT_SHARED_BAR_IDX 3 ++#define HCT_PASID_BAR_IDX 4 ++ ++#define PASID_OFFSET 40 ++ ++static volatile struct hct_data { ++ int init; ++ int hct_fd; ++ unsigned long pasid; ++ uint8_t *pasid_memory; ++ uint8_t *hct_shared_memory; ++ uint8_t ccp_index[MAX_CCP_CNT]; ++ uint8_t ccp_cnt; ++} hct_data; ++ ++typedef struct SharedDevice { ++ PCIDevice dev; ++ int shared_memory_offset; ++} SharedDevice; ++ ++typedef struct HctDevState { ++ SharedDevice sdev; ++ VFIODevice vdev; ++ MemoryRegion mmio; ++ MemoryRegion shared; ++ MemoryRegion pasid; ++ void *maps[PCI_NUM_REGIONS]; ++} HCTDevState; ++ ++struct hct_dev_ctrl { ++ unsigned char op; ++ unsigned char rsvd[3]; ++ union { ++ unsigned char version[VERSION_SIZE]; ++ struct { ++ unsigned long vaddr; ++ unsigned long iova; ++ unsigned long size; ++ }; ++ unsigned int id; ++ }; ++}; ++ ++static int pasid_get_and_init(HCTDevState *state) ++{ ++ struct hct_dev_ctrl ctrl; ++ int ret; ++ ++ ctrl.op = HCT_SHARE_OP_GET_PASID; ++ ctrl.id = -1; ++ ret = ioctl(hct_data.hct_fd, HCT_SHARE_OP, &ctrl); ++ if (ret < 0) { ++ ret = -errno; ++ error_report("GET_PASID fail: %d", -errno); ++ goto out; ++ } ++ ++ *hct_data.pasid_memory = ctrl.id; ++ hct_data.pasid = ctrl.id; ++ ++out: ++ return ret; ++} ++ ++static const MemoryRegionOps hct_mmio_ops = { ++ .endianness = DEVICE_NATIVE_ENDIAN, ++ .valid = ++ { ++ .min_access_size = 4, ++ .max_access_size = 4, ++ }, ++}; ++ ++static void vfio_hct_detach_device(HCTDevState *state) ++{ ++ vfio_detach_device(&state->vdev); ++ g_free(state->vdev.name); ++} ++ ++static void vfio_hct_exit(PCIDevice *dev) ++{ ++ HCTDevState *state = PCI_HCT_DEV(dev); ++ ++ vfio_hct_detach_device(state); ++ ++ if (hct_data.hct_fd) { ++ qemu_close(hct_data.hct_fd); ++ hct_data.hct_fd = 0; ++ } ++} ++ ++static Property vfio_hct_properties[] = { ++ DEFINE_PROP_STRING("sysfsdev", HCTDevState, vdev.sysfsdev), ++ DEFINE_PROP_END_OF_LIST(), ++}; ++ ++static void vfio_ccp_compute_needs_reset(VFIODevice *vdev) ++{ ++ vdev->needs_reset = false; ++} ++ ++struct VFIODeviceOps vfio_ccp_ops = { ++ .vfio_compute_needs_reset = vfio_ccp_compute_needs_reset, ++}; ++ ++/* create BAR2, BAR3 and BAR4 space for the virtual machine. */ ++static int vfio_hct_region_mmap(HCTDevState *state) ++{ ++ int ret; ++ int i; ++ struct vfio_region_info *info; ++ ++ for (i = 0; i < PCI_ROM_SLOT; i++) { ++ ret = vfio_get_region_info(&state->vdev, i, &info); ++ if (ret) ++ goto out; ++ ++ if (info->size) { ++ state->maps[i] = mmap(NULL, info->size, PROT_READ | PROT_WRITE, ++ MAP_SHARED, state->vdev.fd, info->offset); ++ if (state->maps[i] == MAP_FAILED) { ++ ret = -errno; ++ g_free(info); ++ error_report("vfio mmap fail\n"); ++ goto out; ++ } ++ } ++ g_free(info); ++ } ++ ++ memory_region_init_io(&state->mmio, OBJECT(state), &hct_mmio_ops, state, ++ "hct mmio", HCT_MMIO_SIZE); ++ memory_region_init_ram_device_ptr(&state->mmio, OBJECT(state), "hct mmio", ++ HCT_MMIO_SIZE, ++ state->maps[HCT_REG_BAR_IDX]); ++ ++ memory_region_init_io(&state->shared, OBJECT(state), &hct_mmio_ops, state, ++ "hct shared memory", PAGE_SIZE); ++ memory_region_init_ram_device_ptr( ++ &state->shared, OBJECT(state), "hct shared memory", PAGE_SIZE, ++ (void *)hct_data.hct_shared_memory + ++ state->sdev.shared_memory_offset * PAGE_SIZE); ++ ++ memory_region_init_io(&state->pasid, OBJECT(state), &hct_mmio_ops, state, ++ "hct pasid", PAGE_SIZE); ++ memory_region_init_ram_device_ptr(&state->pasid, OBJECT(state), "hct pasid", ++ PAGE_SIZE, hct_data.pasid_memory); ++ ++ pci_register_bar(&state->sdev.dev, HCT_REG_BAR_IDX, ++ PCI_BASE_ADDRESS_SPACE_MEMORY, &state->mmio); ++ pci_register_bar(&state->sdev.dev, HCT_SHARED_BAR_IDX, ++ PCI_BASE_ADDRESS_SPACE_MEMORY, &state->shared); ++ pci_register_bar(&state->sdev.dev, HCT_PASID_BAR_IDX, ++ PCI_BASE_ADDRESS_SPACE_MEMORY, &state->pasid); ++out: ++ return ret; ++} ++ ++static int hct_check_duplicated_index(int index) ++{ ++ int cnt; ++ for (cnt = 0; cnt < hct_data.ccp_cnt; cnt++) { ++ if (hct_data.ccp_index[cnt] == index) { ++ error_report("many mdev shouldn't be mapped to one ccp in a " ++ "virtual machine!\n"); ++ return -1; ++ } ++ } ++ ++ hct_data.ccp_index[hct_data.ccp_cnt++] = index; ++ return 0; ++} ++ ++static int hct_get_ccp_index(HCTDevState *state) ++{ ++ char path[PATH_MAX]; ++ char buf[CCP_INDEX_BYTES]; ++ int fd; ++ int ret; ++ int ccp_index; ++ ++ snprintf(path, PATH_MAX, "%s/vendor/id", state->vdev.sysfsdev); ++ fd = qemu_open_old(path, O_RDONLY); ++ if (fd < 0) { ++ error_report("open %s fail\n", path); ++ return -errno; ++ } ++ ++ ret = read(fd, buf, sizeof(buf)); ++ if (ret < 0) { ++ ret = -errno; ++ error_report("read %s fail\n", path); ++ goto out; ++ } ++ ++ if (1 != sscanf(buf, "%d", &ccp_index)) { ++ ret = -errno; ++ error_report("format addr %s fail\n", buf); ++ goto out; ++ } ++ ++ if (!hct_check_duplicated_index(ccp_index)) { ++ state->sdev.shared_memory_offset = ccp_index; ++ } else { ++ ret = -1; ++ } ++ ++out: ++ qemu_close(fd); ++ return ret; ++} ++ ++static int hct_api_version_check(void) ++{ ++ struct hct_dev_ctrl ctrl; ++ int ret; ++ ++ ctrl.op = HCT_SHARE_OP_GET_VERSION; ++ memcpy(ctrl.version, DEF_VERSION_STRING, sizeof(DEF_VERSION_STRING)); ++ ret = ioctl(hct_data.hct_fd, HCT_SHARE_OP, &ctrl); ++ if (ret < 0) { ++ error_report("ret %d, errno %d: fail to get hct.ko version, please " ++ "update hct.ko to version 0.2.\n", ++ ret, errno); ++ return -1; ++ } else if (memcmp(ctrl.version, HCT_VERSION_STRING, ++ sizeof(HCT_VERSION_STRING)) < 0) { ++ error_report("The API version %s is larger than hct.ko version %s, " ++ "please update hct.ko to version 0.2\n", ++ HCT_VERSION_STRING, ctrl.version); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int hct_shared_memory_init(void) ++{ ++ int ret = 0; ++ ++ hct_data.hct_shared_memory = ++ mmap(NULL, HCT_SHARED_MEMORY_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, ++ hct_data.hct_fd, 0); ++ if (hct_data.hct_shared_memory == MAP_FAILED) { ++ ret = -errno; ++ error_report("map hct shared memory fail\n"); ++ goto out; ++ } ++ ++out: ++ return ret; ++} ++ ++static void hct_listener_region_add(MemoryListener *listener, ++ MemoryRegionSection *section) ++{ ++ struct hct_dev_ctrl ctrl; ++ hwaddr iova; ++ Int128 llend, llsize; ++ void *vaddr; ++ int ret; ++ ++ iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); ++ llend = int128_make64(section->offset_within_address_space); ++ llend = int128_add(llend, section->size); ++ llend = int128_add(llend, int128_exts64(qemu_real_host_page_mask())); ++ ++ if (int128_ge(int128_make64(iova), llend)) { ++ return; ++ } ++ ++ if (!section->mr->ram) { ++ return; ++ } ++ ++ vaddr = memory_region_get_ram_ptr(section->mr) + ++ section->offset_within_region + ++ (iova - section->offset_within_address_space); ++ llsize = int128_sub(llend, int128_make64(iova)); ++ ++ ctrl.op = HCT_SHARE_OP_DMA_MAP; ++ ctrl.iova = iova | (hct_data.pasid << PASID_OFFSET); ++ ctrl.vaddr = (uint64_t)vaddr; ++ ctrl.size = llsize; ++ ret = ioctl(hct_data.hct_fd, HCT_SHARE_OP, &ctrl); ++ if (ret < 0) ++ error_report("VFIO_MAP_DMA: %d, iova=%lx", -errno, iova); ++} ++ ++static void hct_listener_region_del(MemoryListener *listener, ++ MemoryRegionSection *section) ++{ ++ struct hct_dev_ctrl ctrl; ++ hwaddr iova; ++ Int128 llend, llsize; ++ int ret; ++ ++ iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); ++ llend = int128_make64(section->offset_within_address_space); ++ llend = int128_add(llend, section->size); ++ llend = int128_add(llend, int128_exts64(qemu_real_host_page_mask())); ++ ++ if (int128_ge(int128_make64(iova), llend)) { ++ return; ++ } ++ ++ if (!section->mr->ram) { ++ return; ++ } ++ ++ llsize = int128_sub(llend, int128_make64(iova)); ++ ++ ctrl.op = HCT_SHARE_OP_DMA_UNMAP; ++ ctrl.iova = iova | (hct_data.pasid << PASID_OFFSET); ++ ctrl.size = llsize; ++ ret = ioctl(hct_data.hct_fd, HCT_SHARE_OP, &ctrl); ++ if (ret < 0) ++ error_report("VFIO_UNMAP_DMA: %d", -errno); ++} ++ ++static MemoryListener hct_memory_listener = { ++ .region_add = hct_listener_region_add, ++ .region_del = hct_listener_region_del, ++}; ++ ++static void hct_data_uninit(HCTDevState *state) ++{ ++ if (hct_data.hct_fd) { ++ qemu_close(hct_data.hct_fd); ++ hct_data.hct_fd = 0; ++ } ++ ++ if (hct_data.pasid) { ++ hct_data.pasid = 0; ++ } ++ ++ if (hct_data.pasid_memory) { ++ munmap(hct_data.pasid_memory, PAGE_SIZE); ++ hct_data.pasid_memory = NULL; ++ } ++ ++ if (hct_data.hct_shared_memory) { ++ munmap((void *)hct_data.hct_shared_memory, HCT_SHARED_MEMORY_SIZE); ++ hct_data.hct_shared_memory = NULL; ++ } ++ ++ memory_listener_unregister(&hct_memory_listener); ++} ++ ++static int hct_data_init(HCTDevState *state) ++{ ++ int ret; ++ ++ if (hct_data.init == 0) { ++ ++ hct_data.hct_fd = qemu_open_old(HCT_SHARE_DEV, O_RDWR); ++ if (hct_data.hct_fd < 0) { ++ error_report("fail to open %s, errno %d.", HCT_SHARE_DEV, errno); ++ ret = -errno; ++ goto out; ++ } ++ ++ /* The hct.ko version number needs not to be less than 0.2. */ ++ ret = hct_api_version_check(); ++ if (ret) ++ goto out; ++ ++ /* assign a page to the virtual BAR3 of each CCP. */ ++ ret = hct_shared_memory_init(); ++ if (ret) ++ goto out; ++ ++ hct_data.pasid_memory = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ++ if (hct_data.pasid_memory < 0) ++ goto unmap_shared_memory_exit; ++ ++ /* assign a unique pasid to each virtual machine. */ ++ ret = pasid_get_and_init(state); ++ if (ret < 0) ++ goto unmap_pasid_memory_exit; ++ ++ /* perform DMA_MAP and DMA_UNMAP operations on all memories of the ++ * virtual machine. */ ++ memory_listener_register(&hct_memory_listener, &address_space_memory); ++ ++ hct_data.init = 1; ++ } ++ ++ return hct_get_ccp_index(state); ++ ++unmap_pasid_memory_exit: ++ munmap(hct_data.pasid_memory, PAGE_SIZE); ++ ++unmap_shared_memory_exit: ++ munmap((void *)hct_data.hct_shared_memory, HCT_SHARED_MEMORY_SIZE); ++ ++out: ++ return ret; ++} ++ ++/* When device is loaded */ ++static void vfio_hct_realize(PCIDevice *pci_dev, Error **errp) ++{ ++ int ret; ++ char *mdevid; ++ Error *err = NULL; ++ HCTDevState *state = PCI_HCT_DEV(pci_dev); ++ ++ /* parsing mdev device name from startup scripts */ ++ mdevid = g_path_get_basename(state->vdev.sysfsdev); ++ state->vdev.name = g_strdup_printf("%s", mdevid); ++ ++ ret = hct_data_init(state); ++ if (ret < 0) { ++ g_free(state->vdev.name); ++ goto out; ++ } ++ ++ ret = vfio_attach_device(state->vdev.name, &state->vdev, ++ pci_device_iommu_address_space(pci_dev), &err); ++ ++ if (ret) { ++ error_report("attach device failed, name = %s", state->vdev.name); ++ goto data_uninit_out; ++ } ++ ++ state->vdev.ops = &vfio_ccp_ops; ++ state->vdev.dev = &state->sdev.dev.qdev; ++ ++ ret = vfio_hct_region_mmap(state); ++ if (ret < 0) ++ goto detach_device_out; ++ ++ return; ++ ++detach_device_out: ++ vfio_hct_detach_device(state); ++ ++data_uninit_out: ++ hct_data_uninit(state); ++ ++out: ++ return; ++} ++ ++static void hct_dev_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass); ++ ++ dc->desc = "HCT Device"; ++ device_class_set_props(dc, vfio_hct_properties); ++ ++ pdc->realize = vfio_hct_realize; ++ pdc->exit = vfio_hct_exit; ++ pdc->vendor_id = PCI_VENDOR_ID_HYGON_CCP; ++ pdc->device_id = PCI_DEVICE_ID_HYGON_CCP; ++ pdc->class_id = PCI_CLASS_CRYPT_OTHER; ++ set_bit(DEVICE_CATEGORY_MISC, dc->categories); ++ ++ return; ++} ++ ++static const TypeInfo pci_hct_info = { ++ .name = TYPE_HCT_DEV, ++ .parent = TYPE_PCI_DEVICE, ++ .instance_size = sizeof(HCTDevState), ++ .class_init = hct_dev_class_init, ++ .interfaces = ++ (InterfaceInfo[]){ ++ {INTERFACE_CONVENTIONAL_PCI_DEVICE}, ++ {}, ++ }, ++}; ++ ++static void hct_register_types(void) { ++ type_register_static(&pci_hct_info); ++} ++ ++type_init(hct_register_types); +diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build +index 2a6912c940..b1db4c8605 100644 +--- a/hw/vfio/meson.build ++++ b/hw/vfio/meson.build +@@ -17,5 +17,6 @@ vfio_ss.add(when: 'CONFIG_VFIO_XGMAC', if_true: files('calxeda-xgmac.c')) + vfio_ss.add(when: 'CONFIG_VFIO_AMD_XGBE', if_true: files('amd-xgbe.c')) + vfio_ss.add(when: 'CONFIG_VFIO_AP', if_true: files('ap.c')) + vfio_ss.add(when: 'CONFIG_VFIO_IGD', if_true: files('igd.c')) ++vfio_ss.add(when: 'CONFIG_VFIO_HCT', if_true: files('hct.c')) + + specific_ss.add_all(when: 'CONFIG_VFIO', if_true: vfio_ss) +-- +2.41.0.windows.1 + diff --git a/hw-vfio-hct-fix-ccp_index-error-caused-by-uninitiali.patch b/hw-vfio-hct-fix-ccp_index-error-caused-by-uninitiali.patch new file mode 100644 index 0000000..22e8907 --- /dev/null +++ b/hw-vfio-hct-fix-ccp_index-error-caused-by-uninitiali.patch @@ -0,0 +1,28 @@ +From 360bd43ff3c4e4938ee8af1a5ccf981152f7ca95 Mon Sep 17 00:00:00 2001 +From: yangdepei +Date: Mon, 26 Aug 2024 15:40:25 +0800 +Subject: [PATCH] hw/vfio/hct: fix ccp_index error caused by uninitialized buf + +Signed-off-by: yangdepei +--- + hw/vfio/hct.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/vfio/hct.c b/hw/vfio/hct.c +index 790bb78439..9374e95e85 100644 +--- a/hw/vfio/hct.c ++++ b/hw/vfio/hct.c +@@ -235,8 +235,8 @@ static int hct_check_duplicated_index(int index) + + static int hct_get_ccp_index(HCTDevState *state) + { +- char path[PATH_MAX]; +- char buf[CCP_INDEX_BYTES]; ++ char path[PATH_MAX] = {0}; ++ char buf[CCP_INDEX_BYTES] = {0}; + int fd; + int ret; + int ccp_index; +-- +2.41.0.windows.1 + diff --git a/hw-vfio-hct-qemu-startup-terminate-once-error-happen.patch b/hw-vfio-hct-qemu-startup-terminate-once-error-happen.patch new file mode 100644 index 0000000..1609833 --- /dev/null +++ b/hw-vfio-hct-qemu-startup-terminate-once-error-happen.patch @@ -0,0 +1,79 @@ +From 32855e315c3050f09388f1335c0869bba065fbae Mon Sep 17 00:00:00 2001 +From: yangdepei +Date: Fri, 27 Sep 2024 17:08:08 +0800 +Subject: [PATCH] hw/vfio/hct: qemu startup terminate once error happened in + hct + +Signed-off-by: yangdepei +--- + hw/vfio/hct.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/hw/vfio/hct.c b/hw/vfio/hct.c +index 9374e95e85..7fd3977182 100644 +--- a/hw/vfio/hct.c ++++ b/hw/vfio/hct.c +@@ -136,7 +136,9 @@ static const MemoryRegionOps hct_mmio_ops = { + static void vfio_hct_detach_device(HCTDevState *state) + { + vfio_detach_device(&state->vdev); +- g_free(state->vdev.name); ++ ++ if (state->vdev.name) ++ g_free(state->vdev.name); + } + + static void vfio_hct_exit(PCIDevice *dev) +@@ -413,7 +415,6 @@ static int hct_data_init(HCTDevState *state) + int ret; + + if (hct_data.init == 0) { +- + hct_data.hct_fd = qemu_open_old(HCT_SHARE_DEV, O_RDWR); + if (hct_data.hct_fd < 0) { + error_report("fail to open %s, errno %d.", HCT_SHARE_DEV, errno); +@@ -465,7 +466,6 @@ static void vfio_hct_realize(PCIDevice *pci_dev, Error **errp) + { + int ret; + char *mdevid; +- Error *err = NULL; + HCTDevState *state = PCI_HCT_DEV(pci_dev); + + /* parsing mdev device name from startup scripts */ +@@ -475,14 +475,18 @@ static void vfio_hct_realize(PCIDevice *pci_dev, Error **errp) + ret = hct_data_init(state); + if (ret < 0) { + g_free(state->vdev.name); ++ state->vdev.name = NULL; ++ error_setg(errp, "hct data init failed"); + goto out; + } + + ret = vfio_attach_device(state->vdev.name, &state->vdev, +- pci_device_iommu_address_space(pci_dev), &err); ++ pci_device_iommu_address_space(pci_dev), errp); + + if (ret) { +- error_report("attach device failed, name = %s", state->vdev.name); ++ g_free(state->vdev.name); ++ state->vdev.name = NULL; ++ error_setg(errp, "attach device failed, name = %s", state->vdev.name); + goto data_uninit_out; + } + +@@ -491,7 +495,12 @@ static void vfio_hct_realize(PCIDevice *pci_dev, Error **errp) + + ret = vfio_hct_region_mmap(state); + if (ret < 0) ++ { ++ g_free(state->vdev.name); ++ state->vdev.name = NULL; ++ error_setg(errp, "region mmap failed, name = %s", state->vdev.name); + goto detach_device_out; ++ } + + return; + +-- +2.41.0.windows.1 + diff --git a/hw-vfio-hct-update-support-ccp-count-to-48.patch b/hw-vfio-hct-update-support-ccp-count-to-48.patch new file mode 100644 index 0000000..57e3947 --- /dev/null +++ b/hw-vfio-hct-update-support-ccp-count-to-48.patch @@ -0,0 +1,57 @@ +From 3af7045d3aea901d366f4f6dee51e70998351698 Mon Sep 17 00:00:00 2001 +From: Yabin Li +Date: Tue, 23 Apr 2024 15:38:48 +0800 +Subject: [PATCH] hw/vfio/hct: update support ccp count to 48. + +Signed-off-by: Yabin Li +Signed-off-by: yangdepei +--- + hw/vfio/hct.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/hw/vfio/hct.c b/hw/vfio/hct.c +index 476e86c61d..790bb78439 100644 +--- a/hw/vfio/hct.c ++++ b/hw/vfio/hct.c +@@ -28,7 +28,7 @@ + #include "qapi/error.h" + #include "hw/qdev-properties.h" + +-#define MAX_CCP_CNT 16 ++#define MAX_CCP_CNT 48 + #define PAGE_SIZE 4096 + #define HCT_SHARED_MEMORY_SIZE (PAGE_SIZE * MAX_CCP_CNT) + #define CCP_INDEX_BYTES 4 +@@ -43,7 +43,7 @@ + + #define HCT_SHARE_DEV "/dev/hct_share" + +-#define HCT_VERSION_STRING "0.2" ++#define HCT_VERSION_STRING "0.5" + #define DEF_VERSION_STRING "0.1" + #define VERSION_SIZE 16 + +@@ -281,15 +281,14 @@ static int hct_api_version_check(void) + memcpy(ctrl.version, DEF_VERSION_STRING, sizeof(DEF_VERSION_STRING)); + ret = ioctl(hct_data.hct_fd, HCT_SHARE_OP, &ctrl); + if (ret < 0) { +- error_report("ret %d, errno %d: fail to get hct.ko version, please " +- "update hct.ko to version 0.2.\n", +- ret, errno); ++ error_report("ret %d, errno %d: fail to get hct.ko version.\n", ret, ++ errno); + return -1; + } else if (memcmp(ctrl.version, HCT_VERSION_STRING, + sizeof(HCT_VERSION_STRING)) < 0) { +- error_report("The API version %s is larger than hct.ko version %s, " +- "please update hct.ko to version 0.2\n", +- HCT_VERSION_STRING, ctrl.version); ++ error_report("The hct.ko version is %s, please upgrade to version %s " ++ "or higher.\n", ++ ctrl.version, HCT_VERSION_STRING); + return -1; + } + +-- +2.41.0.windows.1 + diff --git a/meson.build-Remove-ncurses-workaround-for-OpenBSD.patch b/meson.build-Remove-ncurses-workaround-for-OpenBSD.patch new file mode 100644 index 0000000..5db58de --- /dev/null +++ b/meson.build-Remove-ncurses-workaround-for-OpenBSD.patch @@ -0,0 +1,51 @@ +From 199dcd16027e3573f5eeaa4396c361cfec91cbe1 Mon Sep 17 00:00:00 2001 +From: Susanooo +Date: Fri, 25 Oct 2024 09:44:21 +0800 +Subject: [PATCH] meson.build: Remove ncurses workaround for OpenBSD +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +meson.build: Remove ncurses workaround for OpenBSD + +OpenBSD 7.5 has upgraded to ncurses 6.4. + +Signed-off-by: Brad Smith +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Michael Tokarev +Signed-off-by: Michael Tokarev +Signed-off-by: zhangchujun +--- + meson.build | 2 +- + ui/curses.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/meson.build b/meson.build +index 4024f9a4bb..b3ee125b72 100644 +--- a/meson.build ++++ b/meson.build +@@ -1139,7 +1139,7 @@ iconv = not_found + curses = not_found + if have_system and get_option('curses').allowed() + curses_test = ''' +- #if defined(__APPLE__) || defined(__OpenBSD__) ++ #ifdef __APPLE__ + #define _XOPEN_SOURCE_EXTENDED 1 + #endif + #include +diff --git a/ui/curses.c b/ui/curses.c +index 8bde8c5cf7..26438486fc 100644 +--- a/ui/curses.c ++++ b/ui/curses.c +@@ -38,7 +38,7 @@ + #include "ui/input.h" + #include "sysemu/sysemu.h" + +-#if defined(__APPLE__) || defined(__OpenBSD__) ++#ifdef __APPLE__ + #define _XOPEN_SOURCE_EXTENDED 1 + #endif + +-- +2.41.0.windows.1 + diff --git a/qemu.spec b/qemu.spec index 58f1288..ae2bdd3 100644 --- a/qemu.spec +++ b/qemu.spec @@ -3,7 +3,7 @@ Name: qemu Version: 8.2.0 -Release: 24 +Release: 25 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 @@ -425,6 +425,22 @@ Patch0408: target-arm-Clear-high-SVE-elements-in-handle_vec_sim.patch Patch0409: target-ppc-Fix-migration-of-CPUs-with-TLB_EMB-TLB-ty.patch Patch0410: target-hppa-Fix-PSW-V-bit-packaging-in-cpu_hppa_get-.patch Patch0411: ppc-xive-Fix-ESB-length-overflow-on-32-bit-hosts.patch +Patch0412: hw-vfio-add-device-hct-based-on-vfio.patch +Patch0413: hw-vfio-hct-update-support-ccp-count-to-48.patch +Patch0414: hw-vfio-hct-fix-ccp_index-error-caused-by-uninitiali.patch +Patch0415: hw-vfio-hct-qemu-startup-terminate-once-error-happen.patch +Patch0416: s390x-sclp-Simplify-get_sclp_device.patch +Patch0417: ui-remove-break-after-g_assert_not_reached.patch +Patch0418: ui-console-vc-Silence-warning-about-sprintf-on-OpenB.patch +Patch0419: meson.build-Remove-ncurses-workaround-for-OpenBSD.patch +Patch0420: hw-audio-hda-free-timer-on-exit.patch +Patch0421: hw-pci-Add-parenthesis-to-PCI_BUILD_BDF-macro.patch +Patch0422: hw-cxl-Ensure-there-is-enough-data-for-the-header-in.patch +Patch0423: target-i386-sev-Fix-incompatibility-between-SEV-and-.patch +Patch0424: target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch +Patch0425: Add-virtCCA-Coda-annotation.patch +Patch0426: cvm-Add-support-for-TEE-based-national-encryption-ac.patch +Patch0427: hw-arm-virt-Keep-Guest-L1-cache-type-consistent-with.patch BuildRequires: flex BuildRequires: gcc @@ -1022,6 +1038,24 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Sat Nov 30 2024 Jiabo Feng - 11:8.2.0-25 +- hw/arm/virt:Keep Guest L1 cache type consistent with KVM +- cvm : Add support for TEE-based national encryption acceleration. +- Add virtCCA Coda annotation Adjust the position of the security device +- target/i386: sev: Add support for reuse ASID for different CSV guests +- target/i386: sev: Fix incompatibility between SEV and CSV on the GET_ID API +- hw/cxl: Ensure there is enough data for the header in cmd_ccls_set_lsa() +- hw/pci: Add parenthesis to PCI_BUILD_BDF macro +- hw/audio/hda: free timer on exit +- meson.build: Remove ncurses workaround for OpenBSD +- ui/console-vc: Silence warning about sprintf() on OpenBSD +- ui: remove break after g_assert_not_reached() +- s390x/sclp: Simplify get_sclp_device() +- hw/vfio/hct: qemu startup terminate once error happened in hct +- hw/vfio/hct: fix ccp_index error caused by uninitialized buf +- hw/vfio/hct: update support ccp count to 48. +- hw/vfio: add device hct based on vfio. + * Sat Nov 30 2024 Jiabo Feng - 11:8.2.0-24 - ppc/xive: Fix ESB length overflow on 32-bit hosts - target/hppa: Fix PSW V-bit packaging in cpu_hppa_get for hppa64 diff --git a/s390x-sclp-Simplify-get_sclp_device.patch b/s390x-sclp-Simplify-get_sclp_device.patch new file mode 100644 index 0000000..297c6b3 --- /dev/null +++ b/s390x-sclp-Simplify-get_sclp_device.patch @@ -0,0 +1,48 @@ +From 358b772c1289c1bf42dfe8c62b04b8a28d60ebf1 Mon Sep 17 00:00:00 2001 +From: Zhang Jiao +Date: Mon, 21 Oct 2024 14:28:13 +0800 +Subject: [PATCH] s390x/sclp: Simplify get_sclp_device() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from 3d9836e46dbe1e46c39fe76a62d3085a71ddbf7a + +get_sclp_device() scans the whole machine to find a TYPE_SCLP object. +Now that the SCLPDevice instance is available under the machine state, +use it to simplify the lookup. While at it, remove the inline to let +the compiler decide on how to optimize. + +Signed-off-by: Cédric Le Goater +Message-ID: <20240502131533.377719-4-clg@redhat.com> +Reviewed-by: Thomas Huth +Signed-off-by: Thomas Huth +Signed-off-by: Zhang Jiao +--- + hw/s390x/sclp.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c +index 893e71a41b..69bf04e23a 100644 +--- a/hw/s390x/sclp.c ++++ b/hw/s390x/sclp.c +@@ -21,13 +21,14 @@ + #include "hw/s390x/s390-pci-bus.h" + #include "hw/s390x/ipl.h" + #include "hw/s390x/cpu-topology.h" ++#include "hw/s390x/s390-virtio-ccw.h" + +-static inline SCLPDevice *get_sclp_device(void) ++static SCLPDevice *get_sclp_device(void) + { + static SCLPDevice *sclp; + + if (!sclp) { +- sclp = SCLP(object_resolve_path_type("", TYPE_SCLP, NULL)); ++ sclp = S390_CCW_MACHINE(qdev_get_machine())->sclp; + } + return sclp; + } +-- +2.41.0.windows.1 + diff --git a/target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch b/target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch new file mode 100644 index 0000000..f029a89 --- /dev/null +++ b/target-i386-sev-Add-support-for-reuse-ASID-for-diffe.patch @@ -0,0 +1,177 @@ +From 8f4f8a2071e69130f0b9327ce8f9b92a5ae42c8d Mon Sep 17 00:00:00 2001 +From: appleLin +Date: Wed, 3 Aug 2022 21:02:41 +0800 +Subject: [PATCH] target/i386: sev: Add support for reuse ASID for different + CSV guests + +In you want to reuse one ASID for many CSV guests, you should provide a +label (i.e. userid) and the length of the label when launch CSV guest. +The CSV guests which were provided the same userid will share the same +ASID. + +Signed-off-by: hanliyang +--- + linux-headers/linux/kvm.h | 5 +++++ + qapi/qom.json | 6 ++++- + qemu-options.hx | 5 ++++- + target/i386/csv.h | 2 ++ + target/i386/sev.c | 46 ++++++++++++++++++++++++++++++++++++++- + 5 files changed, 61 insertions(+), 3 deletions(-) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index eb30402c2d..8dc00808ec 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -2103,6 +2103,11 @@ struct kvm_csv_command_batch { + __u64 csv_batch_list_uaddr; + }; + ++struct kvm_csv_init { ++ __u64 userid_addr; ++ __u32 len; ++}; ++ + #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) + #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) + #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) +diff --git a/qapi/qom.json b/qapi/qom.json +index 213edd8db2..8c7461a113 100644 +--- a/qapi/qom.json ++++ b/qapi/qom.json +@@ -866,6 +866,9 @@ + # designated guest firmware page for measured boot with -kernel + # (default: false) (since 6.2) + # ++# @user-id: the user id of the guest owner, only support on Hygon CPUs ++# (since 8.2) ++# + # Since: 2.12 + ## + { 'struct': 'SevGuestProperties', +@@ -876,7 +879,8 @@ + '*handle': 'uint32', + '*cbitpos': 'uint32', + 'reduced-phys-bits': 'uint32', +- '*kernel-hashes': 'bool' } } ++ '*kernel-hashes': 'bool', ++ '*user-id': 'str' } } + + ## + # @ThreadContextProperties: +diff --git a/qemu-options.hx b/qemu-options.hx +index 42fd09e4de..9829b1020a 100644 +--- a/qemu-options.hx ++++ b/qemu-options.hx +@@ -5637,7 +5637,7 @@ SRST + -object secret,id=sec0,keyid=secmaster0,format=base64,\\ + data=$SECRET,iv=$(dh_cert_file = g_strdup(value); + } + ++static char * ++sev_guest_get_user_id(Object *obj, Error **errp) ++{ ++ SevGuestState *s = SEV_GUEST(obj); ++ ++ return g_strdup(s->user_id); ++} ++ ++static void ++sev_guest_set_user_id(Object *obj, const char *value, Error **errp) ++{ ++ SevGuestState *s = SEV_GUEST(obj); ++ ++ s->user_id = g_strdup(value); ++} ++ + static char * + sev_guest_get_sev_device(Object *obj, Error **errp) + { +@@ -426,6 +443,11 @@ sev_guest_class_init(ObjectClass *oc, void *data) + sev_guest_set_kernel_hashes); + object_class_property_set_description(oc, "kernel-hashes", + "add kernel hashes to guest firmware for measured Linux boot"); ++ object_class_property_add_str(oc, "user-id", ++ sev_guest_get_user_id, ++ sev_guest_set_user_id); ++ object_class_property_set_description(oc, "user-id", ++ "user id of the guest owner"); + } + + static void +@@ -1174,7 +1196,29 @@ int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp) + } + + trace_kvm_sev_init(); +- ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); ++ ++ /* Only support reuse asid for CSV/CSV2 guest */ ++ if (is_hygon_cpu() && ++ (sev_guest->policy & GUEST_POLICY_REUSE_ASID)) { ++ char *user_id = NULL; ++ struct kvm_csv_init *init_cmd_buf = NULL; ++ ++ user_id = object_property_get_str(OBJECT(sev), "user-id", NULL); ++ if (user_id && strlen(user_id)) { ++ init_cmd_buf = g_new0(struct kvm_csv_init, 1); ++ init_cmd_buf->len = strlen(user_id); ++ init_cmd_buf->userid_addr = (__u64)user_id; ++ } ++ ret = sev_ioctl(sev->sev_fd, cmd, init_cmd_buf, &fw_error); ++ ++ if (user_id) { ++ g_free(user_id); ++ g_free(init_cmd_buf); ++ } ++ } else { ++ ret = sev_ioctl(sev->sev_fd, cmd, NULL, &fw_error); ++ } ++ + if (ret) { + error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'", + __func__, ret, fw_error, fw_error_to_str(fw_error)); +-- +2.41.0.windows.1 + diff --git a/target-i386-sev-Fix-incompatibility-between-SEV-and-.patch b/target-i386-sev-Fix-incompatibility-between-SEV-and-.patch new file mode 100644 index 0000000..abc6d3a --- /dev/null +++ b/target-i386-sev-Fix-incompatibility-between-SEV-and-.patch @@ -0,0 +1,36 @@ +From c357946fa7c1d45a09b40214b5113f689bf7bbd0 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Fri, 1 Mar 2024 14:12:44 +0800 +Subject: [PATCH] target/i386: sev: Fix incompatibility between SEV and CSV on + the GET_ID API + +If the length of GET_ID request is too small, Hygon CSV will return +SEV_RET_INVALID_PARAM. This return code doesn't comply with SEV API +Spec. + +Hygon will consider to fix the compitibility issue of return value +of the GET_ID API, so also check whether the return value is +SEV_RET_INVALID_LEN on Hygon CPUs. + +Signed-off-by: hanliyang +--- + target/i386/sev.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 2c6aecd1a3..04888bc3a8 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -589,7 +589,8 @@ static int sev_get_cpu0_id(int fd, guchar **id, size_t *id_len, Error **errp) + + /* query the ID length */ + r = sev_platform_ioctl(fd, SEV_GET_ID2, &get_id2, &err); +- if (r < 0 && err != SEV_RET_INVALID_LEN) { ++ if (r < 0 && err != SEV_RET_INVALID_LEN && ++ !(is_hygon_cpu() && err == SEV_RET_INVALID_PARAM)) { + error_setg(errp, "SEV: Failed to get ID ret=%d fw_err=%d (%s)", + r, err, fw_error_to_str(err)); + return 1; +-- +2.41.0.windows.1 + diff --git a/ui-console-vc-Silence-warning-about-sprintf-on-OpenB.patch b/ui-console-vc-Silence-warning-about-sprintf-on-OpenB.patch new file mode 100644 index 0000000..b82b1c5 --- /dev/null +++ b/ui-console-vc-Silence-warning-about-sprintf-on-OpenB.patch @@ -0,0 +1,52 @@ +From e41395594aab30a22ffaf1556d19ee623a33e6ec Mon Sep 17 00:00:00 2001 +From: Susanooo +Date: Fri, 25 Oct 2024 09:33:41 +0800 +Subject: [PATCH] ui/console-vc: Silence warning about sprintf() on OpenBSD +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The linker on OpenBSD complains: + + ld: warning: console-vc.c:824 (../src/ui/console-vc.c:824)([...]): + warning: sprintf() is often misused, please use snprintf() + +Using g_strdup_printf() is certainly better here, so let's switch +to that function instead. + +Signed-off-by: Thomas Huth +Reviewed-by: Marc-André Lureau +Reviewed-by: Alex Bennée +Reviewed-by: Richard Henderson +Reviewed-by: Michael Tokarev +Signed-off-by: Michael Tokarev +Signed-off-by: zhangchujun +--- + ui/console-vc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ui/console-vc.c b/ui/console-vc.c +index 9c13cc2981..b1903c3e48 100644 +--- a/ui/console-vc.c ++++ b/ui/console-vc.c +@@ -648,7 +648,7 @@ static void vc_putchar(VCChardev *vc, int ch) + QemuTextConsole *s = vc->console; + int i; + int x, y; +- char response[40]; ++ g_autofree char *response = NULL; + + switch(vc->state) { + case TTY_STATE_NORM: +@@ -821,7 +821,7 @@ static void vc_putchar(VCChardev *vc, int ch) + break; + case 6: + /* report cursor position */ +- sprintf(response, "\033[%d;%dR", ++ response = g_strdup_printf("\033[%d;%dR", + (s->y_base + s->y) % s->total_height + 1, + s->x + 1); + vc_respond_str(vc, response); +-- +2.41.0.windows.1 + diff --git a/ui-remove-break-after-g_assert_not_reached.patch b/ui-remove-break-after-g_assert_not_reached.patch new file mode 100644 index 0000000..0f026ce --- /dev/null +++ b/ui-remove-break-after-g_assert_not_reached.patch @@ -0,0 +1,48 @@ +From c761dac5d72f0d7c4643125e0611c75334b4ec4e Mon Sep 17 00:00:00 2001 +From: Zhang Jiao +Date: Mon, 21 Oct 2024 15:58:54 +0800 +Subject: [PATCH] ui: remove break after g_assert_not_reached() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from b3372e0ec818d7747963a2ec7ae04fd1a8152afd + +Use of assert(false) can trip spurious control flow warnings from +some versions of GCC (i.e. using -fsanitize=thread with gcc-12): + + error: control reaches end of non-void function [-Werror=return-type] + default: + g_assert_not_reached(); + break; + | ^^^^^ + +Solve that by removing the unreachable 'break' statement, unifying +the code base on g_assert_not_reached() instead. + +Signed-off-by: Pierrick Bouvier +Reviewed-by: Richard Henderson +Reviewed-by: Philippe Mathieu-Daudé +Message-ID: <20240910221606.1817478-37-pierrick.bouvier@linaro.org> +[PMD: Add description suggested by Eric Blake] +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: Zhang Jiao +--- + ui/qemu-pixman.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c +index 5ca55dd199..6cada8b45e 100644 +--- a/ui/qemu-pixman.c ++++ b/ui/qemu-pixman.c +@@ -49,7 +49,6 @@ PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format) + break; + default: + g_assert_not_reached(); +- break; + } + + pf.amax = (1 << pf.abits) - 1; +-- +2.41.0.windows.1 + -- Gitee