From 030950c947f123de2f6f8f7c9590a46867efc4d2 Mon Sep 17 00:00:00 2001 From: Jacob Wang Date: Mon, 11 Aug 2025 11:54:58 +0800 Subject: [PATCH 1/8] [CVE]update to libvirt-8.0.0-23.4 to #ICSB5G update to libvirt-8.0.0-23.4 for CVE-2025-49133 Project: TC2024080204 Signed-off-by: Jacob Wang --- ...bvirt-support-reuse-id-for-hygon-CSV.patch | 89 -- ...t-provide-inject-secret-for-Hygon-CS.patch | 129 -- libvirt-Add-loongarch-support.patch | 1233 ----------------- ...w64-architecture-support-for-libvirt.patch | 687 --------- libvirt-add-loongarch-edit-xml-validate.patch | 20 - ...nf-add-deprecated_features-attribute.patch | 135 ++ libvirt-cpu-Add-new-Dharma-CPU-model.patch | 131 -- libvirt-cpu-map-add-S5000C-cpu-model.patch | 54 - ...BILITIES_DISABLE_DEPRECATED_FEATURES.patch | 58 + ...m-query-cpu-model-expansion-response.patch | 214 +++ ...Expansion-refactor-parsing-functions.patch | 100 ++ ...ter-deprecated-features-if-requested.patch | 95 ++ ...y-deprecated-features-for-host-model.patch | 128 ++ ...ntroduce-virXMLNodeGetSubelementList.patch | 104 ++ ...from-virXMLNodeGetSubelement-partial.patch | 92 ++ ...ted-features-flag-to-domcapabilities.patch | 83 ++ libvirt.spec | 57 +- ...e-correct-tpm-device-for-all-non-x86.patch | 32 - ...alidate-Drop-tpm-tis-arch-validation.patch | 35 - 19 files changed, 1036 insertions(+), 2440 deletions(-) delete mode 100644 1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch delete mode 100644 1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch delete mode 100644 libvirt-Add-loongarch-support.patch delete mode 100644 libvirt-Add-sw64-architecture-support-for-libvirt.patch delete mode 100644 libvirt-add-loongarch-edit-xml-validate.patch create mode 100644 libvirt-conf-add-deprecated_features-attribute.patch delete mode 100644 libvirt-cpu-Add-new-Dharma-CPU-model.patch delete mode 100644 libvirt-cpu-map-add-S5000C-cpu-model.patch create mode 100644 libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES.patch create mode 100644 libvirt-qemu-parse-deprecated-props-from-query-cpu-model-expansion-response.patch create mode 100644 libvirt-qemuMonitorJSONGetCPUModelExpansion-refactor-parsing-functions.patch create mode 100644 libvirt-qemu_capabilities-filter-deprecated-features-if-requested.patch create mode 100644 libvirt-qemu_capabilities-query-deprecated-features-for-host-model.patch create mode 100644 libvirt-util-xml-Introduce-virXMLNodeGetSubelementList.patch create mode 100644 libvirt-util-xml-Return-GPtrArray-from-virXMLNodeGetSubelement-partial.patch create mode 100644 libvirt-virsh-add-disable-deprecated-features-flag-to-domcapabilities.patch delete mode 100644 qemu-command-Use-correct-tpm-device-for-all-non-x86.patch delete mode 100644 qemu-validate-Drop-tpm-tis-arch-validation.patch diff --git a/1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch b/1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch deleted file mode 100644 index b9b178a..0000000 --- a/1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch +++ /dev/null @@ -1,89 +0,0 @@ -From f5f6b60a6f8d58bbece7db96730cd506cd5703ee Mon Sep 17 00:00:00 2001 -From: panpingsheng -Date: Fri, 8 Sep 2023 15:04:44 +0800 -Subject: [PATCH 1/2] conf: qemu: add libvirt support reuse id for hygon CSV - -csv xml format: - - 0x0081 - 47 - 5 - usertest - - -Signed-off-by: panpingsheng -Signed-off-by: Xin Jiang -Signed-off-by: hanliyang ---- - src/conf/domain_conf.c | 5 +++++ - src/conf/domain_conf.h | 1 + - src/qemu/qemu_command.c | 4 ++++ - 3 files changed, 10 insertions(+) - -diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c -index 427e7d1..85a5d9c 100644 ---- a/src/conf/domain_conf.c -+++ b/src/conf/domain_conf.c -@@ -3560,6 +3560,7 @@ virDomainSecDefFree(virDomainSecDef *def) - case VIR_DOMAIN_LAUNCH_SECURITY_SEV: - g_free(def->data.sev.dh_cert); - g_free(def->data.sev.session); -+ g_free(def->data.sev.user_id); - break; - case VIR_DOMAIN_LAUNCH_SECURITY_PV: - case VIR_DOMAIN_LAUNCH_SECURITY_NONE: -@@ -14850,6 +14851,7 @@ virDomainSEVDefParseXML(virDomainSEVDef *def, - def->policy = policy; - def->dh_cert = virXPathString("string(./dhCert)", ctxt); - def->session = virXPathString("string(./session)", ctxt); -+ def->user_id = virXPathString("string(./userid)", ctxt); - - return 0; - } -@@ -27179,6 +27181,9 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec) - if (sev->session) - virBufferEscapeString(&childBuf, "%s\n", sev->session); - -+ if (sev->user_id) -+ virBufferEscapeString(&childBuf, "%s\n", sev->user_id); -+ - break; - } - -diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h -index 930af36..768ba5f 100644 ---- a/src/conf/domain_conf.h -+++ b/src/conf/domain_conf.h -@@ -2717,6 +2717,7 @@ struct _virDomainSEVDef { - bool haveReducedPhysBits; - unsigned int reduced_phys_bits; - virTristateBool kernel_hashes; -+ char *user_id; - }; - - struct _virDomainSecDef { -diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c -index 978ce89..d742ac4 100644 ---- a/src/qemu/qemu_command.c -+++ b/src/qemu/qemu_command.c -@@ -9930,6 +9930,9 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, - VIR_DEBUG("policy=0x%x cbitpos=%d reduced_phys_bits=%d", - sev->policy, sev->cbitpos, sev->reduced_phys_bits); - -+ if (sev->user_id) -+ VIR_DEBUG("user_id=%s", sev->user_id); -+ - if (sev->dh_cert) - dhpath = g_strdup_printf("%s/dh_cert.base64", priv->libDir); - -@@ -9940,6 +9943,7 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, - "u:cbitpos", sev->cbitpos, - "u:reduced-phys-bits", sev->reduced_phys_bits, - "u:policy", sev->policy, -+ "S:user-id", sev->user_id, - "S:dh-cert-file", dhpath, - "S:session-file", sessionpath, - "T:kernel-hashes", sev->kernel_hashes, --- -2.43.5 - diff --git a/1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch b/1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch deleted file mode 100644 index 788eecc..0000000 --- a/1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch +++ /dev/null @@ -1,129 +0,0 @@ -From ad62b677c476440b1a831d4fb8f5f7ef3c7a9975 Mon Sep 17 00:00:00 2001 -From: hanliyang -Date: Wed, 13 Nov 2024 16:12:57 +0800 -Subject: [PATCH 2/2] conf: qemu: support provide inject secret for Hygon CSV - -csv xml format: - - 0x0001 - 47 - 5 - U2FsdGVkX1+rW6B/JbYqNA== - 5aeG4mH2E/OqN1a3uT8hfg== - gW3E30rG/I3L1nD/YfG+DA== - zP1oY9W7ZcPFtL0QeN11vQ== - - -Signed-off-by: hanliyang ---- - src/conf/domain_conf.c | 8 ++++++++ - src/conf/domain_conf.h | 2 ++ - src/qemu/qemu_command.c | 10 ++++++++++ - src/qemu/qemu_process.c | 10 ++++++++++ - 4 files changed, 30 insertions(+) - -diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c -index 85a5d9c..fa108b1 100644 ---- a/src/conf/domain_conf.c -+++ b/src/conf/domain_conf.c -@@ -3561,6 +3561,8 @@ virDomainSecDefFree(virDomainSecDef *def) - g_free(def->data.sev.dh_cert); - g_free(def->data.sev.session); - g_free(def->data.sev.user_id); -+ g_free(def->data.sev.secret_header); -+ g_free(def->data.sev.secret); - break; - case VIR_DOMAIN_LAUNCH_SECURITY_PV: - case VIR_DOMAIN_LAUNCH_SECURITY_NONE: -@@ -14852,6 +14854,8 @@ virDomainSEVDefParseXML(virDomainSEVDef *def, - def->dh_cert = virXPathString("string(./dhCert)", ctxt); - def->session = virXPathString("string(./session)", ctxt); - def->user_id = virXPathString("string(./userid)", ctxt); -+ def->secret_header = virXPathString("string(./secretHeader)", ctxt); -+ def->secret = virXPathString("string(./secret)", ctxt); - - return 0; - } -@@ -27183,6 +27187,10 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec) - - if (sev->user_id) - virBufferEscapeString(&childBuf, "%s\n", sev->user_id); -+ if (sev->secret_header) -+ virBufferEscapeString(&childBuf, "%s\n", sev->secret_header); -+ if (sev->secret) -+ virBufferEscapeString(&childBuf, "%s\n", sev->secret); - - break; - } -diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h -index 768ba5f..2bc4358 100644 ---- a/src/conf/domain_conf.h -+++ b/src/conf/domain_conf.h -@@ -2718,6 +2718,8 @@ struct _virDomainSEVDef { - unsigned int reduced_phys_bits; - virTristateBool kernel_hashes; - char *user_id; -+ char *secret_header; -+ char *secret; - }; - - struct _virDomainSecDef { -diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c -index d742ac4..2b6b5fb 100644 ---- a/src/qemu/qemu_command.c -+++ b/src/qemu/qemu_command.c -@@ -9926,6 +9926,8 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, - qemuDomainObjPrivate *priv = vm->privateData; - g_autofree char *dhpath = NULL; - g_autofree char *sessionpath = NULL; -+ g_autofree char *secretheaderpath = NULL; -+ g_autofree char *secretpath = NULL; - - VIR_DEBUG("policy=0x%x cbitpos=%d reduced_phys_bits=%d", - sev->policy, sev->cbitpos, sev->reduced_phys_bits); -@@ -9939,6 +9941,12 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, - if (sev->session) - sessionpath = g_strdup_printf("%s/session.base64", priv->libDir); - -+ if (sev->secret_header) -+ secretheaderpath = g_strdup_printf("%s/secret_header.base64", priv->libDir); -+ -+ if (sev->secret) -+ secretpath = g_strdup_printf("%s/secret.base64", priv->libDir); -+ - if (qemuMonitorCreateObjectProps(&props, "sev-guest", "lsec0", - "u:cbitpos", sev->cbitpos, - "u:reduced-phys-bits", sev->reduced_phys_bits, -@@ -9947,6 +9955,8 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, - "S:dh-cert-file", dhpath, - "S:session-file", sessionpath, - "T:kernel-hashes", sev->kernel_hashes, -+ "S:secret-header-file", secretheaderpath, -+ "S:secret-file", secretpath, - NULL) < 0) - return -1; - -diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c -index 73d54f0..dac44ce 100644 ---- a/src/qemu/qemu_process.c -+++ b/src/qemu/qemu_process.c -@@ -6650,6 +6650,16 @@ qemuProcessPrepareSEVGuestInput(virDomainObj *vm) - return -1; - } - -+ if (sev->secret_header) { -+ if (qemuProcessSEVCreateFile(vm, "secret_header", sev->secret_header) < 0) -+ return -1; -+ } -+ -+ if (sev->secret) { -+ if (qemuProcessSEVCreateFile(vm, "secret", sev->secret) < 0) -+ return -1; -+ } -+ - return 0; - } - --- -2.43.5 - diff --git a/libvirt-Add-loongarch-support.patch b/libvirt-Add-loongarch-support.patch deleted file mode 100644 index ac0da71..0000000 --- a/libvirt-Add-loongarch-support.patch +++ /dev/null @@ -1,1233 +0,0 @@ -From da7befb4ce165d692f34156f740f4ea3ce2b7fec Mon Sep 17 00:00:00 2001 -From: zhaotianrui -Date: Sat, 3 Sep 2022 14:23:43 -0400 -Subject: [PATCH] Add loongarch support - -Signed-off-by: zhaotianrui -Change-Id: I8d245bc2fb914b08af4ade8e334d59ba3a5c2f01 ---- - po/POTFILES.in | 1 + - src/cpu/cpu.c | 3 +- - src/cpu/cpu.h | 3 +- - src/cpu/cpu_loongarch.c | 727 ++++++++++++++++++++++++++++++ - src/cpu/cpu_loongarch.h | 28 ++ - src/cpu/cpu_loongarch_data.h | 40 ++ - src/cpu/meson.build | 1 + - src/cpu_map/index.xml | 5 + - src/cpu_map/loongarch_vendors.xml | 3 + - src/cpu_map/ls_3a5000.xml | 6 + - src/cpu_map/meson.build | 2 + - src/qemu/qemu_capabilities.c | 5 + - src/qemu/qemu_conf.c | 4 +- - src/qemu/qemu_domain.c | 20 +- - src/qemu/qemu_domain.h | 1 + - src/qemu/qemu_domain_address.c | 58 +++ - src/qemu/qemu_validate.c | 3 +- - src/util/virarch.c | 3 + - src/util/virarch.h | 3 + - src/util/virhostcpu.c | 2 +- - src/util/virsysinfo.c | 2 +- - 21 files changed, 913 insertions(+), 7 deletions(-) - create mode 100644 src/cpu/cpu_loongarch.c - create mode 100644 src/cpu/cpu_loongarch.h - create mode 100644 src/cpu/cpu_loongarch_data.h - create mode 100644 src/cpu_map/loongarch_vendors.xml - create mode 100644 src/cpu_map/ls_3a5000.xml - -diff --git a/po/POTFILES.in b/po/POTFILES.in -index bf0a3b3529..1153e78265 100644 ---- a/po/POTFILES.in -+++ b/po/POTFILES.in -@@ -68,6 +68,7 @@ - @SRCDIR@src/cpu/cpu_arm.c - @SRCDIR@src/cpu/cpu_map.c - @SRCDIR@src/cpu/cpu_ppc64.c -+@SRCDIR@src/cpu/cpu_loongarch.c - @SRCDIR@src/cpu/cpu_s390.c - @SRCDIR@src/cpu/cpu_x86.c - @SRCDIR@src/datatypes.c -diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c -index 285c7eee44..49527c3688 100644 ---- a/src/cpu/cpu.c -+++ b/src/cpu/cpu.c -@@ -31,7 +31,7 @@ - #include "cpu_arm.h" - #include "capabilities.h" - #include "virstring.h" -- -+#include "cpu_loongarch.h" - - #define VIR_FROM_THIS VIR_FROM_CPU - -@@ -42,6 +42,7 @@ static struct cpuArchDriver *drivers[] = { - &cpuDriverPPC64, - &cpuDriverS390, - &cpuDriverArm, -+ &cpuDriverLoongArch, - }; - - -diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h -index 071b33fe76..ce7aee4757 100644 ---- a/src/cpu/cpu.h -+++ b/src/cpu/cpu.h -@@ -28,7 +28,7 @@ - #include "cpu_x86_data.h" - #include "cpu_ppc64_data.h" - #include "cpu_arm_data.h" -- -+#include "cpu_loongarch_data.h" - - typedef struct _virCPUData virCPUData; - struct _virCPUData { -@@ -37,6 +37,7 @@ struct _virCPUData { - virCPUx86Data x86; - virCPUppc64Data ppc64; - virCPUarmData arm; -+ virCPULoongArchData loongarch; - /* generic driver needs no data */ - } data; - }; -diff --git a/src/cpu/cpu_loongarch.c b/src/cpu/cpu_loongarch.c -new file mode 100644 -index 0000000000..f7b4b85a44 ---- /dev/null -+++ b/src/cpu/cpu_loongarch.c -@@ -0,0 +1,727 @@ -+/* -+ * cpu_loongarch.c: CPU driver for 64-bit LOONGARCH CPUs -+ * -+ * Copyright (C) 2013 Red Hat, Inc. -+ * Copyright (C) IBM Corporation, 2010 -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library. If not, see -+ * . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "virlog.h" -+#include "viralloc.h" -+#include "cpu.h" -+#include "virstring.h" -+#include "cpu_map.h" -+#include "virbuffer.h" -+#include "cpu_loongarch.h" -+#include "cpu_loongarch_data.h" -+ -+#define VIR_FROM_THIS VIR_FROM_CPU -+ -+VIR_LOG_INIT("cpu.cpu_loongarch"); -+ -+static const virArch archs[] = { VIR_ARCH_LOONGARCH64 }; -+ -+typedef struct _LoongArch_vendor LoongArch_vendor; -+struct _LoongArch_vendor { -+ char *name; -+}; -+ -+typedef struct _LoongArch_model LoongArch_model; -+struct _LoongArch_model { -+ char *name; -+ LoongArch_vendor *vendor; -+ virCPULoongArchData data; -+}; -+ -+typedef struct _LoongArch_map LoongArch_map; -+struct _LoongArch_map { -+ size_t nvendors; -+ LoongArch_vendor **vendors; -+ size_t nmodels; -+ LoongArch_model **models; -+}; -+ -+static void -+LoongArchDataClear(virCPULoongArchData *data) -+{ -+ if (!data) -+ return; -+ -+ g_free(data->prid); -+} -+ -+static int -+LoongArchDataCopy(virCPULoongArchData *dst, const virCPULoongArchData *src) -+{ -+ size_t i; -+ -+ dst->prid = g_new0(virCPULoongArchPrid, src->len); -+ dst->len = src->len; -+ -+ for (i = 0; i < src->len; i++) { -+ dst->prid[i].value = src->prid[i].value; -+ dst->prid[i].mask = src->prid[i].mask; -+ } -+ -+ return 0; -+} -+ -+static void -+LoongArchVendorFree(LoongArch_vendor *vendor) -+{ -+ if (!vendor) -+ return; -+ -+ g_free(vendor); -+} -+ -+static LoongArch_vendor * -+LoongArchVendorFind(LoongArch_map *map, -+ const char *name) -+{ -+ size_t i; -+ -+ for (i = 0; i < map->nvendors; i++) { -+ if (STREQ(map->vendors[i]->name, name)) -+ return map->vendors[i]; -+ } -+ -+ return NULL; -+} -+ -+static void -+LoongArchModelFree(LoongArch_model *model) -+{ -+ if (!model) -+ return; -+ -+ LoongArchDataClear(&model->data); -+ g_free(model->name); -+ g_free(model); -+} -+ -+static LoongArch_model * -+LoongArchModelCopy(LoongArch_model *model) -+{ -+ LoongArch_model *copy; -+ -+ copy = g_new0(LoongArch_model, 1); -+ copy->name = g_strdup(model->name); -+ -+ if (LoongArchDataCopy(©->data, &model->data) < 0) -+ goto error; -+ -+ copy->vendor = model->vendor; -+ -+ return copy; -+ -+ error: -+ LoongArchModelFree(copy); -+ return NULL; -+} -+ -+static LoongArch_model * -+LoongArchModelFind(LoongArch_map *map, -+ const char *name) -+{ -+ size_t i; -+ -+ for (i = 0; i < map->nmodels; i++) { -+ if (STREQ(map->models[i]->name, name)) -+ return map->models[i]; -+ } -+ -+ return NULL; -+} -+ -+static LoongArch_model * -+LoongArchModelFindPrid(LoongArch_map *map, -+ uint32_t prid) -+{ -+ size_t i; -+ size_t j; -+ -+ for (i = 0; i < map->nmodels; i++) { -+ LoongArch_model *model = map->models[i]; -+ for (j = 0; j < model->data.len; j++) { -+ if ((prid & model->data.prid[j].mask) == model->data.prid[j].value) -+ return model; -+ } -+ } -+ -+ return NULL; -+} -+ -+static LoongArch_model * -+LoongArchModelFromCPU(const virCPUDef *cpu, -+ LoongArch_map *map) -+{ -+ LoongArch_model *model; -+ -+ if (!cpu->model) { -+ virReportError(VIR_ERR_INVALID_ARG, "%s", -+ _("no CPU model specified")); -+ return NULL; -+ } -+ -+ if (!(model = LoongArchModelFind(map, cpu->model))) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("Unknown CPU model %s"), cpu->model); -+ return NULL; -+ } -+ -+ return LoongArchModelCopy(model); -+} -+ -+static void -+LoongArchMapFree(LoongArch_map *map) -+{ -+ size_t i; -+ -+ if (!map) -+ return; -+ -+ for (i = 0; i < map->nmodels; i++) -+ LoongArchModelFree(map->models[i]); -+ g_free(map->models); -+ -+ for (i = 0; i < map->nvendors; i++) -+ LoongArchVendorFree(map->vendors[i]); -+ g_free(map->vendors); -+ -+ g_free(map); -+} -+ -+static int -+LoongArchVendorParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, -+ const char *name, -+ void *data) -+{ -+ LoongArch_map *map = data; -+ LoongArch_vendor *vendor; -+ int ret = -1; -+ -+ vendor = g_new0(LoongArch_vendor, 1); -+ vendor->name = g_strdup(name); -+ -+ if (LoongArchVendorFind(map, vendor->name)) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("CPU vendor %s already defined"), vendor->name); -+ goto cleanup; -+ } -+ -+ VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor); -+ ret = 0; -+ -+ cleanup: -+ LoongArchVendorFree(vendor); -+ return ret; -+} -+ -+static int -+LoongArchModelParse(xmlXPathContextPtr ctxt, -+ const char *name, -+ void *data) -+{ -+ LoongArch_map *map = data; -+ LoongArch_model *model; -+ xmlNodePtr *nodes = NULL; -+ char *vendor = NULL; -+ unsigned long prid; -+ size_t i; -+ int n; -+ int ret = -1; -+ -+ model = g_new0(LoongArch_model, 1); -+ model->name = g_strdup(name); -+ -+ if (LoongArchModelFind(map, model->name)) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("CPU model %s already defined"), model->name); -+ goto cleanup; -+ } -+ -+ if (virXPathBoolean("boolean(./vendor)", ctxt)) { -+ vendor = virXPathString("string(./vendor/@name)", ctxt); -+ if (!vendor) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("Invalid vendor element in CPU model %s"), -+ model->name); -+ goto cleanup; -+ } -+ -+ if (!(model->vendor = LoongArchVendorFind(map, vendor))) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("Unknown vendor %s referenced by CPU model %s"), -+ vendor, model->name); -+ goto cleanup; -+ } -+ } -+ -+ if ((n = virXPathNodeSet("./prid", ctxt, &nodes)) <= 0) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("Missing Prid information for CPU model %s"), -+ model->name); -+ goto cleanup; -+ } -+ -+ model->data.prid = g_new0(virCPULoongArchPrid, n); -+ model->data.len = n; -+ -+ for (i = 0; i < n; i++) { -+ ctxt->node = nodes[i]; -+ -+ if (virXPathULongHex("string(./@value)", ctxt, &prid) < 0) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("Missing or invalid Prid value in CPU model %s"), -+ model->name); -+ goto cleanup; -+ } -+ model->data.prid[i].value = prid; -+ -+ if (virXPathULongHex("string(./@mask)", ctxt, &prid) < 0) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("Missing or invalid PVR mask in CPU model %s"), -+ model->name); -+ goto cleanup; -+ } -+ model->data.prid[i].mask = prid; -+ } -+ -+ VIR_APPEND_ELEMENT(map->models, map->nmodels, model); -+ ret = 0; -+ -+ cleanup: -+ LoongArchModelFree(model); -+ g_free(vendor); -+ g_free(nodes); -+ return ret; -+} -+ -+static LoongArch_map * -+LoongArchLoadMap(void) -+{ -+ LoongArch_map *map; -+ -+ map = g_new0(LoongArch_map, 1); -+ if (cpuMapLoad("loongarch64", LoongArchVendorParse, NULL, LoongArchModelParse, map) < 0) -+ goto error; -+ -+ return map; -+ -+ error: -+ LoongArchMapFree(map); -+ return NULL; -+} -+ -+static virCPUData * -+LoongArchMakeCPUData(virArch arch, -+ virCPULoongArchData *data) -+{ -+ virCPUData *cpuData; -+ -+ cpuData = g_new0(virCPUData, 1); -+ cpuData->arch = arch; -+ -+ if (LoongArchDataCopy(&cpuData->data.loongarch, data) < 0) -+ g_free(cpuData); -+ -+ return cpuData; -+} -+ -+static virCPUCompareResult -+LoongArchCompute(virCPUDef *host, -+ const virCPUDef *other, -+ virCPUData *guestData, -+ char **message) -+{ -+ LoongArch_map *map = NULL; -+ LoongArch_model *host_model = NULL; -+ LoongArch_model *guest_model = NULL; -+ virCPUDef *cpu = NULL; -+ virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR; -+ virArch arch; -+ size_t i; -+ -+ /* Ensure existing configurations are handled correctly */ -+ if (!(cpu = virCPUDefCopy(other))) -+ goto cleanup; -+ -+ if (cpu->arch != VIR_ARCH_NONE) { -+ bool found = false; -+ -+ for (i = 0; i < G_N_ELEMENTS(archs); i++) { -+ if (archs[i] == cpu->arch) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) { -+ VIR_DEBUG("CPU arch %s does not match host arch", -+ virArchToString(cpu->arch)); -+ if (message) { -+ *message = g_strdup_printf(_("CPU arch %s does not match host arch"), -+ virArchToString(cpu->arch)); -+ } -+ ret = VIR_CPU_COMPARE_INCOMPATIBLE; -+ goto cleanup; -+ } -+ arch = cpu->arch; -+ } else { -+ arch = host->arch; -+ } -+ -+ if (cpu->vendor && -+ (!host->vendor || STRNEQ(cpu->vendor, host->vendor))) { -+ VIR_DEBUG("host CPU vendor does not match required CPU vendor %s", -+ cpu->vendor); -+ if (message) { -+ *message = g_strdup_printf(_("host CPU vendor does not match required " -+ "CPU vendor %s"), cpu->vendor); -+ } -+ ret = VIR_CPU_COMPARE_INCOMPATIBLE; -+ goto cleanup; -+ } -+ -+ if (!(map = LoongArchLoadMap())) -+ goto cleanup; -+ -+ /* Host CPU information */ -+ if (!(host_model = LoongArchModelFromCPU(host, map))) -+ goto cleanup; -+ -+ if (cpu->type == VIR_CPU_TYPE_GUEST) { -+ /* Guest CPU information */ -+ switch (cpu->mode) { -+ case VIR_CPU_MODE_HOST_MODEL: -+ case VIR_CPU_MODE_HOST_PASSTHROUGH: -+ /* host-model and host-passthrough: -+ * the guest CPU is the same as the host */ -+ guest_model = LoongArchModelCopy(host_model); -+ break; -+ -+ case VIR_CPU_MODE_CUSTOM: -+ /* custom: -+ * look up guest CPU information */ -+ guest_model = LoongArchModelFromCPU(cpu, map); -+ break; -+ } -+ } else { -+ /* Other host CPU information */ -+ guest_model = LoongArchModelFromCPU(cpu, map); -+ } -+ -+ if (!guest_model) -+ goto cleanup; -+ -+ if (STRNEQ(guest_model->name, host_model->name)) { -+ VIR_DEBUG("host CPU model does not match required CPU model %s", -+ guest_model->name); -+ if (message) { -+ *message = g_strdup_printf(_("host CPU model does not match required " -+ "CPU model %s"),guest_model->name); -+ } -+ ret = VIR_CPU_COMPARE_INCOMPATIBLE; -+ goto cleanup; -+ } -+ -+ if (guestData) -+ if (!(guestData = LoongArchMakeCPUData(arch, &guest_model->data))) -+ goto cleanup; -+ -+ ret = VIR_CPU_COMPARE_IDENTICAL; -+ -+ cleanup: -+ virCPUDefFree(cpu); -+ LoongArchMapFree(map); -+ LoongArchModelFree(host_model); -+ LoongArchModelFree(guest_model); -+ return ret; -+} -+ -+static virCPUCompareResult -+virCPULoongArchCompare(virCPUDef *host, -+ virCPUDef *cpu, -+ bool failIncompatible) -+{ -+ virCPUCompareResult ret; -+ char *message = NULL; -+ -+ if (!host || !host->model) { -+ if (failIncompatible) { -+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", -+ _("unknown host CPU")); -+ } else { -+ VIR_WARN("unknown host CPU"); -+ ret = VIR_CPU_COMPARE_INCOMPATIBLE; -+ } -+ return -1; -+ } -+ -+ ret = LoongArchCompute(host, cpu, NULL, &message); -+ -+ if (failIncompatible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) { -+ ret = VIR_CPU_COMPARE_ERROR; -+ if (message) { -+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", message); -+ } else { -+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL); -+ } -+ } -+ g_free(message); -+ -+ return ret; -+} -+ -+static int -+LoongArchDriverDecode(virCPUDef *cpu, -+ const virCPUData *data, -+ virDomainCapsCPUModels *models) -+{ -+ int ret = -1; -+ LoongArch_map *map; -+ LoongArch_model *model; -+ -+ if (!data || !(map = LoongArchLoadMap())) -+ return -1; -+ -+ if (!(model = LoongArchModelFindPrid(map, data->data.loongarch.prid[0].value))) { -+ virReportError(VIR_ERR_OPERATION_FAILED, -+ _("Cannot find CPU model with Prid 0x%08x"), -+ data->data.loongarch.prid[0].value); -+ goto cleanup; -+ } -+ -+ if (!virCPUModelIsAllowed(model->name, models)) { -+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, -+ _("CPU model %s is not supported by hypervisor"), -+ model->name); -+ goto cleanup; -+ } -+ -+ cpu->model = g_strdup(model->name); -+ if (model->vendor) { -+ cpu->vendor = g_strdup(model->vendor->name); -+ } -+ ret = 0; -+ -+ cleanup: -+ LoongArchMapFree(map); -+ -+ return ret; -+} -+ -+static void -+virCPULoongArchDataFree(virCPUData *data) -+{ -+ if (!data) -+ return; -+ -+ LoongArchDataClear(&data->data.loongarch); -+ g_free(data); -+} -+ -+static int virCPULoongArchGetHostPRID(void) -+{ -+ return 0x14c010; -+} -+ -+static int -+virCPULoongArchGetHost(virCPUDef *cpu, -+ virDomainCapsCPUModels *models) -+{ -+ virCPUData *cpuData = NULL; -+ virCPULoongArchData *data; -+ int ret = -1; -+ -+ if (!(cpuData = virCPUDataNew(archs[0]))) -+ goto cleanup; -+ -+ data = &cpuData->data.loongarch; -+ -+ data->prid = g_new0(virCPULoongArchPrid, 1); -+ data->len = 1; -+ -+ data->prid[0].value = virCPULoongArchGetHostPRID(); -+ data->prid[0].mask = 0xffff00ul; -+ -+ ret = LoongArchDriverDecode(cpu, cpuData, models); -+ -+ cleanup: -+ virCPULoongArchDataFree(cpuData); -+ return ret; -+} -+ -+ -+static int -+virCPULoongArchUpdate(virCPUDef *guest, -+ const virCPUDef *host, -+ bool relative) -+{ -+ /* -+ * - host-passthrough doesn't even get here -+ * - host-model is used for host CPU running in a compatibility mode and -+ * it needs to remain unchanged -+ * - custom doesn't support any optional features, there's nothing to -+ * update -+ */ -+ VIR_DEBUG("host model %s, if relatived %d",host->model, relative); -+ if (guest->mode == VIR_CPU_MODE_CUSTOM) -+ guest->match = VIR_CPU_MATCH_EXACT; -+ -+ return 0; -+} -+ -+static virCPUDef * -+LoongArchDriverBaseline(virCPUDef **cpus, -+ unsigned int ncpus, -+ virDomainCapsCPUModels *models, -+ const char **features, -+ bool migratable) -+{ -+ LoongArch_map *map; -+ LoongArch_model *model; -+ LoongArch_vendor *vendor = NULL; -+ virCPUDef *cpu = NULL; -+ size_t i; -+ if (models && *features) { -+ VIR_DEBUG("migratable %d features %s",migratable, *features); -+ } -+ if (!(map = LoongArchLoadMap())) -+ goto error; -+ -+ if (!(model = LoongArchModelFind(map, cpus[0]->model))) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("Unknown CPU model %s"), cpus[0]->model); -+ goto error; -+ } -+ -+ for (i = 0; i < ncpus; i++) { -+ LoongArch_vendor *vnd; -+ -+ if (STRNEQ(cpus[i]->model, model->name)) { -+ virReportError(VIR_ERR_OPERATION_FAILED, "%s", -+ _("CPUs are incompatible")); -+ goto error; -+ } -+ -+ if (!cpus[i]->vendor) -+ continue; -+ -+ if (!(vnd = LoongArchVendorFind(map, cpus[i]->vendor))) { -+ virReportError(VIR_ERR_OPERATION_FAILED, -+ _("Unknown CPU vendor %s"), cpus[i]->vendor); -+ goto error; -+ } -+ -+ if (model->vendor) { -+ if (model->vendor != vnd) { -+ virReportError(VIR_ERR_OPERATION_FAILED, -+ _("CPU vendor %s of model %s differs from " -+ "vendor %s"), -+ model->vendor->name, model->name, -+ vnd->name); -+ goto error; -+ } -+ } else if (vendor) { -+ if (vendor != vnd) { -+ virReportError(VIR_ERR_OPERATION_FAILED, "%s", -+ _("CPU vendors do not match")); -+ goto error; -+ } -+ } else { -+ vendor = vnd; -+ } -+ } -+ -+ cpu = g_new0(virCPUDef ,1); -+ cpu->model = g_strdup(model->name); -+ if (vendor) { -+ cpu->vendor = g_strdup(vendor->name); -+ } -+ cpu->type = VIR_CPU_TYPE_GUEST; -+ cpu->match = VIR_CPU_MATCH_EXACT; -+ cpu->fallback = VIR_CPU_FALLBACK_FORBID; -+ -+ cleanup: -+ LoongArchMapFree(map); -+ -+ return cpu; -+ -+ error: -+ virCPUDefFree(cpu); -+ cpu = NULL; -+ goto cleanup; -+} -+ -+static int -+virCPULoongArchDriverGetModels(char ***models) -+{ -+ LoongArch_map *map; -+ size_t i; -+ int ret = -1; -+ -+ if (!(map = LoongArchLoadMap())) -+ goto error; -+ -+ if (models) { -+ *models = g_new0(char *, map->nmodels + 1); -+ for (i = 0; i < map->nmodels; i++) { -+ (*models)[i] = g_strdup(map->models[i]->name); -+ } -+ } -+ -+ ret = map->nmodels; -+ -+ cleanup: -+ LoongArchMapFree(map); -+ return ret; -+ -+ error: -+ if (models) { -+ g_strfreev(*models); -+ *models = NULL; -+ } -+ goto cleanup; -+} -+ -+struct cpuArchDriver cpuDriverLoongArch = { -+ .name = "LoongArch", -+ .arch = archs, -+ .narch = G_N_ELEMENTS(archs), -+ .compare = virCPULoongArchCompare, -+ .decode = LoongArchDriverDecode, -+ .encode = NULL, -+ .dataFree = virCPULoongArchDataFree, -+ .getHost = virCPULoongArchGetHost, -+ .baseline = LoongArchDriverBaseline, -+ .update = virCPULoongArchUpdate, -+ .getModels = virCPULoongArchDriverGetModels, -+}; -diff --git a/src/cpu/cpu_loongarch.h b/src/cpu/cpu_loongarch.h -new file mode 100644 -index 0000000000..1fde3b5162 ---- /dev/null -+++ b/src/cpu/cpu_loongarch.h -@@ -0,0 +1,28 @@ -+/* -+ * cpu_loongarch.h: CPU driver for 64-bit LOONGARCH CPUs -+ * -+ * Copyright (C) Copyright (C) IBM Corporation, 2010 -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library. If not, see -+ * . -+ */ -+ -+#ifndef __VIR_CPU_LOONGARCH_H__ -+# define __VIR_CPU_LOONGARCH_H__ -+ -+# include "cpu.h" -+ -+extern struct cpuArchDriver cpuDriverLoongArch; -+ -+#endif /* __VIR_CPU_LOONGARCH_H__ */ -diff --git a/src/cpu/cpu_loongarch_data.h b/src/cpu/cpu_loongarch_data.h -new file mode 100644 -index 0000000000..1a759e7d16 ---- /dev/null -+++ b/src/cpu/cpu_loongarch_data.h -@@ -0,0 +1,40 @@ -+/* -+ * cpu_loongarch_data.h: 64-bit LOONGARCH CPU specific data -+ * -+ * Copyright (C) 2012 IBM Corporation. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; If not, see -+ * . -+ */ -+ -+#ifndef __VIR_CPU_LOONGARCH_DATA_H__ -+# define __VIR_CPU_LOONGARCH_DATA_H__ -+ -+# include -+ -+typedef struct _virCPULoongArchPrid virCPULoongArchPrid; -+struct _virCPULoongArchPrid { -+ uint32_t value; -+ uint32_t mask; -+}; -+ -+# define VIR_CPU_LOONGARCH_DATA_INIT { 0 } -+ -+typedef struct _virCPULoongArchData virCPULoongArchData; -+struct _virCPULoongArchData { -+ size_t len; -+ virCPULoongArchPrid *prid; -+}; -+ -+#endif /* __VIR_CPU_MIPS64_DATA_H__ */ -diff --git a/src/cpu/meson.build b/src/cpu/meson.build -index b4ad95e46d..ad2f859fd8 100644 ---- a/src/cpu/meson.build -+++ b/src/cpu/meson.build -@@ -5,6 +5,7 @@ cpu_sources = [ - 'cpu_ppc64.c', - 'cpu_s390.c', - 'cpu_x86.c', -+ 'cpu_loongarch.c', - ] - - cpu_lib = static_library( -diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml -index ffe1fa91e5..d302de396a 100644 ---- a/src/cpu_map/index.xml -+++ b/src/cpu_map/index.xml -@@ -110,4 +110,9 @@ - - - -+ -+ -+ -+ -+ - -diff --git a/src/cpu_map/loongarch_vendors.xml b/src/cpu_map/loongarch_vendors.xml -new file mode 100644 -index 0000000000..c744654617 ---- /dev/null -+++ b/src/cpu_map/loongarch_vendors.xml -@@ -0,0 +1,3 @@ -+ -+ -+ -diff --git a/src/cpu_map/ls_3a5000.xml b/src/cpu_map/ls_3a5000.xml -new file mode 100644 -index 0000000000..f6fe3386f7 ---- /dev/null -+++ b/src/cpu_map/ls_3a5000.xml -@@ -0,0 +1,6 @@ -+ -+ -+ -+ -+ -+ -diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build -index 013fc62a02..9657c5164e 100644 ---- a/src/cpu_map/meson.build -+++ b/src/cpu_map/meson.build -@@ -77,6 +77,8 @@ cpumap_data = [ - 'x86_vendors.xml', - 'x86_Westmere-IBRS.xml', - 'x86_Westmere.xml', -+ 'loongarch_vendors.xml', -+ 'ls_3a5000.xml', - ] - - install_data(cpumap_data, install_dir: pkgdatadir / 'cpu_map') -diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c -index c4f7db55c8..75668c6451 100644 ---- a/src/qemu/qemu_capabilities.c -+++ b/src/qemu/qemu_capabilities.c -@@ -2073,6 +2073,9 @@ bool virQEMUCapsHasPCIMultiBus(const virDomainDef *def) - if (ARCH_IS_X86(def->os.arch)) - return true; - -+ if (STRPREFIX(def->os.machine,"loongson7a")) -+ return true; -+ - /* PPC supports multibus on all machine types which have pci since qemu-2.0.0 */ - if (def->os.arch == VIR_ARCH_PPC || - ARCH_IS_PPC64(def->os.arch)) { -@@ -2690,6 +2693,7 @@ static const char *preferredMachines[] = - - "malta", /* VIR_ARCH_MIPS64 */ - "malta", /* VIR_ARCH_MIPS64EL */ -+ "loongson7a", /* VIR_ARCH_LOONGARCH64 */ - "or1k-sim", /* VIR_ARCH_OR32 */ - NULL, /* VIR_ARCH_PARISC (no QEMU impl) */ - NULL, /* VIR_ARCH_PARISC64 (no QEMU impl) */ -@@ -5115,6 +5119,7 @@ virQEMUCapsInitQMPBasicArch(virQEMUCaps *qemuCaps) - case VIR_ARCH_MIPSEL: - case VIR_ARCH_MIPS64: - case VIR_ARCH_MIPS64EL: -+ case VIR_ARCH_LOONGARCH64: - case VIR_ARCH_OR32: - case VIR_ARCH_PARISC: - case VIR_ARCH_PARISC64: -diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c -index a0b8076d6b..8cd03261ac 100644 ---- a/src/qemu/qemu_conf.c -+++ b/src/qemu/qemu_conf.c -@@ -101,7 +101,9 @@ qemuDriverUnlock(virQEMUDriver *driver) - "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd:" \ - "/usr/share/OVMF/OVMF_CODE.secboot.fd:/usr/share/OVMF/OVMF_VARS.fd:" \ - "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd:" \ -- "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd" -+ "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd:" \ -+ "/usr/share/qemu-kvm/loongarch_bios.bin:/usr/share/qemu-kvm/loongarch_bios.bin" -+ - #endif - - -diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c -index 40fe9985e6..814d8cb67d 100644 ---- a/src/qemu/qemu_domain.c -+++ b/src/qemu/qemu_domain.c -@@ -3668,6 +3668,10 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver, - addPCIeRoot = virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_GPEX); - break; - -+ case VIR_ARCH_LOONGARCH64: -+ addPCIeRoot = true; -+ break; -+ - case VIR_ARCH_PPC64: - case VIR_ARCH_PPC64LE: - addPCIRoot = true; -@@ -5065,6 +5069,11 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont, - cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; - else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) - cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; -+ } else if (ARCH_IS_LOONGARCH(def->os.arch)) { -+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI)) -+ cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; -+ else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) -+ cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; - } - } - /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */ -@@ -8324,6 +8333,13 @@ qemuDomainDefCheckABIStability(virQEMUDriver *driver, - } - - -+bool -+qemuDomainIsLoongson(const virDomainDef *def) -+{ -+ return (STRPREFIX(def->os.machine,"loongson3a") || STRPREFIX(def->os.machine,"loongson7a")); -+} -+ -+ - bool - qemuDomainCheckABIStability(virQEMUDriver *driver, - virDomainObj *vm, -@@ -8664,7 +8680,9 @@ qemuDomainMachineHasBuiltinIDE(const char *machine, - return qemuDomainMachineIsI440FX(machine, arch) || - STREQ(machine, "malta") || - STREQ(machine, "sun4u") || -- STREQ(machine, "g3beige"); -+ STREQ(machine, "g3beige") || -+ STREQ(machine, "loongson3a") || -+ STREQ(machine, "loongson7a"); - } - - -diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h -index e5046367e3..57f1f97348 100644 ---- a/src/qemu/qemu_domain.h -+++ b/src/qemu/qemu_domain.h -@@ -770,6 +770,7 @@ bool qemuDomainIsS390CCW(const virDomainDef *def); - bool qemuDomainIsARMVirt(const virDomainDef *def); - bool qemuDomainIsRISCVVirt(const virDomainDef *def); - bool qemuDomainIsPSeries(const virDomainDef *def); -+bool qemuDomainIsLoongson(const virDomainDef *def); - bool qemuDomainHasPCIRoot(const virDomainDef *def); - bool qemuDomainHasPCIeRoot(const virDomainDef *def); - bool qemuDomainHasBuiltinIDE(const virDomainDef *def); -diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c -index 18fc34d049..c3fac1c33b 100644 ---- a/src/qemu/qemu_domain_address.c -+++ b/src/qemu/qemu_domain_address.c -@@ -2026,6 +2026,59 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDef *def, - } - - -+static int -+qemuDomainValidateDevicePCISlotsLoongson(virDomainDef *def, -+ virDomainPCIAddressSet *addrs) -+{ -+ int ret = -1; -+ virPCIDeviceAddress tmp_addr; -+ char *addrStr = NULL; -+ virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_AUTOASSIGN -+ | VIR_PCI_CONNECT_TYPE_PCI_DEVICE); -+ -+ if (addrs->nbuses) { -+ memset(&tmp_addr, 0, sizeof(tmp_addr)); -+ tmp_addr.slot = 1; -+ /* pci-ohci at 00:01.0 */ -+ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) -+ goto cleanup; -+ } -+ -+ if (def->nvideos > 0 && -+ def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_NONE && -+ def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_RAMFB) { -+ /*reserve slot 2 for vga device */ -+ virDomainVideoDef *primaryVideo = def->videos[0]; -+ -+ if (virDeviceInfoPCIAddressIsWanted(&primaryVideo->info)) { -+ memset(&tmp_addr, 0, sizeof(tmp_addr)); -+ tmp_addr.slot = 2; -+ -+ if (!(addrStr = virPCIDeviceAddressAsString(&tmp_addr))) -+ goto cleanup; -+ if (!virDomainPCIAddressValidate(addrs, &tmp_addr, -+ addrStr, flags, true)) -+ goto cleanup; -+ -+ if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { -+ if (qemuDomainPCIAddressReserveNextAddr(addrs, -+ &primaryVideo->info) < 0) -+ goto cleanup; -+ } else { -+ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) -+ goto cleanup; -+ primaryVideo->info.addr.pci = tmp_addr; -+ primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; -+ } -+ } -+ } -+ ret = 0; -+ cleanup: -+ VIR_FREE(addrStr); -+ return ret; -+} -+ -+ - static int - qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def, - virDomainPCIAddressSet *addrs) -@@ -2040,6 +2093,11 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def, - return -1; - } - -+ if (qemuDomainIsLoongson(def) && -+ qemuDomainValidateDevicePCISlotsLoongson(def, addrs) < 0) { -+ return -1; -+ } -+ - return 0; - } - -diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c -index 7bc14293d6..7d01d31aaf 100644 ---- a/src/qemu/qemu_validate.c -+++ b/src/qemu/qemu_validate.c -@@ -186,7 +186,8 @@ qemuValidateDomainDefFeatures(const virDomainDef *def, - switch ((virDomainFeature) i) { - case VIR_DOMAIN_FEATURE_IOAPIC: - if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) { -- if (!ARCH_IS_X86(def->os.arch)) { -+ if (!(ARCH_IS_X86(def->os.arch) -+ || ARCH_IS_LOONGARCH(def->os.arch))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("The '%s' feature is not supported for " - "architecture '%s' or machine type '%s'"), -diff --git a/src/util/virarch.c b/src/util/virarch.c -index 2134dd6a9d..9f40a7110c 100644 ---- a/src/util/virarch.c -+++ b/src/util/virarch.c -@@ -59,6 +59,7 @@ static const struct virArchData { - - { "mips64", 64, VIR_ARCH_BIG_ENDIAN }, - { "mips64el", 64, VIR_ARCH_LITTLE_ENDIAN }, -+ { "loongarch64", 64, VIR_ARCH_LITTLE_ENDIAN }, - { "openrisc", 32, VIR_ARCH_BIG_ENDIAN }, - { "parisc", 32, VIR_ARCH_BIG_ENDIAN }, - { "parisc64", 64, VIR_ARCH_BIG_ENDIAN }, -@@ -222,6 +223,8 @@ virArch virArchFromHost(void) - arch = VIR_ARCH_X86_64; - } else if (STREQ(ut.machine, "arm64")) { - arch = VIR_ARCH_AARCH64; -+ } else if (STREQ(ut.machine, "loongarch64")) { -+ arch = VIR_ARCH_LOONGARCH64; - } else { - /* Otherwise assume the canonical name */ - if ((arch = virArchFromString(ut.machine)) == VIR_ARCH_NONE) { -diff --git a/src/util/virarch.h b/src/util/virarch.h -index 528f84f8a5..7d396f2fff 100644 ---- a/src/util/virarch.h -+++ b/src/util/virarch.h -@@ -44,6 +44,7 @@ typedef enum { - - VIR_ARCH_MIPS64, /* MIPS 64 BE https://en.wikipedia.org/wiki/MIPS_architecture */ - VIR_ARCH_MIPS64EL, /* MIPS 64 LE https://en.wikipedia.org/wiki/MIPS_architecture */ -+ VIR_ARCH_LOONGARCH64, - VIR_ARCH_OR32, /* OpenRisc 32 BE https://en.wikipedia.org/wiki/OpenRISC#QEMU_support */ - VIR_ARCH_PARISC, /* PA-Risc 32 BE https://en.wikipedia.org/wiki/PA-RISC */ - VIR_ARCH_PARISC64, /* PA-Risc 64 BE https://en.wikipedia.org/wiki/PA-RISC */ -@@ -98,6 +99,8 @@ typedef enum { - #define ARCH_IS_MIPS64(arch) ((arch) == VIR_ARCH_MIPS64 ||\ - (arch) == VIR_ARCH_MIPS64EL) - -+#define ARCH_IS_LOONGARCH(arch) ((arch) == VIR_ARCH_LOONGARCH64) -+ - typedef enum { - VIR_ARCH_LITTLE_ENDIAN, - VIR_ARCH_BIG_ENDIAN, -diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c -index 35f41daef2..137796ea07 100644 ---- a/src/util/virhostcpu.c -+++ b/src/util/virhostcpu.c -@@ -546,7 +546,7 @@ virHostCPUParseFrequency(FILE *cpuinfo, - char line[1024]; - - /* No sensible way to retrieve CPU frequency */ -- if (ARCH_IS_ARM(arch)) -+ if (ARCH_IS_ARM(arch) || ARCH_IS_LOONGARCH(arch)) - return 0; - - if (ARCH_IS_X86(arch)) -diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c -index af9e03c5ac..9577cf1910 100644 ---- a/src/util/virsysinfo.c -+++ b/src/util/virsysinfo.c -@@ -1247,7 +1247,7 @@ virSysinfoRead(void) - { - #if defined(__powerpc__) - return virSysinfoReadPPC(); --#elif defined(__arm__) || defined(__aarch64__) -+#elif defined(__arm__) || defined(__aarch64__) || defined(__loongarch__) - return virSysinfoReadARM(); - #elif defined(__s390__) || defined(__s390x__) - return virSysinfoReadS390(); --- -2.27.0 - diff --git a/libvirt-Add-sw64-architecture-support-for-libvirt.patch b/libvirt-Add-sw64-architecture-support-for-libvirt.patch deleted file mode 100644 index 7654027..0000000 --- a/libvirt-Add-sw64-architecture-support-for-libvirt.patch +++ /dev/null @@ -1,687 +0,0 @@ -From 6053366caf3573323e1436fc7c3e4e13d26fd3c2 Mon Sep 17 00:00:00 2001 -From: Chen Wang -Date: Wed, 25 May 2022 09:42:04 +0800 -Subject: [PATCH] sw_64: Add sw64 architecture support for libvirt-8.0.0 - -Signed-off-by: Chen Wang ---- - docs/schemas/basictypes.rng | 1 + - docs/schemas/domaincommon.rng | 1 + - meson.build | 2 +- - src/cpu/cpu.c | 2 + - src/cpu/cpu_sw64.c | 302 ++++++++++++++++++++++++++++++++++ - src/cpu/cpu_sw64.h | 31 ++++ - src/cpu/meson.build | 1 + - src/cpu_map/index.xml | 5 + - src/cpu_map/meson.build | 2 + - src/cpu_map/sw64_core3.xml | 4 + - src/cpu_map/sw64_core4.xml | 4 + - src/qemu/qemu_capabilities.c | 12 ++ - src/qemu/qemu_domain.c | 15 +- - src/util/virarch.c | 6 + - src/util/virarch.h | 3 + - src/util/virhostcpu.c | 2 + - src/util/virprocess.c | 2 + - src/util/virsysinfo.c | 3 +- - 18 files changed, 393 insertions(+), 5 deletions(-) - create mode 100644 src/cpu/cpu_sw64.c - create mode 100644 src/cpu/cpu_sw64.h - create mode 100644 src/cpu_map/sw64_core3.xml - create mode 100644 src/cpu_map/sw64_core4.xml - -diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng -index ab18b18..e0724fe 100644 ---- a/docs/schemas/basictypes.rng -+++ b/docs/schemas/basictypes.rng -@@ -460,6 +460,7 @@ - sh4eb - sparc - sparc64 -+ sw_64 - unicore32 - x86_64 - xtensa -diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng -index 79c8979..c2bd970 100644 ---- a/docs/schemas/domaincommon.rng -+++ b/docs/schemas/domaincommon.rng -@@ -2613,6 +2613,7 @@ - pcie-pci-bridge - - ioh3420 -+ pcie-root - pcie-root-port - - x3130-upstream -diff --git a/meson.build b/meson.build -index 214a3f0..e76cf4e 100644 ---- a/meson.build -+++ b/meson.build -@@ -1596,7 +1596,7 @@ elif get_option('driver_lxc').enabled() - error('linux and remote_driver are required for LXC') - endif - --if not get_option('driver_ch').disabled() and host_machine.system() == 'linux' and (host_machine.cpu_family() == 'x86_64' or host_machine.cpu_family() == 'aarch64') -+if not get_option('driver_ch').disabled() and host_machine.system() == 'linux' and (host_machine.cpu_family() == 'x86_64' or host_machine.cpu_family() == 'aarch64' or host_machine.cpu_family() == 'sw_64') - use_ch = true - - if not conf.has('WITH_LIBVIRTD') -diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c -index 49527c3..d11bcc9 100644 ---- a/src/cpu/cpu.c -+++ b/src/cpu/cpu.c -@@ -29,6 +29,7 @@ - #include "cpu_ppc64.h" - #include "cpu_s390.h" - #include "cpu_arm.h" -+#include "cpu_sw64.h" - #include "capabilities.h" - #include "virstring.h" - #include "cpu_loongarch.h" -@@ -43,6 +44,7 @@ static struct cpuArchDriver *drivers[] = { - &cpuDriverS390, - &cpuDriverArm, - &cpuDriverLoongArch, -+ &cpuDriverSW64, - }; - - -diff --git a/src/cpu/cpu_sw64.c b/src/cpu/cpu_sw64.c -new file mode 100644 -index 0000000..199ed60 ---- /dev/null -+++ b/src/cpu/cpu_sw64.c -@@ -0,0 +1,302 @@ -+/* -+ * cpu_sw64.c: CPU driver for sw64 CPUs -+ * -+ * Copyright (C) 2021 Lu Feifei -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library. If not, see -+ * . -+ * -+ * Authors: -+ * Lu Feifei -+ */ -+ -+#include -+ -+#include "virfile.h" -+#include "viralloc.h" -+#include "cpu.h" -+#include "cpu_sw64.h" -+#include "cpu_map.h" -+#include "virstring.h" -+#include "virhostcpu.h" -+ -+#define VIR_FROM_THIS VIR_FROM_CPU -+#define CPUINFO_PATH "/proc/cpuinfo" -+ -+static const virArch archs[] = { VIR_ARCH_SW_64 }; -+ -+typedef struct _sw64Model sw64Model; -+struct _sw64Model { -+ char *name; -+}; -+ -+typedef struct _sw64Map sw64Map; -+struct _sw64Map { -+ size_t nmodels; -+ sw64Model **models; -+}; -+ -+static virCPUCompareResult -+virCPUsw64Compare(virCPUDef *host ATTRIBUTE_UNUSED, -+ virCPUDef *cpu ATTRIBUTE_UNUSED, -+ bool failMessages ATTRIBUTE_UNUSED) -+{ -+ return VIR_CPU_COMPARE_IDENTICAL; -+} -+ -+static int -+virCPUsw64Update(virCPUDef *guest, -+ const virCPUDef *host, -+ bool relative) -+{ -+ g_autoptr(virCPUDef) updated = NULL; -+ -+ if (!relative || guest->mode != VIR_CPU_MODE_HOST_MODEL) -+ return 0; -+ -+ if (!host) { -+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", -+ _("unknown host CPU model")); -+ return -1; -+ } -+ -+ if (!(updated = virCPUDefCopyWithoutModel(guest))) -+ return -1; -+ -+ updated->mode = VIR_CPU_MODE_CUSTOM; -+ if (virCPUDefCopyModel(updated, host, true) < 0) -+ return -1; -+ -+ virCPUDefStealModel(guest, updated, false); -+ guest->mode = VIR_CPU_MODE_CUSTOM; -+ guest->match = VIR_CPU_MATCH_EXACT; -+ -+ return 0; -+} -+ -+static void -+sw64ModelFree(sw64Model *model) -+{ -+ if (!model) -+ return; -+ -+ VIR_FREE(model->name); -+ VIR_FREE(model); -+} -+ -+static void -+sw64MapFree(sw64Map *map) -+{ -+ size_t i; -+ -+ if (!map) -+ return; -+ -+ for (i = 0; i < map->nmodels; i++) -+ sw64ModelFree(map->models[i]); -+ VIR_FREE(map->models); -+ VIR_FREE(map); -+} -+ -+static sw64Model * -+sw64ModelFind(const sw64Map *map, -+ const char *name) -+{ -+ size_t i; -+ -+ for (i = 0; i < map->nmodels; i++) { -+ if (STREQ(map->models[i]->name, name)) -+ return map->models[i]; -+ } -+ -+ return NULL; -+} -+ -+static int -+sw64ModelParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, -+ const char *name, -+ void *data) -+{ -+ sw64Map *map = data; -+ sw64Model *model; -+ int ret = -1; -+ -+ model = g_new0(sw64Model, 1); -+ -+ model->name = g_strdup(name); -+ -+ if (sw64ModelFind(map, model->name)) { -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("CPU model %s already defined"), model->name); -+ goto cleanup; -+ } -+ -+ VIR_APPEND_ELEMENT(map->models, map->nmodels, model); -+ -+ ret = 0; -+ -+ cleanup: -+ sw64ModelFree(model); -+ return ret; -+} -+ -+static sw64Map * -+sw64LoadMap(void) -+{ -+ sw64Map *map; -+ -+ map = g_new0(sw64Map, 1); -+ -+ if (cpuMapLoad("sw64", NULL, NULL, sw64ModelParse, map) < 0) -+ goto error; -+ -+ return map; -+ -+ error: -+ sw64MapFree(map); -+ return NULL; -+} -+ -+static int -+sw64CPUParseCpuModeString(const char *str, -+ const char *prefix, -+ unsigned int *mode) -+{ -+ char *p; -+ unsigned int ui; -+ /* If the string doesn't start with the expected prefix, then -+ * we're not looking at the right string and we should move on */ -+ if (!STRPREFIX(str, prefix)) -+ return 1; -+ /* Skip the prefix */ -+ str += strlen(prefix); -+ -+ /* Skip all whitespace */ -+ while (g_ascii_isspace(*str)) -+ str++; -+ if (*str == '\0') -+ goto error; -+ -+ /* Skip the colon. If anything but a colon is found, then we're -+ * not looking at the right string and we should move on */ -+ if (*str != ':') -+ return 1; -+ str++; -+ -+ /* Skip all whitespace */ -+ while (g_ascii_isspace(*str)) -+ str++; -+ if (*str == '\0') -+ goto error; -+ -+ if (virStrToLong_ui(str, &p, 10, &ui) < 0 || -+ (*p != '.' && *p != '\0' && !g_ascii_isspace(*p))) { -+ goto error; -+ } -+ -+ *mode = ui; -+ return 0; -+ -+ error: -+ virReportError(VIR_ERR_INTERNAL_ERROR, -+ _("Missing or invalid CPU variation in %s"), -+ CPUINFO_PATH); -+ return -1; -+} -+ -+static int -+sw64CPUParseCpuMode(FILE *cpuinfo, unsigned int *mode) -+{ -+ const char *prefix = "cpu variation"; -+ char line[1024]; -+ -+ while (fgets(line, sizeof(line), cpuinfo) != NULL) { -+ if (sw64CPUParseCpuModeString(line, prefix, mode) < 0) -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int -+virCPUsw64GetHost(virCPUDef *cpu, -+ virDomainCapsCPUModels *models ATTRIBUTE_UNUSED) -+{ -+ int ret = -1; -+ unsigned int mode; -+ FILE *cpuinfo = fopen(CPUINFO_PATH, "r"); -+ if (!cpuinfo) { -+ virReportSystemError(errno, -+ _("cannot open %s"), CPUINFO_PATH); -+ return -1; -+ } -+ -+ ret = sw64CPUParseCpuMode(cpuinfo, &mode); -+ if (ret < 0) -+ goto cleanup; -+ -+ if (mode == 3) -+ cpu->model = g_strdup("core3"); -+ else if (mode == 4) -+ cpu->model = g_strdup("core4"); -+ -+ cleanup: -+ VIR_FORCE_FCLOSE(cpuinfo); -+ return ret; -+} -+ -+static int -+virCPUsw64DriverGetModels(char ***models) -+{ -+ sw64Map *map; -+ size_t i; -+ int ret = -1; -+ -+ if (!(map = sw64LoadMap())) -+ goto error; -+ -+ if (models) { -+ *models = g_new0(char *, map->nmodels + 1); -+ -+ for (i = 0; i < map->nmodels; i++) { -+ (*models)[i] = g_strdup(map->models[i]->name); -+ } -+ } -+ -+ ret = map->nmodels; -+ -+ cleanup: -+ sw64MapFree(map); -+ return ret; -+ -+ error: -+ if (models) { -+ g_strfreev(*models); -+ *models = NULL; -+ } -+ goto cleanup; -+} -+ -+struct cpuArchDriver cpuDriverSW64 = { -+ .name = "sw_64", -+ .arch = archs, -+ .narch = G_N_ELEMENTS(archs), -+ .getHost = virCPUsw64GetHost, -+ .compare = virCPUsw64Compare, -+ .decode = NULL, -+ .encode = NULL, -+ .baseline = NULL, -+ .update = virCPUsw64Update, -+ .getModels = virCPUsw64DriverGetModels, -+}; -diff --git a/src/cpu/cpu_sw64.h b/src/cpu/cpu_sw64.h -new file mode 100644 -index 0000000..211a7cf ---- /dev/null -+++ b/src/cpu/cpu_sw64.h -@@ -0,0 +1,31 @@ -+/* -+ * cpu_sw64.h: CPU driver for sw64 CPUs -+ * -+ * Copyright (C) 2021 Lu Feifei -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library. If not, see -+ * . -+ * -+ * Authors: -+ * Lu Feifei -+ */ -+ -+#ifndef __VIR_CPU_SW64_H__ -+# define __VIR_CPU_SW64_H__ -+ -+# include "cpu.h" -+ -+extern struct cpuArchDriver cpuDriverSW64; -+ -+#endif /* __VIR_CPU_SW64_H__ */ -diff --git a/src/cpu/meson.build b/src/cpu/meson.build -index ad2f859..5e99dbd 100644 ---- a/src/cpu/meson.build -+++ b/src/cpu/meson.build -@@ -1,6 +1,7 @@ - cpu_sources = [ - 'cpu.c', - 'cpu_arm.c', -+ 'cpu_sw64.c', - 'cpu_map.c', - 'cpu_ppc64.c', - 'cpu_s390.c', -diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml -index 3ae9348..5d1a999 100644 ---- a/src/cpu_map/index.xml -+++ b/src/cpu_map/index.xml -@@ -113,6 +113,11 @@ - - - -+ -+ -+ -+ -+ - - - -diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build -index baeffa3..3871f09 100644 ---- a/src/cpu_map/meson.build -+++ b/src/cpu_map/meson.build -@@ -79,6 +79,8 @@ cpumap_data = [ - 'x86_vendors.xml', - 'x86_Westmere-IBRS.xml', - 'x86_Westmere.xml', -+ 'sw64_core3.xml', -+ 'sw64_core4.xml', - 'loongarch_vendors.xml', - 'ls_3a5000.xml', - ] -diff --git a/src/cpu_map/sw64_core3.xml b/src/cpu_map/sw64_core3.xml -new file mode 100644 -index 0000000..ec3fa0e ---- /dev/null -+++ b/src/cpu_map/sw64_core3.xml -@@ -0,0 +1,4 @@ -+ -+ -+ -+ -diff --git a/src/cpu_map/sw64_core4.xml b/src/cpu_map/sw64_core4.xml -new file mode 100644 -index 0000000..11e763b ---- /dev/null -+++ b/src/cpu_map/sw64_core4.xml -@@ -0,0 +1,4 @@ -+ -+ -+ -+ -diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c -index 75668c6..ca47a7a 100644 ---- a/src/qemu/qemu_capabilities.c -+++ b/src/qemu/qemu_capabilities.c -@@ -771,6 +771,8 @@ virArch virQEMUCapsArchFromString(const char *arch) - return VIR_ARCH_ARMV7L; - if (STREQ(arch, "or32")) - return VIR_ARCH_OR32; -+ if (STREQ(arch, "sw64")) -+ return VIR_ARCH_SW_64; - - return virArchFromString(arch); - } -@@ -784,6 +786,8 @@ const char *virQEMUCapsArchToString(virArch arch) - return "arm"; - if (arch == VIR_ARCH_OR32) - return "or32"; -+ if (arch == VIR_ARCH_SW_64) -+ return "sw64"; - - return virArchToString(arch); - } -@@ -2072,6 +2076,10 @@ bool virQEMUCapsHasPCIMultiBus(const virDomainDef *def) - * since forever */ - if (ARCH_IS_X86(def->os.arch)) - return true; -+ /* sw_64 support PCI-multibus on all machine types -+ * since forever */ -+ if (ARCH_IS_SW64(def->os.arch)) -+ return true; - - if (STRPREFIX(def->os.machine,"loongson7a")) - return true; -@@ -2718,6 +2726,8 @@ static const char *preferredMachines[] = - - "sim", /* VIR_ARCH_XTENSA */ - "sim", /* VIR_ARCH_XTENSAEB */ -+ -+ "core3", /* VIR_ARCH_SW_64 */ - }; - G_STATIC_ASSERT(G_N_ELEMENTS(preferredMachines) == VIR_ARCH_LAST); - -@@ -5129,6 +5139,8 @@ virQEMUCapsInitQMPBasicArch(virQEMUCaps *qemuCaps) - case VIR_ARCH_XTENSAEB: - case VIR_ARCH_NONE: - case VIR_ARCH_LAST: -+ case VIR_ARCH_SW_64: -+ - default: - break; - } -diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c -index 7a53b93..f32fdcb 100644 ---- a/src/qemu/qemu_domain.c -+++ b/src/qemu/qemu_domain.c -@@ -3740,6 +3740,10 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver, - addPCIRoot = true; - break; - -+ case VIR_ARCH_SW_64: -+ addPCIeRoot = true; -+ break; -+ - case VIR_ARCH_ARMV7B: - case VIR_ARCH_CRIS: - case VIR_ARCH_ITANIUM: -@@ -5099,7 +5103,10 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont, - cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; - else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) - cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; -- } -+ } else if (def->os.arch == VIR_ARCH_SW_64) { -+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI)) -+ cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; -+ } - } - /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */ - if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1 || -@@ -5396,7 +5403,8 @@ qemuDomainDefaultVideoDevice(const virDomainDef *def, - return VIR_DOMAIN_VIDEO_TYPE_VGA; - if (qemuDomainIsARMVirt(def) || - qemuDomainIsRISCVVirt(def) || -- ARCH_IS_S390(def->os.arch)) { -+ ARCH_IS_S390(def->os.arch) || -+ ARCH_IS_SW64(def->os.arch)) { - return VIR_DOMAIN_VIDEO_TYPE_VIRTIO; - } - if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA)) -@@ -8705,7 +8713,8 @@ qemuDomainMachineHasBuiltinIDE(const char *machine, - return qemuDomainMachineIsI440FX(machine, arch) || - STREQ(machine, "malta") || - STREQ(machine, "sun4u") || -- STREQ(machine, "g3beige") || -+ STRPREFIX(machine, "core") || -+ STREQ(machine, "g3beige") || - STREQ(machine, "loongson3a") || - STREQ(machine, "loongson7a"); - } -diff --git a/src/util/virarch.c b/src/util/virarch.c -index 9f40a71..ce149a4 100644 ---- a/src/util/virarch.c -+++ b/src/util/virarch.c -@@ -84,6 +84,8 @@ static const struct virArchData { - - { "xtensa", 32, VIR_ARCH_LITTLE_ENDIAN }, - { "xtensaeb", 32, VIR_ARCH_BIG_ENDIAN }, -+ -+ { "sw_64", 64, VIR_ARCH_LITTLE_ENDIAN }, - }; - - G_STATIC_ASSERT(G_N_ELEMENTS(virArchData) == VIR_ARCH_LAST); -@@ -197,6 +199,8 @@ virArch virArchFromHost(void) - return VIR_ARCH_ARMV7L; - case PROCESSOR_ARCHITECTURE_ARM64: - return VIR_ARCH_AARCH64; -+ case PROCESSOR_ARCHITECTURE_SW64: -+ return VIR_ARCH_SW_64; - default: - VIR_WARN("Unknown host arch '%d', report to libvir-list@redhat.com", - info.wProcessorArchitecture); -@@ -221,6 +225,8 @@ virArch virArchFromHost(void) - arch = VIR_ARCH_I686; - } else if (STREQ(ut.machine, "amd64")) { - arch = VIR_ARCH_X86_64; -+ } else if (STREQ(ut.machine, "sw_64")) { -+ arch = VIR_ARCH_SW_64; - } else if (STREQ(ut.machine, "arm64")) { - arch = VIR_ARCH_AARCH64; - } else if (STREQ(ut.machine, "loongarch64")) { -diff --git a/src/util/virarch.h b/src/util/virarch.h -index 7d396f2..2e4f7c9 100644 ---- a/src/util/virarch.h -+++ b/src/util/virarch.h -@@ -70,6 +70,8 @@ typedef enum { - VIR_ARCH_XTENSA, /* XTensa 32 LE https://en.wikipedia.org/wiki/Xtensa#Processor_Cores */ - VIR_ARCH_XTENSAEB, /* XTensa 32 BE https://en.wikipedia.org/wiki/Xtensa#Processor_Cores */ - -+ VIR_ARCH_SW_64, /* SW_64 64 LE XHB */ -+ - VIR_ARCH_LAST, - } virArch; - -@@ -98,6 +100,7 @@ typedef enum { - - #define ARCH_IS_MIPS64(arch) ((arch) == VIR_ARCH_MIPS64 ||\ - (arch) == VIR_ARCH_MIPS64EL) -+#define ARCH_IS_SW64(arch) ((arch) == VIR_ARCH_SW_64) - - #define ARCH_IS_LOONGARCH(arch) ((arch) == VIR_ARCH_LOONGARCH64) - -diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c -index 137796e..2572229 100644 ---- a/src/util/virhostcpu.c -+++ b/src/util/virhostcpu.c -@@ -555,6 +555,8 @@ virHostCPUParseFrequency(FILE *cpuinfo, - prefix = "clock"; - else if (ARCH_IS_S390(arch)) - prefix = "cpu MHz dynamic"; -+ else if (ARCH_IS_SW64(arch)) -+ prefix = "cpu frequency [MHz]"; - - if (!prefix) { - VIR_WARN("%s is not supported by the %s parser", -diff --git a/src/util/virprocess.c b/src/util/virprocess.c -index f3933a2..04095e0 100644 ---- a/src/util/virprocess.c -+++ b/src/util/virprocess.c -@@ -89,6 +89,8 @@ VIR_LOG_INIT("util.process"); - # define __NR_setns 350 - # elif defined(__s390__) - # define __NR_setns 339 -+# elif defined(__sw_64__) -+# define __NR_setns 501 - # endif - # endif - -diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c -index 9577cf1..4cdbf32 100644 ---- a/src/util/virsysinfo.c -+++ b/src/util/virsysinfo.c -@@ -1254,7 +1254,8 @@ virSysinfoRead(void) - #elif !defined(WIN32) && \ - (defined(__x86_64__) || \ - defined(__i386__) || \ -- defined(__amd64__)) -+ defined(__amd64__) || \ -+ defined(__sw_64__)) - return virSysinfoReadDMI(); - #else /* WIN32 || not supported arch */ - /* --- -2.17.1 - diff --git a/libvirt-add-loongarch-edit-xml-validate.patch b/libvirt-add-loongarch-edit-xml-validate.patch deleted file mode 100644 index 7dba7ec..0000000 --- a/libvirt-add-loongarch-edit-xml-validate.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 6391d1634db6319d852c65c4e384030dcf568103 Mon Sep 17 00:00:00 2001 -From: zhaotianrui -Date: Wed, 13 Oct 2021 15:51:40 +0800 -Subject: [PATCH] Fix loongarch xml validate - -Signed-off-by: zhaotianrui ---- - -diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng -index 8146527..b58a61a 100644 ---- a/docs/schemas/basictypes.rng -+++ b/docs/schemas/basictypes.rng -@@ -425,6 +425,7 @@ - mipsel - mips64 - mips64el -+ loongarch64 - openrisc - parisc - parisc64 diff --git a/libvirt-conf-add-deprecated_features-attribute.patch b/libvirt-conf-add-deprecated_features-attribute.patch new file mode 100644 index 0000000..2dfeedc --- /dev/null +++ b/libvirt-conf-add-deprecated_features-attribute.patch @@ -0,0 +1,135 @@ +From 7a412cc71a4764f7e80bf475c39d999a584f41aa Mon Sep 17 00:00:00 2001 +Message-ID: <7a412cc71a4764f7e80bf475c39d999a584f41aa.1749113304.git.jdenemar@redhat.com> +From: Collin Walling +Date: Mon, 16 Dec 2024 18:03:58 -0500 +Subject: [PATCH] conf: add deprecated_features attribute + +Add a new a attribute, deprecated_features='on|off' to the +element. This is used to toggle features flagged as deprecated on the +CPU model on or off. When this attribute is paired with 'on', +deprecated features will not be filtered. When paired with 'off', any +CPU features that are flagged as deprecated will be listed under the +CPU model with the 'disable' policy. + +Example: + + + +The absence of this attribute is equivalent to the 'on' option. + +The deprecated features that will populate the domain XML are the same +features that result in the virsh domcapabilities command with the +--disable-deprecated-features argument present. + +It is recommended to define a domain XML with this attribute set to +'off' to ensure migration to machines that may outright drop these +features in the future. + +Signed-off-by: Collin Walling +Reviewed-by: Jiri Denemark +(cherry picked from commit 62658bbf060784c757f96c9de3935f27885834aa) + +JIRA: https://issues.redhat.com/browse/RHEL-88716 +Conflicts: + src/qemu/qemu_process.c + (contextual conflict) + tests/* + (dropped the changes to these files since they are of no use in + downstream - upstream testing code changed too much, so it's + not possible to get the related tests to work in downstream) +Signed-off-by: Thomas Huth +--- + docs/schemas/cputypes.rng | 5 +++++ + src/conf/cpu_conf.c | 11 +++++++++++ + src/conf/cpu_conf.h | 1 + + src/qemu/qemu_process.c | 11 +++++++++++ + 4 files changed, 28 insertions(+) + +diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng +index 056e66e1b4..2d831b423c 100644 +--- a/docs/schemas/cputypes.rng ++++ b/docs/schemas/cputypes.rng +@@ -395,6 +395,11 @@ + + + ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c +index fbceac1657..1db0c978e2 100644 +--- a/src/conf/cpu_conf.c ++++ b/src/conf/cpu_conf.c +@@ -238,6 +238,7 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu) + copy->mode = cpu->mode; + copy->match = cpu->match; + copy->check = cpu->check; ++ copy->deprecated_feats = cpu->deprecated_feats; + copy->fallback = cpu->fallback; + copy->sockets = cpu->sockets; + copy->dies = cpu->dies; +@@ -431,6 +432,11 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, + if (virXMLPropEnum(ctxt->node, "check", virCPUCheckTypeFromString, + VIR_XML_PROP_NONE, &def->check) < 0) + return -1; ++ ++ if (virXMLPropTristateSwitch(ctxt->node, "deprecated_features", ++ VIR_XML_PROP_NONE, ++ &def->deprecated_feats) < 0) ++ return -1; + } + + if (def->type == VIR_CPU_TYPE_HOST) { +@@ -707,6 +713,11 @@ virCPUDefFormatBufFull(virBuffer *buf, + virBufferAsprintf(&attributeBuf, " migratable='%s'", + virTristateSwitchTypeToString(def->migratable)); + } ++ ++ if (def->deprecated_feats) { ++ virBufferAsprintf(&attributeBuf, " deprecated_features='%s'", ++ virTristateSwitchTypeToString(def->deprecated_feats)); ++ } + } + + /* Format children */ +diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h +index b0a81895be..a69ff724ca 100644 +--- a/src/conf/cpu_conf.h ++++ b/src/conf/cpu_conf.h +@@ -140,6 +140,7 @@ struct _virCPUDef { + virCPUCacheDef *cache; + virHostCPUTscInfo *tsc; + virTristateSwitch migratable; /* for host-passthrough mode */ ++ virTristateSwitch deprecated_feats; + }; + + virCPUDef *virCPUDefNew(void); +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 73d54f01cd..54afcbe53e 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -6143,6 +6143,17 @@ qemuProcessUpdateGuestCPU(virDomainDef *def, + return -1; + } + ++ if (def->cpu->deprecated_feats && ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("toggling deprecated features for CPU model is unsupported")); ++ return -1; ++ } ++ ++ if (def->cpu->deprecated_feats == VIR_TRISTATE_SWITCH_OFF) { ++ virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, def->virtType, def->cpu); ++ } ++ + return 0; + } + +-- +2.49.0 diff --git a/libvirt-cpu-Add-new-Dharma-CPU-model.patch b/libvirt-cpu-Add-new-Dharma-CPU-model.patch deleted file mode 100644 index 39c6176..0000000 --- a/libvirt-cpu-Add-new-Dharma-CPU-model.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 654e5425700bcc5ece7a414061a504283ae24727 Mon Sep 17 00:00:00 2001 -From: Yanjing Zhou -Date: Tue, 11 Jun 2024 16:00:14 +0800 -Subject: [PATCH] cpu: Add new Dharma CPU model - -Add Hygon Dharma CPU model to the processor model. - -Signed-off-by: Yanjing Zhou ---- - src/cpu_map/index.xml | 1 + - src/cpu_map/meson.build | 1 + - src/cpu_map/x86_Dharma.xml | 83 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 85 insertions(+) - create mode 100644 src/cpu_map/x86_Dharma.xml - -diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml -index ffe1fa9..9419674 100644 ---- a/src/cpu_map/index.xml -+++ b/src/cpu_map/index.xml -@@ -72,6 +72,7 @@ - - - -+ - - - -diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build -index 013fc62..c2a7052 100644 ---- a/src/cpu_map/meson.build -+++ b/src/cpu_map/meson.build -@@ -31,6 +31,7 @@ cpumap_data = [ - 'x86_coreduo.xml', - 'x86_cpu64-rhel5.xml', - 'x86_cpu64-rhel6.xml', -+ 'x86_Dharma.xml', - 'x86_Dhyana.xml', - 'x86_EPYC-IBPB.xml', - 'x86_EPYC.xml', -diff --git a/src/cpu_map/x86_Dharma.xml b/src/cpu_map/x86_Dharma.xml -new file mode 100644 -index 0000000..bf20116 ---- /dev/null -+++ b/src/cpu_map/x86_Dharma.xml -@@ -0,0 +1,83 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ --- -2.39.3 - diff --git a/libvirt-cpu-map-add-S5000C-cpu-model.patch b/libvirt-cpu-map-add-S5000C-cpu-model.patch deleted file mode 100644 index 73c051a..0000000 --- a/libvirt-cpu-map-add-S5000C-cpu-model.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0b896a38e152b7350d9f685ec898ff9ff0f86ebe Mon Sep 17 00:00:00 2001 -From: Peng Mengguang -Date: Thu, 12 Sep 2024 10:57:23 -0400 -Subject: [PATCH] cpu_map: add S5000C cpu model - - add Phytium S5000C cpu model. - -Signed-off-by: Peng Mengguang ---- - src/cpu_map/arm_Tengyun-S5000C.xml | 6 ++++++ - src/cpu_map/index.xml | 1 + - src/cpu_map/meson.build | 1 + - 3 files changed, 8 insertions(+) - create mode 100644 src/cpu_map/arm_Tengyun-S5000C.xml - -diff --git a/src/cpu_map/arm_Tengyun-S5000C.xml b/src/cpu_map/arm_Tengyun-S5000C.xml -new file mode 100644 -index 0000000000..f8fa593c19 ---- /dev/null -+++ b/src/cpu_map/arm_Tengyun-S5000C.xml -@@ -0,0 +1,6 @@ -+ -+ -+ -+ -+ -+ -diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml -index 150535fac4..3ae9348bc5 100644 ---- a/src/cpu_map/index.xml -+++ b/src/cpu_map/index.xml -@@ -110,6 +110,7 @@ - - - -+ - - - -diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build -index 42d2105f2a..baeffa3b70 100644 ---- a/src/cpu_map/meson.build -+++ b/src/cpu_map/meson.build -@@ -7,6 +7,7 @@ cpumap_data = [ - 'arm_features.xml', - 'arm_Kunpeng-920.xml', - 'arm_Tengyun-S2500.xml', -+ 'arm_Tengyun-S5000C.xml', - 'arm_ThunderX299xx.xml', - 'arm_vendors.xml', - 'index.xml', --- -2.39.3 - diff --git a/libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES.patch b/libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES.patch new file mode 100644 index 0000000..adfac4d --- /dev/null +++ b/libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES.patch @@ -0,0 +1,58 @@ +From a47232facc446039ed509100f80ebb7de621fffa Mon Sep 17 00:00:00 2001 +Message-ID: +From: Collin Walling +Date: Mon, 16 Dec 2024 18:03:55 -0500 +Subject: [PATCH] libvirt-domain: introduce + VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES + +Introduce domain flag used to filter deprecated features from the +domain's CPU model. + +Signed-off-by: Collin Walling +Reviewed-by: Jiri Denemark +(cherry picked from commit 4e2c8de2047e21d98443944a2bfe94529b269efa) +JIRA: https://issues.redhat.com/browse/RHEL-88716 +Signed-off-by: Thomas Huth +--- + include/libvirt/libvirt-domain.h | 12 ++++++++++++ + src/libvirt-domain.c | 2 +- + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index 792973ce2d..d3101b112b 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -1160,6 +1160,18 @@ int virDomainMigrateGetMaxSpeed(virDomainPtr domain, + int virDomainMigrateStartPostCopy(virDomainPtr domain, + unsigned int flags); + ++/** ++ * virConnectGetDomainCapabilitiesFlags: ++ * ++ * Domain capabilities flags. ++ * ++ * Since: 11.0.0 ++ */ ++typedef enum { ++ /* Report host model with deprecated features disabled. (Since: 11.0.0) */ ++ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES = (1 << 0), ++} virConnectGetDomainCapabilitiesFlags; ++ + char * virConnectGetDomainCapabilities(virConnectPtr conn, + const char *emulatorbin, + const char *arch, +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index 5912551a49..7083f10f04 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -11573,7 +11573,7 @@ virDomainSetUserPassword(virDomainPtr dom, + * @arch: domain architecture + * @machine: machine type + * @virttype: virtualization type +- * @flags: extra flags; not used yet, so callers should always pass 0 ++ * @flags: extra flags; bitwise-OR of virConnectGetDomainCapabilitiesFlags + * + * Prior creating a domain (for instance via virDomainCreateXML + * or virDomainDefineXML) it may be suitable to know what the +-- +2.49.0 diff --git a/libvirt-qemu-parse-deprecated-props-from-query-cpu-model-expansion-response.patch b/libvirt-qemu-parse-deprecated-props-from-query-cpu-model-expansion-response.patch new file mode 100644 index 0000000..110f618 --- /dev/null +++ b/libvirt-qemu-parse-deprecated-props-from-query-cpu-model-expansion-response.patch @@ -0,0 +1,214 @@ +From 5289208127468cd34b5cb6ea7bb45bbeff45d537 Mon Sep 17 00:00:00 2001 +Message-ID: <5289208127468cd34b5cb6ea7bb45bbeff45d537.1749113303.git.jdenemar@redhat.com> +From: Collin Walling +Date: Mon, 16 Dec 2024 18:03:53 -0500 +Subject: [PATCH] qemu: parse deprecated-props from query-cpu-model-expansion + response + +query-cpu-model-expansion may report an array of deprecated properties. +This array is optional, and may not be supported for a particular +architecture or reported for a particular CPU model. If the output is +present, then capture it and store in a qemuMonitorCPUModelInfo struct +for later use. + +The deprecated features will be retained in qemuCaps->kvm->hostCPU.info +and will be stored in the capabilities cache file under the +element using the following format: + + + + + + + + +At this time the data is only queried, parsed, and cached. The data +will be utilized in a subsequent patch. + +Signed-off-by: Collin Walling +Reviewed-by: Boris Fiuczynski +Reviewed-by: Jiri Denemark +(cherry picked from commit 45140d293007c1b29f7563bf6ee9640e27769b96) + +JIRA: https://issues.redhat.com/browse/RHEL-88716 +Conflicts: + tests/qemucapabilitiesdata/caps_9.1.0.s390x.xml + tests/qemucapabilitiesdata/caps_9.2.0.s390x.xml + (dropped the changes to these files since they are of no use in + downstream - upstream testing code changed too much, so it's + not possible to get the related tests to work in downstream) +Signed-off-by: Thomas Huth +--- + src/qemu/qemu_capabilities.c | 31 +++++++++++++++++++++++++++++++ + src/qemu/qemu_monitor.c | 3 +++ + src/qemu/qemu_monitor.h | 1 + + src/qemu/qemu_monitor_json.c | 18 ++++++++++++++++++ + 4 files changed, 53 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index c4f7db55c8..d616273406 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -3766,6 +3766,7 @@ virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsAccel *caps, + { + g_autofree char *migratability = NULL; + xmlNodePtr hostCPUNode; ++ xmlNodePtr deprecated_props; + g_autofree xmlNodePtr *nodes = NULL; + VIR_XPATH_NODE_AUTORESTORE(ctxt) + g_autoptr(qemuMonitorCPUModelInfo) hostCPU = NULL; +@@ -3870,6 +3871,24 @@ virQEMUCapsLoadHostCPUModelInfo(virQEMUCapsAccel *caps, + } + } + ++ ctxt->node = hostCPUNode; ++ ++ if ((deprecated_props = virXPathNode("./deprecatedFeatures", ctxt))) { ++ g_autoptr(GPtrArray) props = virXMLNodeGetSubelementList(deprecated_props, NULL); ++ ++ hostCPU->deprecated_props = g_new0(char *, props->len + 1); ++ ++ for (i = 0; i < props->len; i++) { ++ xmlNodePtr prop = g_ptr_array_index(props, i); ++ ++ if (!(hostCPU->deprecated_props[i] = virXMLPropString(prop, "name"))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("missing 'name' attribute for a host CPU model deprecated property in QEMU capabilities cache")); ++ return -1; ++ } ++ } ++ } ++ + caps->hostCPU.info = g_steal_pointer(&hostCPU); + return 0; + } +@@ -4500,6 +4519,18 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsAccel *caps, + virBufferAddLit(buf, "/>\n"); + } + ++ if (model->deprecated_props) { ++ virBufferAddLit(buf, "\n"); ++ virBufferAdjustIndent(buf, 2); ++ ++ for (i = 0; i < g_strv_length(model->deprecated_props); i++) ++ virBufferAsprintf(buf, "\n", ++ model->deprecated_props[i]); ++ ++ virBufferAdjustIndent(buf, -2); ++ virBufferAddLit(buf, "\n"); ++ } ++ + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + } +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 99667fdf2f..8f72fc5bd9 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -3487,6 +3487,7 @@ qemuMonitorCPUModelInfoFree(qemuMonitorCPUModelInfo *model_info) + g_free(model_info->props[i].value.string); + } + ++ g_strfreev(model_info->deprecated_props); + g_free(model_info->props); + g_free(model_info->name); + g_free(model_info); +@@ -3531,6 +3532,8 @@ qemuMonitorCPUModelInfoCopy(const qemuMonitorCPUModelInfo *orig) + } + } + ++ copy->deprecated_props = g_strdupv(orig->deprecated_props); ++ + return copy; + } + +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index d00967d84f..5b9ea336ec 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -1238,6 +1238,7 @@ struct _qemuMonitorCPUModelInfo { + char *name; + size_t nprops; + qemuMonitorCPUProperty *props; ++ GStrv deprecated_props; + bool migratability; + }; + +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 487f8028d9..9a3ca3d186 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -5500,6 +5500,7 @@ qemuMonitorJSONParseCPUModelExpansionData(virJSONValue *data, + bool fail_no_props, + virJSONValue **cpu_model, + virJSONValue **cpu_props, ++ virJSONValue **cpu_deprecated_props, + const char **cpu_name) + { + if (qemuMonitorJSONParseCPUModelData(data, "query-cpu-model-expansion", +@@ -5507,6 +5508,12 @@ qemuMonitorJSONParseCPUModelExpansionData(virJSONValue *data, + cpu_name) < 0) + return -1; + ++ /* ++ * Unconditionally check for the deprecated-props array, as ++ * it is not a guarantee response even if QEMU supports it. ++ */ ++ *cpu_deprecated_props = virJSONValueObjectGetArray(data, "deprecated-props"); ++ + return 0; + } + +@@ -5514,6 +5521,7 @@ qemuMonitorJSONParseCPUModelExpansionData(virJSONValue *data, + static int + qemuMonitorJSONParseCPUModelExpansion(const char *cpu_name, + virJSONValue *cpu_props, ++ virJSONValue *cpu_deprecated_props, + qemuMonitorCPUModelInfo **model_info) + { + g_autoptr(qemuMonitorCPUModelInfo) expanded_model = NULL; +@@ -5521,6 +5529,12 @@ qemuMonitorJSONParseCPUModelExpansion(const char *cpu_name, + if (qemuMonitorJSONParseCPUModel(cpu_name, cpu_props, &expanded_model) < 0) + return -1; + ++ if (cpu_deprecated_props && ++ virJSONValueArraySize(cpu_deprecated_props) && ++ (!(expanded_model->deprecated_props = virJSONValueArrayToStringList(cpu_deprecated_props)))) { ++ return -1; ++ } ++ + *model_info = g_steal_pointer(&expanded_model); + return 0; + } +@@ -5584,6 +5598,7 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitor *mon, + g_autoptr(virJSONValue) fullData = NULL; + virJSONValue *cpu_model; + virJSONValue *cpu_props = NULL; ++ virJSONValue *cpu_deprecated_props = NULL; + const char *cpu_name = ""; + int rc; + +@@ -5597,6 +5612,7 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitor *mon, + + if (qemuMonitorJSONParseCPUModelExpansionData(data, fail_no_props, + &cpu_model, &cpu_props, ++ &cpu_deprecated_props, + &cpu_name) < 0) + return -1; + +@@ -5615,11 +5631,13 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitor *mon, + + if (qemuMonitorJSONParseCPUModelExpansionData(fullData, fail_no_props, + &cpu_model, &cpu_props, ++ &cpu_deprecated_props, + &cpu_name) < 0) + return -1; + } + + return qemuMonitorJSONParseCPUModelExpansion(cpu_name, cpu_props, ++ cpu_deprecated_props, + model_info); + } + +-- +2.49.0 diff --git a/libvirt-qemuMonitorJSONGetCPUModelExpansion-refactor-parsing-functions.patch b/libvirt-qemuMonitorJSONGetCPUModelExpansion-refactor-parsing-functions.patch new file mode 100644 index 0000000..f98c144 --- /dev/null +++ b/libvirt-qemuMonitorJSONGetCPUModelExpansion-refactor-parsing-functions.patch @@ -0,0 +1,100 @@ +From ed03cdb563ee30bff2f4f8a66f7778b5e55a4683 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Collin Walling +Date: Mon, 16 Dec 2024 18:03:52 -0500 +Subject: [PATCH] qemuMonitorJSONGetCPUModelExpansion: refactor parsing + functions + +Refactor the CPU Model parsing functions within +qemuMonitorJSONGetCPUModelExpansion. The new functions, +qemuMonitorJSONParseCPUModelExpansionData and +qemuMonitorJSONParseCPUModelExpansion invoke the functions they +replace and leave room for a subsequent patch to handle parsing the +(optional) deprecated_props field resulting from the command. + +Signed-off-by: Collin Walling +Reviewed-by: Boris Fiuczynski +Reviewed-by: Jiri Denemark +(cherry picked from commit 60e407deb5cd88e5f1564d1c9145e374001cf34f) +JIRA: https://issues.redhat.com/browse/RHEL-88716 +Signed-off-by: Thomas Huth +--- + src/qemu/qemu_monitor_json.c | 46 ++++++++++++++++++++++++++++++------ + 1 file changed, 39 insertions(+), 7 deletions(-) + +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 789554e225..487f8028d9 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -5495,6 +5495,37 @@ qemuMonitorJSONParseCPUModel(const char *cpu_name, + } + + ++static int ++qemuMonitorJSONParseCPUModelExpansionData(virJSONValue *data, ++ bool fail_no_props, ++ virJSONValue **cpu_model, ++ virJSONValue **cpu_props, ++ const char **cpu_name) ++{ ++ if (qemuMonitorJSONParseCPUModelData(data, "query-cpu-model-expansion", ++ fail_no_props, cpu_model, cpu_props, ++ cpu_name) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++ ++static int ++qemuMonitorJSONParseCPUModelExpansion(const char *cpu_name, ++ virJSONValue *cpu_props, ++ qemuMonitorCPUModelInfo **model_info) ++{ ++ g_autoptr(qemuMonitorCPUModelInfo) expanded_model = NULL; ++ ++ if (qemuMonitorJSONParseCPUModel(cpu_name, cpu_props, &expanded_model) < 0) ++ return -1; ++ ++ *model_info = g_steal_pointer(&expanded_model); ++ return 0; ++} ++ ++ + static int + qemuMonitorJSONQueryCPUModelExpansionOne(qemuMonitor *mon, + qemuMonitorCPUModelExpansionType type, +@@ -5564,9 +5595,9 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitor *mon, + if ((rc = qemuMonitorJSONQueryCPUModelExpansionOne(mon, type, &model, &data)) <= 0) + return rc; + +- if (qemuMonitorJSONParseCPUModelData(data, "query-cpu-model-expansion", +- fail_no_props, &cpu_model, &cpu_props, +- &cpu_name) < 0) ++ if (qemuMonitorJSONParseCPUModelExpansionData(data, fail_no_props, ++ &cpu_model, &cpu_props, ++ &cpu_name) < 0) + return -1; + + /* QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC_FULL requests "full" expansion +@@ -5582,13 +5613,14 @@ qemuMonitorJSONGetCPUModelExpansion(qemuMonitor *mon, + if ((rc = qemuMonitorJSONQueryCPUModelExpansionOne(mon, type, &fullModel, &fullData)) <= 0) + return rc; + +- if (qemuMonitorJSONParseCPUModelData(fullData, "query-cpu-model-expansion", +- fail_no_props, &cpu_model, &cpu_props, +- &cpu_name) < 0) ++ if (qemuMonitorJSONParseCPUModelExpansionData(fullData, fail_no_props, ++ &cpu_model, &cpu_props, ++ &cpu_name) < 0) + return -1; + } + +- return qemuMonitorJSONParseCPUModel(cpu_name, cpu_props, model_info); ++ return qemuMonitorJSONParseCPUModelExpansion(cpu_name, cpu_props, ++ model_info); + } + + +-- +2.49.0 diff --git a/libvirt-qemu_capabilities-filter-deprecated-features-if-requested.patch b/libvirt-qemu_capabilities-filter-deprecated-features-if-requested.patch new file mode 100644 index 0000000..f2168f1 --- /dev/null +++ b/libvirt-qemu_capabilities-filter-deprecated-features-if-requested.patch @@ -0,0 +1,95 @@ +From 59ec9c201e8849f7231557c6019e1fabd0893240 Mon Sep 17 00:00:00 2001 +Message-ID: <59ec9c201e8849f7231557c6019e1fabd0893240.1749113303.git.jdenemar@redhat.com> +From: Collin Walling +Date: Mon, 16 Dec 2024 18:03:56 -0500 +Subject: [PATCH] qemu_capabilities: filter deprecated features if requested + +If flag VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES +is passed to qemuConnectGetDomainCapabilities, then the domain's CPU +model features will be updated to set any deprecated features to the +'disabled' policy. + +Signed-off-by: Collin Walling +Reviewed-by: Jiri Denemark +(cherry picked from commit cd1e837c22182dcadfe17b469c931f9fc9745a46) +JIRA: https://issues.redhat.com/browse/RHEL-88716 +Signed-off-by: Thomas Huth +--- + src/qemu/qemu_capabilities.c | 20 ++++++++++++++++++++ + src/qemu/qemu_capabilities.h | 3 +++ + src/qemu/qemu_driver.c | 8 +++++++- + 3 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 98773d2a0a..389b43ab3d 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -3152,6 +3152,26 @@ virQEMUCapsGetCPUFeatures(virQEMUCaps *qemuCaps, + } + + ++void ++virQEMUCapsUpdateCPUDeprecatedFeatures(virQEMUCaps *qemuCaps, ++ virDomainVirtType virtType, ++ virCPUDef *cpu) ++{ ++ qemuMonitorCPUModelInfo *modelInfo; ++ size_t i; ++ ++ modelInfo = virQEMUCapsGetCPUModelInfo(qemuCaps, virtType); ++ ++ if (!modelInfo || !modelInfo->deprecated_props) ++ return; ++ ++ for (i = 0; i < g_strv_length(modelInfo->deprecated_props); i++) { ++ virCPUDefUpdateFeature(cpu, modelInfo->deprecated_props[i], ++ VIR_CPU_FEATURE_DISABLE); ++ } ++} ++ ++ + struct tpmTypeToCaps { + int type; + virQEMUCapsFlags caps; +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 4a7fb2c726..249adf66fa 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -702,6 +702,9 @@ int virQEMUCapsGetCPUFeatures(virQEMUCaps *qemuCaps, + virDomainVirtType virtType, + bool migratable, + char ***features); ++void virQEMUCapsUpdateCPUDeprecatedFeatures(virQEMUCaps *qemuCaps, ++ virDomainVirtType virtType, ++ virCPUDef *cpu); + + virDomainVirtType virQEMUCapsGetVirtType(virQEMUCaps *qemuCaps); + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index d3d76c003f..315abe57b0 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -17383,7 +17383,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, + virDomainVirtType virttype; + g_autoptr(virDomainCaps) domCaps = NULL; + +- virCheckFlags(0, NULL); ++ virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES, ++ NULL); + + if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0) + return NULL; +@@ -17402,6 +17403,11 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, + arch, virttype))) + return NULL; + ++ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES) { ++ virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, virttype, ++ domCaps->cpu.hostModel); ++ } ++ + return virDomainCapsFormat(domCaps); + } + +-- +2.49.0 diff --git a/libvirt-qemu_capabilities-query-deprecated-features-for-host-model.patch b/libvirt-qemu_capabilities-query-deprecated-features-for-host-model.patch new file mode 100644 index 0000000..79cc5cd --- /dev/null +++ b/libvirt-qemu_capabilities-query-deprecated-features-for-host-model.patch @@ -0,0 +1,128 @@ +From 4ad452d843406b9bb8423a47987f4180d565f11a Mon Sep 17 00:00:00 2001 +Message-ID: <4ad452d843406b9bb8423a47987f4180d565f11a.1749113303.git.jdenemar@redhat.com> +From: Collin Walling +Date: Mon, 16 Dec 2024 18:03:54 -0500 +Subject: [PATCH] qemu_capabilities: query deprecated features for host-model + +Add QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS for detecting +if query-cpu-model-expansion can report deprecated CPU model properties. +QEMU introduced this capability in 9.1 release. Add flag and deprecated +features to the capabilities test data for QEMU 9.1 and 9.2 replies/XML +since it can now be accounted for. + +When probing for the host CPU, perform a full CPU model expansion to +retrieve the list of features deprecated across the entire architecture. +The list and count are stored in the host's CPU model info within the +QEMU capabilities. Other info resulting from this query (e.g. model +name, etc) is ignored. + +The new capabilities flag is used to fence off the extra query for +architectures/QEMU binaries that do not report deprecated CPU model +features. + +Signed-off-by: Collin Walling +Reviewed-by: Boris Fiuczynski +Reviewed-by: Jiri Denemark +(cherry picked from commit 51c098347d7f2af9b4386ac0adc4431997d06f3d) + +JIRA: https://issues.redhat.com/browse/RHEL-88716 +Conflicts: + src/qemu/qemu_capabilities.c + src/qemu/qemu_capabilities.h + (Contextual conflicts due to missing other patches in downstream + and qemuMonitorGetCPUModelExpansion() having one parameter less + in downstream) + tests/qemucapabilitiesdata/caps_9.* + (dropped the changes to these files since they are of no use in + downstream - upstream testing code changed too much, so it's + not possible to get the related tests to work in downstream) +Signed-off-by: Thomas Huth +--- + src/qemu/qemu_capabilities.c | 38 ++++++++++++++++++++++++++++++++++++ + src/qemu/qemu_capabilities.h | 1 + + 2 files changed, 39 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index d616273406..98773d2a0a 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -658,6 +658,7 @@ VIR_ENUM_IMPL(virQEMUCaps, + /* 420 */ + "blockdev-reopen.__com.redhat_rhel-av-8_2_0-api", /* QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API */ + "memory-backend-file.prealloc-threads", /* QEMU_CAPS_MEMORY_BACKEND_PREALLOC_THREADS */ ++ "query-cpu-model-expansion.deprecated-props", /* QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS */ + ); + + +@@ -1579,6 +1580,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = { + { "screendump/arg-type/device", QEMU_CAPS_SCREENDUMP_DEVICE }, + { "set-numa-node/arg-type/+hmat-lb", QEMU_CAPS_NUMA_HMAT }, + { "object-add/arg-type/+sev-guest/kernel-hashes", QEMU_CAPS_SEV_GUEST_KERNEL_HASHES }, ++ { "query-cpu-model-expansion/ret-type/deprecated-props", QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS }, + }; + + typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps; +@@ -2982,6 +2984,38 @@ virQEMUCapsProbeCPUDefinitionsTest(virQEMUCaps *qemuCaps, + } + + ++/** ++ * virQEMUCapsProbeFullDeprecatedProperties ++ * @mon: QEMU monitor ++ * @cpu: CPU definition to be expanded ++ * @props: the array to be filled with deprecated features ++ * ++ * Performs a full CPU model expansion to retrieve an array of deprecated ++ * properties. If the expansion succeeds, then data previously stored in ++ * @props is freed. ++ * ++ * Returns: -1 if the expansion failed; otherwise 0. ++ */ ++static int ++virQEMUCapsProbeFullDeprecatedProperties(qemuMonitor *mon, ++ virCPUDef *cpu, ++ GStrv *props) ++{ ++ g_autoptr(qemuMonitorCPUModelInfo) propsInfo = NULL; ++ ++ if (qemuMonitorGetCPUModelExpansion(mon, QEMU_MONITOR_CPU_MODEL_EXPANSION_FULL, ++ cpu, true, false, &propsInfo) < 0) ++ return -1; ++ ++ if (propsInfo && propsInfo->deprecated_props) { ++ g_free(*props); ++ *props = g_steal_pointer(&propsInfo->deprecated_props); ++ } ++ ++ return 0; ++} ++ ++ + static int + virQEMUCapsProbeQMPHostCPU(virQEMUCaps *qemuCaps, + virQEMUCapsAccel *accel, +@@ -3065,6 +3099,10 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCaps *qemuCaps, + modelInfo->migratability = true; + } + ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS) && ++ virQEMUCapsProbeFullDeprecatedProperties(mon, cpu, &modelInfo->deprecated_props) < 0) ++ return -1; ++ + accel->hostCPU.info = g_steal_pointer(&modelInfo); + return 0; + } +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 8e65635e0d..4a7fb2c726 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -637,6 +637,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + /* 420 */ + QEMU_CAPS_BLOCKDEV_REOPEN_COM_REDHAT_AV_8_2_0_API, /* downstream support for blockdev reopen in rhel-av-8.2.0 */ + QEMU_CAPS_MEMORY_BACKEND_PREALLOC_THREADS, /* -object memory-backend-*.prealloc-threads */ ++ QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION_DEPRECATED_PROPS, /* query-cpu-model-expansion may report deprecated CPU properties */ + + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; +-- +2.49.0 diff --git a/libvirt-util-xml-Introduce-virXMLNodeGetSubelementList.patch b/libvirt-util-xml-Introduce-virXMLNodeGetSubelementList.patch new file mode 100644 index 0000000..cac5d6b --- /dev/null +++ b/libvirt-util-xml-Introduce-virXMLNodeGetSubelementList.patch @@ -0,0 +1,104 @@ +From 534bb6a049e7ad227d143457ddcfe828238cea18 Mon Sep 17 00:00:00 2001 +Message-ID: <534bb6a049e7ad227d143457ddcfe828238cea18.1749113303.git.jdenemar@redhat.com> +From: Peter Krempa +Date: Mon, 13 Feb 2023 15:53:23 +0100 +Subject: [PATCH] util: xml: Introduce virXMLNodeGetSubelementList +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The new helper is similar to virXPathNodeSet list but for cases where we +want to get subelements directly rather than using XPath. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit dcd49d2cd65c9fe58d3df536fa258fc70c633d7e) + +JIRA: https://issues.redhat.com/browse/RHEL-88716 +Conflicts: + Trivial contextual conflicts in all files + (due to missing other patches in downstream) +Signed-off-by: Thomas Huth +--- + src/libvirt_private.syms | 1 + + src/util/virxml.c | 35 +++++++++++++++++++++++++++++++++++ + src/util/virxml.h | 6 ++++++ + 3 files changed, 42 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 7c558ad364..3af1b33a6c 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -3619,6 +3619,7 @@ virXMLFormatElementEmpty; + virXMLFormatMetadata; + virXMLNewNode; + virXMLNodeContentString; ++virXMLNodeGetSubelementList; + virXMLNodeNameEqual; + virXMLNodeSanitizeNamespaces; + virXMLNodeToString; +diff --git a/src/util/virxml.c b/src/util/virxml.c +index 4b09374107..b57462e2d0 100644 +--- a/src/util/virxml.c ++++ b/src/util/virxml.c +@@ -838,6 +838,41 @@ virXPathBoolean(const char *xpath, + return obj->boolval; + } + ++ ++/** ++ * virXMLNodeGetSubelementList: ++ * @node: node to get subelement of ++ * @name: name of subelement to fetch (NULL to fetch all sub-elements) ++ * @list: If non-NULL, filled with a list of pointers to the nodes. Caller is ++ * responsible for freeing the list but not the members. ++ * ++ * Find and return a sub-elements node of @node named @name in a list. ++ * Returns the number of subelements with @name ++ */ ++size_t ++virXMLNodeGetSubelementList(xmlNodePtr node, ++ const char *name, ++ xmlNodePtr **list) ++{ ++ xmlNodePtr n; ++ size_t nelems = 0; ++ ++ for (n = node->children; n; n = n->next) { ++ if (n->type == XML_ELEMENT_NODE) { ++ if (name && !virXMLNodeNameEqual(n, name)) ++ continue; ++ ++ if (list) ++ VIR_APPEND_ELEMENT_COPY(*list, nelems, n); ++ else ++ nelems++; ++ } ++ } ++ ++ return nelems; ++} ++ ++ + /** + * virXPathNode: + * @xpath: the XPath string to evaluate +diff --git a/src/util/virxml.h b/src/util/virxml.h +index c39eae6282..7b60551898 100644 +--- a/src/util/virxml.h ++++ b/src/util/virxml.h +@@ -83,6 +83,12 @@ int + virXPathULongHex(const char *xpath, + xmlXPathContextPtr ctxt, + unsigned long *value); ++ ++size_t ++virXMLNodeGetSubelementList(xmlNodePtr node, ++ const char *name, ++ xmlNodePtr **list); ++ + xmlNodePtr + virXPathNode(const char *xpath, + xmlXPathContextPtr ctxt); +-- +2.49.0 diff --git a/libvirt-util-xml-Return-GPtrArray-from-virXMLNodeGetSubelement-partial.patch b/libvirt-util-xml-Return-GPtrArray-from-virXMLNodeGetSubelement-partial.patch new file mode 100644 index 0000000..455785e --- /dev/null +++ b/libvirt-util-xml-Return-GPtrArray-from-virXMLNodeGetSubelement-partial.patch @@ -0,0 +1,92 @@ +From f3c75e44ad85fb01473c78adfc2a6d2c53f4f358 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Peter Krempa +Date: Mon, 13 Feb 2023 15:53:23 +0100 +Subject: [PATCH] util: xml: Return GPtrArray from virXMLNodeGetSubelement + [partial] +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Rework the helper to use a GPtrArray structure to simplify callers. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 08a7fc834c7c505e73bfcfa11c4a841a972d4f5d) + +JIRA: https://issues.redhat.com/browse/RHEL-88716 +Conflicts: + src/conf/*.c + Dropped the hunks that modify the callers + (since these are not available in downstream yet) +Signed-off-by: Thomas Huth +--- + src/util/virxml.c | 21 ++++++++------------- + src/util/virxml.h | 5 ++--- + 2 files changed, 10 insertions(+), 16 deletions(-) + +diff --git a/src/util/virxml.c b/src/util/virxml.c +index b57462e2d0..46afcf2146 100644 +--- a/src/util/virxml.c ++++ b/src/util/virxml.c +@@ -843,33 +843,28 @@ virXPathBoolean(const char *xpath, + * virXMLNodeGetSubelementList: + * @node: node to get subelement of + * @name: name of subelement to fetch (NULL to fetch all sub-elements) +- * @list: If non-NULL, filled with a list of pointers to the nodes. Caller is +- * responsible for freeing the list but not the members. + * +- * Find and return a sub-elements node of @node named @name in a list. +- * Returns the number of subelements with @name ++ * Find and return a sub-elements node of @node named @name in a GPtrArray ++ * populated with the xmlNodePtr objects. Caller is responsible for freeing the ++ * array but not the contained xmlNode objects. + */ +-size_t ++GPtrArray * + virXMLNodeGetSubelementList(xmlNodePtr node, +- const char *name, +- xmlNodePtr **list) ++ const char *name) + { ++ GPtrArray *ret = g_ptr_array_new(); + xmlNodePtr n; +- size_t nelems = 0; + + for (n = node->children; n; n = n->next) { + if (n->type == XML_ELEMENT_NODE) { + if (name && !virXMLNodeNameEqual(n, name)) + continue; + +- if (list) +- VIR_APPEND_ELEMENT_COPY(*list, nelems, n); +- else +- nelems++; ++ g_ptr_array_add(ret, n); + } + } + +- return nelems; ++ return ret; + } + + +diff --git a/src/util/virxml.h b/src/util/virxml.h +index 7b60551898..03677afc33 100644 +--- a/src/util/virxml.h ++++ b/src/util/virxml.h +@@ -84,10 +84,9 @@ virXPathULongHex(const char *xpath, + xmlXPathContextPtr ctxt, + unsigned long *value); + +-size_t ++GPtrArray * + virXMLNodeGetSubelementList(xmlNodePtr node, +- const char *name, +- xmlNodePtr **list); ++ const char *name); + + xmlNodePtr + virXPathNode(const char *xpath, +-- +2.49.0 diff --git a/libvirt-virsh-add-disable-deprecated-features-flag-to-domcapabilities.patch b/libvirt-virsh-add-disable-deprecated-features-flag-to-domcapabilities.patch new file mode 100644 index 0000000..f49ef36 --- /dev/null +++ b/libvirt-virsh-add-disable-deprecated-features-flag-to-domcapabilities.patch @@ -0,0 +1,83 @@ +From 16a50b3a73f496be8cd2bb9b9c0b88ca9a84ed0e Mon Sep 17 00:00:00 2001 +Message-ID: <16a50b3a73f496be8cd2bb9b9c0b88ca9a84ed0e.1749113304.git.jdenemar@redhat.com> +From: Collin Walling +Date: Mon, 16 Dec 2024 18:03:57 -0500 +Subject: [PATCH] virsh: add --disable-deprecated-features flag to + domcapabilities + +Add a new flag, --disable-deprecated-features, to the domcapabilities +command. This will modify the output to show the 'host-model' CPU +with features flagged as deprecated paired with the 'disable' policy. + +virsh domcapabilities --disable-deprecated-features + +Signed-off-by: Collin Walling +Reviewed-by: Jiri Denemark +(cherry picked from commit 15d45964e453e04f1761e527266af45554f58fcc) + +JIRA: https://issues.redhat.com/browse/RHEL-88716 +Conflicts: + docs/manpages/virsh.rst + tools/virsh-host.c + (Simple contextual conflicts due to other missing patches in downstream) +Signed-off-by: Thomas Huth +--- + docs/manpages/virsh.rst | 6 ++++++ + tools/virsh-host.c | 9 ++++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index d24e7774a6..3adbf42280 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -562,6 +562,7 @@ domcapabilities + :: + + domcapabilities [virttype] [emulatorbin] [arch] [machine] ++ [--disable-deprecated-features] + + + Print an XML document describing the domain capabilities for the +@@ -596,6 +597,11 @@ supplied along with either the *emulatorbin* or *arch* in order to + generate output for the default *machine*. Supplying a *machine* + value will generate output for the specific machine. + ++The **--disable-deprecated-features** argument will modify the contents ++of host-model CPU XML, updating the features list with any features ++flagged as deprecated for the CPU model by the hypervisor. These ++features will be paired with the "disable" policy. ++ + + pool-capabilities + ----------------- +diff --git a/tools/virsh-host.c b/tools/virsh-host.c +index 5ee3834de2..874875b378 100644 +--- a/tools/virsh-host.c ++++ b/tools/virsh-host.c +@@ -91,6 +91,10 @@ static const vshCmdOptDef opts_domcapabilities[] = { + .type = VSH_OT_STRING, + .help = N_("machine type (/domain/os/type/@machine)"), + }, ++ {.name = "disable-deprecated-features", ++ .type = VSH_OT_BOOL, ++ .help = N_("report host CPU model with deprecated features disabled"), ++ }, + {.name = NULL} + }; + +@@ -102,9 +106,12 @@ cmdDomCapabilities(vshControl *ctl, const vshCmd *cmd) + const char *emulatorbin = NULL; + const char *arch = NULL; + const char *machine = NULL; +- const unsigned int flags = 0; /* No flags so far */ ++ unsigned int flags = 0; + virshControl *priv = ctl->privData; + ++ if (vshCommandOptBool(cmd, "disable-deprecated-features")) ++ flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES; ++ + if (vshCommandOptStringReq(ctl, cmd, "virttype", &virttype) < 0 || + vshCommandOptStringReq(ctl, cmd, "emulatorbin", &emulatorbin) < 0 || + vshCommandOptStringReq(ctl, cmd, "arch", &arch) < 0 || +-- +2.49.0 diff --git a/libvirt.spec b/libvirt.spec index 5c8d054..f0c0e85 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -3,20 +3,19 @@ # This spec file assumes you are building on a Fedora or RHEL version # that's still supported by the vendor. It may work on other distros # or versions, but no effort will be made to ensure that going forward. -%define anolis_release .0.2 %define min_rhel 8 %define min_fedora 33 -%define arches_qemu_kvm %{ix86} x86_64 %{power64} %{arm} aarch64 s390x loongarch64 sw_64 +%define arches_qemu_kvm %{ix86} x86_64 %{power64} %{arm} aarch64 s390x %if 0%{?rhel} %if 0%{?rhel} > 8 - %define arches_qemu_kvm x86_64 aarch64 s390x loongarch64 + %define arches_qemu_kvm x86_64 aarch64 s390x %else - %define arches_qemu_kvm x86_64 %{power64} aarch64 s390x loongarch64 + %define arches_qemu_kvm x86_64 %{power64} aarch64 s390x %endif %endif -%define arches_64bit x86_64 %{power64} aarch64 s390x riscv64 loongarch64 sw_64 +%define arches_64bit x86_64 %{power64} aarch64 s390x riscv64 %define arches_x86 %{ix86} x86_64 %define arches_systemtap_64bit %{arches_64bit} @@ -24,9 +23,9 @@ %define arches_xen %{arches_x86} aarch64 %define arches_vbox %{arches_x86} %define arches_ceph %{arches_64bit} -%define arches_zfs %{arches_x86} %{power64} %{arm} loongarch64 sw_64 -%define arches_numactl %{arches_x86} %{power64} aarch64 s390x loongarch64 -%define arches_numad %{arches_x86} %{power64} aarch64 loongarch64 +%define arches_zfs %{arches_x86} %{power64} %{arm} +%define arches_numactl %{arches_x86} %{power64} aarch64 s390x +%define arches_numad %{arches_x86} %{power64} aarch64 # The hypervisor drivers that run in libvirtd %define with_qemu 0%{!?_without_qemu:1} @@ -211,7 +210,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 8.0.0 -Release: 23.3%{anolis_release}%{?dist}%{?extra_release} +Release: 23.4%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -323,15 +322,15 @@ Patch99: libvirt-remote-check-for-negative-array-lengths-before-allocation.patch Patch100: libvirt-util-Fix-error-return-for-virProcessKillPainfullyDelay.patch Patch101: libvirt-rpc-ensure-temporary-GSource-is-removed-from-client-event-loop.patch Patch102: libvirt-virStorageBackendLogicalCheckPool-Properly-mark-empty-logical-pools-as-active.patch -Patch1000: libvirt-Add-loongarch-support.patch -Patch1001: libvirt-add-loongarch-edit-xml-validate.patch -Patch1004: qemu-validate-Drop-tpm-tis-arch-validation.patch -Patch1005: qemu-command-Use-correct-tpm-device-for-all-non-x86.patch -Patch1006: libvirt-cpu-Add-new-Dharma-CPU-model.patch -Patch1007: libvirt-cpu-map-add-S5000C-cpu-model.patch -Patch1008: libvirt-Add-sw64-architecture-support-for-libvirt.patch -Patch1009: 1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch -Patch1010: 1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch +Patch103: libvirt-util-xml-Introduce-virXMLNodeGetSubelementList.patch +Patch104: libvirt-util-xml-Return-GPtrArray-from-virXMLNodeGetSubelement-partial.patch +Patch105: libvirt-qemuMonitorJSONGetCPUModelExpansion-refactor-parsing-functions.patch +Patch106: libvirt-qemu-parse-deprecated-props-from-query-cpu-model-expansion-response.patch +Patch107: libvirt-qemu_capabilities-query-deprecated-features-for-host-model.patch +Patch108: libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES.patch +Patch109: libvirt-qemu_capabilities-filter-deprecated-features-if-requested.patch +Patch110: libvirt-virsh-add-disable-deprecated-features-flag-to-domcapabilities.patch +Patch111: libvirt-conf-add-deprecated_features-attribute.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2211,18 +2210,16 @@ exit 0 %changelog -* Wed Jan 01 2025 hanliyang - 8.0.0-23.3.0.2 -- conf: qemu: add libvirt support reuse id for hygon CSV -- conf: qemu: support provide inject secret for Hygon CSV - -* Fri Dec 20 2024 zhaotianrui - 8.0.0-23.3.0.1 -- Add loongarch support -- Fix loongarch xml validate -- Synchronize upstream patches "Use correct tpm device for all non-x86" (lixianglai@loongson.cn) -- Synchronize upstream patches "validate: Drop tpm-tis arch validation" (lixianglai@loongson.cn) -- Add new Dharma CPU model (zhouyanjing@hygon.cn) -- Add Phytium S5000C CPU model (shuaijiakun1288@phytium.com.cn) -- Add sw64arch support (lufeifei@wxiat.com) +* Thu Jun 5 2025 Jiri Denemark - 8.0.0-23.4.el8 +- util: xml: Introduce virXMLNodeGetSubelementList (RHEL-88716) +- util: xml: Return GPtrArray from virXMLNodeGetSubelement [partial] (RHEL-88716) +- qemuMonitorJSONGetCPUModelExpansion: refactor parsing functions (RHEL-88716) +- qemu: parse deprecated-props from query-cpu-model-expansion response (RHEL-88716) +- qemu_capabilities: query deprecated features for host-model (RHEL-88716) +- libvirt-domain: introduce VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES (RHEL-88716) +- qemu_capabilities: filter deprecated features if requested (RHEL-88716) +- virsh: add --disable-deprecated-features flag to domcapabilities (RHEL-88716) +- conf: add deprecated_features attribute (RHEL-88716) * Wed Nov 6 2024 Jiri Denemark - 8.0.0-23.3.el8 - virStorageBackendLogicalCheckPool: Properly mark empty logical pools as active (RHEL-65771) diff --git a/qemu-command-Use-correct-tpm-device-for-all-non-x86.patch b/qemu-command-Use-correct-tpm-device-for-all-non-x86.patch deleted file mode 100644 index 8189141..0000000 --- a/qemu-command-Use-correct-tpm-device-for-all-non-x86.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7c9af5730bc83bde24d6788720f92fceba533124 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Sat, 18 Jun 2022 12:46:03 -0400 -Subject: [PATCH 2/2] qemu: command: Use correct tpm device for all non-x86 - -The qemu `tpm-tis` device is an ISA device, so only really applicable -to x86 archs. For all non-x86 archs we should use `tpm-tis-device` - -This fixes tpm-tis usage on armv7l and riscv - -Reviewed-by: Michal Privoznik -Signed-off-by: Cole Robinson ---- - src/qemu/qemu_command.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c -index a7855d3..978ce89 100644 ---- a/src/qemu/qemu_command.c -+++ b/src/qemu/qemu_command.c -@@ -9733,7 +9733,7 @@ qemuBuildTPMDevCmd(virCommand *cmd, - const char *model = virDomainTPMModelTypeToString(tpm->model); - g_autofree char *tpmdev = g_strdup_printf("tpm-%s", tpm->info.alias); - -- if (tpm->model == VIR_DOMAIN_TPM_MODEL_TIS && def->os.arch == VIR_ARCH_AARCH64) -+ if (tpm->model == VIR_DOMAIN_TPM_MODEL_TIS && !ARCH_IS_X86(def->os.arch)) - model = "tpm-tis-device"; - - if (virJSONValueObjectAdd(&props, --- -2.31.1 - diff --git a/qemu-validate-Drop-tpm-tis-arch-validation.patch b/qemu-validate-Drop-tpm-tis-arch-validation.patch deleted file mode 100644 index 178a943..0000000 --- a/qemu-validate-Drop-tpm-tis-arch-validation.patch +++ /dev/null @@ -1,35 +0,0 @@ -From d45d539a4aab6702710b877816d93d70f81c0165 Mon Sep 17 00:00:00 2001 -From: Cole Robinson -Date: Sat, 18 Jun 2022 12:52:29 -0400 -Subject: [PATCH 1/2] qemu: validate: Drop tpm-tis arch validation - -Checking against qemu capabilities should be enough here - -Resolves: https://gitlab.com/libvirt/libvirt/-/issues/329 - -Reviewed-by: Michal Privoznik -Signed-off-by: Cole Robinson ---- - src/qemu/qemu_validate.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c -index 7d01d31..6b65ce4 100644 ---- a/src/qemu/qemu_validate.c -+++ b/src/qemu/qemu_validate.c -@@ -4618,12 +4618,6 @@ qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm, - - switch (tpm->model) { - case VIR_DOMAIN_TPM_MODEL_TIS: -- if (!ARCH_IS_X86(def->os.arch) && (def->os.arch != VIR_ARCH_AARCH64)) { -- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, -- _("TPM model '%s' is only available for x86 and aarch64 guests"), -- virDomainTPMModelTypeToString(tpm->model)); -- return -1; -- } - flag = QEMU_CAPS_DEVICE_TPM_TIS; - break; - case VIR_DOMAIN_TPM_MODEL_CRB: --- -2.31.1 - -- Gitee From d31e282a3367d71f46185898c5c2da994bd9b791 Mon Sep 17 00:00:00 2001 From: zhaotianrui Date: Thu, 8 Sep 2022 09:28:25 -0400 Subject: [PATCH 2/8] Add loongarch support Signed-off-by: zhaotianrui --- libvirt-Add-loongarch-support.patch | 1233 +++++++++++++++++++++++++++ libvirt.spec | 21 +- 2 files changed, 1246 insertions(+), 8 deletions(-) create mode 100644 libvirt-Add-loongarch-support.patch diff --git a/libvirt-Add-loongarch-support.patch b/libvirt-Add-loongarch-support.patch new file mode 100644 index 0000000..ac0da71 --- /dev/null +++ b/libvirt-Add-loongarch-support.patch @@ -0,0 +1,1233 @@ +From da7befb4ce165d692f34156f740f4ea3ce2b7fec Mon Sep 17 00:00:00 2001 +From: zhaotianrui +Date: Sat, 3 Sep 2022 14:23:43 -0400 +Subject: [PATCH] Add loongarch support + +Signed-off-by: zhaotianrui +Change-Id: I8d245bc2fb914b08af4ade8e334d59ba3a5c2f01 +--- + po/POTFILES.in | 1 + + src/cpu/cpu.c | 3 +- + src/cpu/cpu.h | 3 +- + src/cpu/cpu_loongarch.c | 727 ++++++++++++++++++++++++++++++ + src/cpu/cpu_loongarch.h | 28 ++ + src/cpu/cpu_loongarch_data.h | 40 ++ + src/cpu/meson.build | 1 + + src/cpu_map/index.xml | 5 + + src/cpu_map/loongarch_vendors.xml | 3 + + src/cpu_map/ls_3a5000.xml | 6 + + src/cpu_map/meson.build | 2 + + src/qemu/qemu_capabilities.c | 5 + + src/qemu/qemu_conf.c | 4 +- + src/qemu/qemu_domain.c | 20 +- + src/qemu/qemu_domain.h | 1 + + src/qemu/qemu_domain_address.c | 58 +++ + src/qemu/qemu_validate.c | 3 +- + src/util/virarch.c | 3 + + src/util/virarch.h | 3 + + src/util/virhostcpu.c | 2 +- + src/util/virsysinfo.c | 2 +- + 21 files changed, 913 insertions(+), 7 deletions(-) + create mode 100644 src/cpu/cpu_loongarch.c + create mode 100644 src/cpu/cpu_loongarch.h + create mode 100644 src/cpu/cpu_loongarch_data.h + create mode 100644 src/cpu_map/loongarch_vendors.xml + create mode 100644 src/cpu_map/ls_3a5000.xml + +diff --git a/po/POTFILES.in b/po/POTFILES.in +index bf0a3b3529..1153e78265 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -68,6 +68,7 @@ + @SRCDIR@src/cpu/cpu_arm.c + @SRCDIR@src/cpu/cpu_map.c + @SRCDIR@src/cpu/cpu_ppc64.c ++@SRCDIR@src/cpu/cpu_loongarch.c + @SRCDIR@src/cpu/cpu_s390.c + @SRCDIR@src/cpu/cpu_x86.c + @SRCDIR@src/datatypes.c +diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c +index 285c7eee44..49527c3688 100644 +--- a/src/cpu/cpu.c ++++ b/src/cpu/cpu.c +@@ -31,7 +31,7 @@ + #include "cpu_arm.h" + #include "capabilities.h" + #include "virstring.h" +- ++#include "cpu_loongarch.h" + + #define VIR_FROM_THIS VIR_FROM_CPU + +@@ -42,6 +42,7 @@ static struct cpuArchDriver *drivers[] = { + &cpuDriverPPC64, + &cpuDriverS390, + &cpuDriverArm, ++ &cpuDriverLoongArch, + }; + + +diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h +index 071b33fe76..ce7aee4757 100644 +--- a/src/cpu/cpu.h ++++ b/src/cpu/cpu.h +@@ -28,7 +28,7 @@ + #include "cpu_x86_data.h" + #include "cpu_ppc64_data.h" + #include "cpu_arm_data.h" +- ++#include "cpu_loongarch_data.h" + + typedef struct _virCPUData virCPUData; + struct _virCPUData { +@@ -37,6 +37,7 @@ struct _virCPUData { + virCPUx86Data x86; + virCPUppc64Data ppc64; + virCPUarmData arm; ++ virCPULoongArchData loongarch; + /* generic driver needs no data */ + } data; + }; +diff --git a/src/cpu/cpu_loongarch.c b/src/cpu/cpu_loongarch.c +new file mode 100644 +index 0000000000..f7b4b85a44 +--- /dev/null ++++ b/src/cpu/cpu_loongarch.c +@@ -0,0 +1,727 @@ ++/* ++ * cpu_loongarch.c: CPU driver for 64-bit LOONGARCH CPUs ++ * ++ * Copyright (C) 2013 Red Hat, Inc. ++ * Copyright (C) IBM Corporation, 2010 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "virlog.h" ++#include "viralloc.h" ++#include "cpu.h" ++#include "virstring.h" ++#include "cpu_map.h" ++#include "virbuffer.h" ++#include "cpu_loongarch.h" ++#include "cpu_loongarch_data.h" ++ ++#define VIR_FROM_THIS VIR_FROM_CPU ++ ++VIR_LOG_INIT("cpu.cpu_loongarch"); ++ ++static const virArch archs[] = { VIR_ARCH_LOONGARCH64 }; ++ ++typedef struct _LoongArch_vendor LoongArch_vendor; ++struct _LoongArch_vendor { ++ char *name; ++}; ++ ++typedef struct _LoongArch_model LoongArch_model; ++struct _LoongArch_model { ++ char *name; ++ LoongArch_vendor *vendor; ++ virCPULoongArchData data; ++}; ++ ++typedef struct _LoongArch_map LoongArch_map; ++struct _LoongArch_map { ++ size_t nvendors; ++ LoongArch_vendor **vendors; ++ size_t nmodels; ++ LoongArch_model **models; ++}; ++ ++static void ++LoongArchDataClear(virCPULoongArchData *data) ++{ ++ if (!data) ++ return; ++ ++ g_free(data->prid); ++} ++ ++static int ++LoongArchDataCopy(virCPULoongArchData *dst, const virCPULoongArchData *src) ++{ ++ size_t i; ++ ++ dst->prid = g_new0(virCPULoongArchPrid, src->len); ++ dst->len = src->len; ++ ++ for (i = 0; i < src->len; i++) { ++ dst->prid[i].value = src->prid[i].value; ++ dst->prid[i].mask = src->prid[i].mask; ++ } ++ ++ return 0; ++} ++ ++static void ++LoongArchVendorFree(LoongArch_vendor *vendor) ++{ ++ if (!vendor) ++ return; ++ ++ g_free(vendor); ++} ++ ++static LoongArch_vendor * ++LoongArchVendorFind(LoongArch_map *map, ++ const char *name) ++{ ++ size_t i; ++ ++ for (i = 0; i < map->nvendors; i++) { ++ if (STREQ(map->vendors[i]->name, name)) ++ return map->vendors[i]; ++ } ++ ++ return NULL; ++} ++ ++static void ++LoongArchModelFree(LoongArch_model *model) ++{ ++ if (!model) ++ return; ++ ++ LoongArchDataClear(&model->data); ++ g_free(model->name); ++ g_free(model); ++} ++ ++static LoongArch_model * ++LoongArchModelCopy(LoongArch_model *model) ++{ ++ LoongArch_model *copy; ++ ++ copy = g_new0(LoongArch_model, 1); ++ copy->name = g_strdup(model->name); ++ ++ if (LoongArchDataCopy(©->data, &model->data) < 0) ++ goto error; ++ ++ copy->vendor = model->vendor; ++ ++ return copy; ++ ++ error: ++ LoongArchModelFree(copy); ++ return NULL; ++} ++ ++static LoongArch_model * ++LoongArchModelFind(LoongArch_map *map, ++ const char *name) ++{ ++ size_t i; ++ ++ for (i = 0; i < map->nmodels; i++) { ++ if (STREQ(map->models[i]->name, name)) ++ return map->models[i]; ++ } ++ ++ return NULL; ++} ++ ++static LoongArch_model * ++LoongArchModelFindPrid(LoongArch_map *map, ++ uint32_t prid) ++{ ++ size_t i; ++ size_t j; ++ ++ for (i = 0; i < map->nmodels; i++) { ++ LoongArch_model *model = map->models[i]; ++ for (j = 0; j < model->data.len; j++) { ++ if ((prid & model->data.prid[j].mask) == model->data.prid[j].value) ++ return model; ++ } ++ } ++ ++ return NULL; ++} ++ ++static LoongArch_model * ++LoongArchModelFromCPU(const virCPUDef *cpu, ++ LoongArch_map *map) ++{ ++ LoongArch_model *model; ++ ++ if (!cpu->model) { ++ virReportError(VIR_ERR_INVALID_ARG, "%s", ++ _("no CPU model specified")); ++ return NULL; ++ } ++ ++ if (!(model = LoongArchModelFind(map, cpu->model))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown CPU model %s"), cpu->model); ++ return NULL; ++ } ++ ++ return LoongArchModelCopy(model); ++} ++ ++static void ++LoongArchMapFree(LoongArch_map *map) ++{ ++ size_t i; ++ ++ if (!map) ++ return; ++ ++ for (i = 0; i < map->nmodels; i++) ++ LoongArchModelFree(map->models[i]); ++ g_free(map->models); ++ ++ for (i = 0; i < map->nvendors; i++) ++ LoongArchVendorFree(map->vendors[i]); ++ g_free(map->vendors); ++ ++ g_free(map); ++} ++ ++static int ++LoongArchVendorParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, ++ const char *name, ++ void *data) ++{ ++ LoongArch_map *map = data; ++ LoongArch_vendor *vendor; ++ int ret = -1; ++ ++ vendor = g_new0(LoongArch_vendor, 1); ++ vendor->name = g_strdup(name); ++ ++ if (LoongArchVendorFind(map, vendor->name)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("CPU vendor %s already defined"), vendor->name); ++ goto cleanup; ++ } ++ ++ VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor); ++ ret = 0; ++ ++ cleanup: ++ LoongArchVendorFree(vendor); ++ return ret; ++} ++ ++static int ++LoongArchModelParse(xmlXPathContextPtr ctxt, ++ const char *name, ++ void *data) ++{ ++ LoongArch_map *map = data; ++ LoongArch_model *model; ++ xmlNodePtr *nodes = NULL; ++ char *vendor = NULL; ++ unsigned long prid; ++ size_t i; ++ int n; ++ int ret = -1; ++ ++ model = g_new0(LoongArch_model, 1); ++ model->name = g_strdup(name); ++ ++ if (LoongArchModelFind(map, model->name)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("CPU model %s already defined"), model->name); ++ goto cleanup; ++ } ++ ++ if (virXPathBoolean("boolean(./vendor)", ctxt)) { ++ vendor = virXPathString("string(./vendor/@name)", ctxt); ++ if (!vendor) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Invalid vendor element in CPU model %s"), ++ model->name); ++ goto cleanup; ++ } ++ ++ if (!(model->vendor = LoongArchVendorFind(map, vendor))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown vendor %s referenced by CPU model %s"), ++ vendor, model->name); ++ goto cleanup; ++ } ++ } ++ ++ if ((n = virXPathNodeSet("./prid", ctxt, &nodes)) <= 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing Prid information for CPU model %s"), ++ model->name); ++ goto cleanup; ++ } ++ ++ model->data.prid = g_new0(virCPULoongArchPrid, n); ++ model->data.len = n; ++ ++ for (i = 0; i < n; i++) { ++ ctxt->node = nodes[i]; ++ ++ if (virXPathULongHex("string(./@value)", ctxt, &prid) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing or invalid Prid value in CPU model %s"), ++ model->name); ++ goto cleanup; ++ } ++ model->data.prid[i].value = prid; ++ ++ if (virXPathULongHex("string(./@mask)", ctxt, &prid) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing or invalid PVR mask in CPU model %s"), ++ model->name); ++ goto cleanup; ++ } ++ model->data.prid[i].mask = prid; ++ } ++ ++ VIR_APPEND_ELEMENT(map->models, map->nmodels, model); ++ ret = 0; ++ ++ cleanup: ++ LoongArchModelFree(model); ++ g_free(vendor); ++ g_free(nodes); ++ return ret; ++} ++ ++static LoongArch_map * ++LoongArchLoadMap(void) ++{ ++ LoongArch_map *map; ++ ++ map = g_new0(LoongArch_map, 1); ++ if (cpuMapLoad("loongarch64", LoongArchVendorParse, NULL, LoongArchModelParse, map) < 0) ++ goto error; ++ ++ return map; ++ ++ error: ++ LoongArchMapFree(map); ++ return NULL; ++} ++ ++static virCPUData * ++LoongArchMakeCPUData(virArch arch, ++ virCPULoongArchData *data) ++{ ++ virCPUData *cpuData; ++ ++ cpuData = g_new0(virCPUData, 1); ++ cpuData->arch = arch; ++ ++ if (LoongArchDataCopy(&cpuData->data.loongarch, data) < 0) ++ g_free(cpuData); ++ ++ return cpuData; ++} ++ ++static virCPUCompareResult ++LoongArchCompute(virCPUDef *host, ++ const virCPUDef *other, ++ virCPUData *guestData, ++ char **message) ++{ ++ LoongArch_map *map = NULL; ++ LoongArch_model *host_model = NULL; ++ LoongArch_model *guest_model = NULL; ++ virCPUDef *cpu = NULL; ++ virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR; ++ virArch arch; ++ size_t i; ++ ++ /* Ensure existing configurations are handled correctly */ ++ if (!(cpu = virCPUDefCopy(other))) ++ goto cleanup; ++ ++ if (cpu->arch != VIR_ARCH_NONE) { ++ bool found = false; ++ ++ for (i = 0; i < G_N_ELEMENTS(archs); i++) { ++ if (archs[i] == cpu->arch) { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) { ++ VIR_DEBUG("CPU arch %s does not match host arch", ++ virArchToString(cpu->arch)); ++ if (message) { ++ *message = g_strdup_printf(_("CPU arch %s does not match host arch"), ++ virArchToString(cpu->arch)); ++ } ++ ret = VIR_CPU_COMPARE_INCOMPATIBLE; ++ goto cleanup; ++ } ++ arch = cpu->arch; ++ } else { ++ arch = host->arch; ++ } ++ ++ if (cpu->vendor && ++ (!host->vendor || STRNEQ(cpu->vendor, host->vendor))) { ++ VIR_DEBUG("host CPU vendor does not match required CPU vendor %s", ++ cpu->vendor); ++ if (message) { ++ *message = g_strdup_printf(_("host CPU vendor does not match required " ++ "CPU vendor %s"), cpu->vendor); ++ } ++ ret = VIR_CPU_COMPARE_INCOMPATIBLE; ++ goto cleanup; ++ } ++ ++ if (!(map = LoongArchLoadMap())) ++ goto cleanup; ++ ++ /* Host CPU information */ ++ if (!(host_model = LoongArchModelFromCPU(host, map))) ++ goto cleanup; ++ ++ if (cpu->type == VIR_CPU_TYPE_GUEST) { ++ /* Guest CPU information */ ++ switch (cpu->mode) { ++ case VIR_CPU_MODE_HOST_MODEL: ++ case VIR_CPU_MODE_HOST_PASSTHROUGH: ++ /* host-model and host-passthrough: ++ * the guest CPU is the same as the host */ ++ guest_model = LoongArchModelCopy(host_model); ++ break; ++ ++ case VIR_CPU_MODE_CUSTOM: ++ /* custom: ++ * look up guest CPU information */ ++ guest_model = LoongArchModelFromCPU(cpu, map); ++ break; ++ } ++ } else { ++ /* Other host CPU information */ ++ guest_model = LoongArchModelFromCPU(cpu, map); ++ } ++ ++ if (!guest_model) ++ goto cleanup; ++ ++ if (STRNEQ(guest_model->name, host_model->name)) { ++ VIR_DEBUG("host CPU model does not match required CPU model %s", ++ guest_model->name); ++ if (message) { ++ *message = g_strdup_printf(_("host CPU model does not match required " ++ "CPU model %s"),guest_model->name); ++ } ++ ret = VIR_CPU_COMPARE_INCOMPATIBLE; ++ goto cleanup; ++ } ++ ++ if (guestData) ++ if (!(guestData = LoongArchMakeCPUData(arch, &guest_model->data))) ++ goto cleanup; ++ ++ ret = VIR_CPU_COMPARE_IDENTICAL; ++ ++ cleanup: ++ virCPUDefFree(cpu); ++ LoongArchMapFree(map); ++ LoongArchModelFree(host_model); ++ LoongArchModelFree(guest_model); ++ return ret; ++} ++ ++static virCPUCompareResult ++virCPULoongArchCompare(virCPUDef *host, ++ virCPUDef *cpu, ++ bool failIncompatible) ++{ ++ virCPUCompareResult ret; ++ char *message = NULL; ++ ++ if (!host || !host->model) { ++ if (failIncompatible) { ++ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", ++ _("unknown host CPU")); ++ } else { ++ VIR_WARN("unknown host CPU"); ++ ret = VIR_CPU_COMPARE_INCOMPATIBLE; ++ } ++ return -1; ++ } ++ ++ ret = LoongArchCompute(host, cpu, NULL, &message); ++ ++ if (failIncompatible && ret == VIR_CPU_COMPARE_INCOMPATIBLE) { ++ ret = VIR_CPU_COMPARE_ERROR; ++ if (message) { ++ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", message); ++ } else { ++ virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL); ++ } ++ } ++ g_free(message); ++ ++ return ret; ++} ++ ++static int ++LoongArchDriverDecode(virCPUDef *cpu, ++ const virCPUData *data, ++ virDomainCapsCPUModels *models) ++{ ++ int ret = -1; ++ LoongArch_map *map; ++ LoongArch_model *model; ++ ++ if (!data || !(map = LoongArchLoadMap())) ++ return -1; ++ ++ if (!(model = LoongArchModelFindPrid(map, data->data.loongarch.prid[0].value))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("Cannot find CPU model with Prid 0x%08x"), ++ data->data.loongarch.prid[0].value); ++ goto cleanup; ++ } ++ ++ if (!virCPUModelIsAllowed(model->name, models)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("CPU model %s is not supported by hypervisor"), ++ model->name); ++ goto cleanup; ++ } ++ ++ cpu->model = g_strdup(model->name); ++ if (model->vendor) { ++ cpu->vendor = g_strdup(model->vendor->name); ++ } ++ ret = 0; ++ ++ cleanup: ++ LoongArchMapFree(map); ++ ++ return ret; ++} ++ ++static void ++virCPULoongArchDataFree(virCPUData *data) ++{ ++ if (!data) ++ return; ++ ++ LoongArchDataClear(&data->data.loongarch); ++ g_free(data); ++} ++ ++static int virCPULoongArchGetHostPRID(void) ++{ ++ return 0x14c010; ++} ++ ++static int ++virCPULoongArchGetHost(virCPUDef *cpu, ++ virDomainCapsCPUModels *models) ++{ ++ virCPUData *cpuData = NULL; ++ virCPULoongArchData *data; ++ int ret = -1; ++ ++ if (!(cpuData = virCPUDataNew(archs[0]))) ++ goto cleanup; ++ ++ data = &cpuData->data.loongarch; ++ ++ data->prid = g_new0(virCPULoongArchPrid, 1); ++ data->len = 1; ++ ++ data->prid[0].value = virCPULoongArchGetHostPRID(); ++ data->prid[0].mask = 0xffff00ul; ++ ++ ret = LoongArchDriverDecode(cpu, cpuData, models); ++ ++ cleanup: ++ virCPULoongArchDataFree(cpuData); ++ return ret; ++} ++ ++ ++static int ++virCPULoongArchUpdate(virCPUDef *guest, ++ const virCPUDef *host, ++ bool relative) ++{ ++ /* ++ * - host-passthrough doesn't even get here ++ * - host-model is used for host CPU running in a compatibility mode and ++ * it needs to remain unchanged ++ * - custom doesn't support any optional features, there's nothing to ++ * update ++ */ ++ VIR_DEBUG("host model %s, if relatived %d",host->model, relative); ++ if (guest->mode == VIR_CPU_MODE_CUSTOM) ++ guest->match = VIR_CPU_MATCH_EXACT; ++ ++ return 0; ++} ++ ++static virCPUDef * ++LoongArchDriverBaseline(virCPUDef **cpus, ++ unsigned int ncpus, ++ virDomainCapsCPUModels *models, ++ const char **features, ++ bool migratable) ++{ ++ LoongArch_map *map; ++ LoongArch_model *model; ++ LoongArch_vendor *vendor = NULL; ++ virCPUDef *cpu = NULL; ++ size_t i; ++ if (models && *features) { ++ VIR_DEBUG("migratable %d features %s",migratable, *features); ++ } ++ if (!(map = LoongArchLoadMap())) ++ goto error; ++ ++ if (!(model = LoongArchModelFind(map, cpus[0]->model))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown CPU model %s"), cpus[0]->model); ++ goto error; ++ } ++ ++ for (i = 0; i < ncpus; i++) { ++ LoongArch_vendor *vnd; ++ ++ if (STRNEQ(cpus[i]->model, model->name)) { ++ virReportError(VIR_ERR_OPERATION_FAILED, "%s", ++ _("CPUs are incompatible")); ++ goto error; ++ } ++ ++ if (!cpus[i]->vendor) ++ continue; ++ ++ if (!(vnd = LoongArchVendorFind(map, cpus[i]->vendor))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("Unknown CPU vendor %s"), cpus[i]->vendor); ++ goto error; ++ } ++ ++ if (model->vendor) { ++ if (model->vendor != vnd) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("CPU vendor %s of model %s differs from " ++ "vendor %s"), ++ model->vendor->name, model->name, ++ vnd->name); ++ goto error; ++ } ++ } else if (vendor) { ++ if (vendor != vnd) { ++ virReportError(VIR_ERR_OPERATION_FAILED, "%s", ++ _("CPU vendors do not match")); ++ goto error; ++ } ++ } else { ++ vendor = vnd; ++ } ++ } ++ ++ cpu = g_new0(virCPUDef ,1); ++ cpu->model = g_strdup(model->name); ++ if (vendor) { ++ cpu->vendor = g_strdup(vendor->name); ++ } ++ cpu->type = VIR_CPU_TYPE_GUEST; ++ cpu->match = VIR_CPU_MATCH_EXACT; ++ cpu->fallback = VIR_CPU_FALLBACK_FORBID; ++ ++ cleanup: ++ LoongArchMapFree(map); ++ ++ return cpu; ++ ++ error: ++ virCPUDefFree(cpu); ++ cpu = NULL; ++ goto cleanup; ++} ++ ++static int ++virCPULoongArchDriverGetModels(char ***models) ++{ ++ LoongArch_map *map; ++ size_t i; ++ int ret = -1; ++ ++ if (!(map = LoongArchLoadMap())) ++ goto error; ++ ++ if (models) { ++ *models = g_new0(char *, map->nmodels + 1); ++ for (i = 0; i < map->nmodels; i++) { ++ (*models)[i] = g_strdup(map->models[i]->name); ++ } ++ } ++ ++ ret = map->nmodels; ++ ++ cleanup: ++ LoongArchMapFree(map); ++ return ret; ++ ++ error: ++ if (models) { ++ g_strfreev(*models); ++ *models = NULL; ++ } ++ goto cleanup; ++} ++ ++struct cpuArchDriver cpuDriverLoongArch = { ++ .name = "LoongArch", ++ .arch = archs, ++ .narch = G_N_ELEMENTS(archs), ++ .compare = virCPULoongArchCompare, ++ .decode = LoongArchDriverDecode, ++ .encode = NULL, ++ .dataFree = virCPULoongArchDataFree, ++ .getHost = virCPULoongArchGetHost, ++ .baseline = LoongArchDriverBaseline, ++ .update = virCPULoongArchUpdate, ++ .getModels = virCPULoongArchDriverGetModels, ++}; +diff --git a/src/cpu/cpu_loongarch.h b/src/cpu/cpu_loongarch.h +new file mode 100644 +index 0000000000..1fde3b5162 +--- /dev/null ++++ b/src/cpu/cpu_loongarch.h +@@ -0,0 +1,28 @@ ++/* ++ * cpu_loongarch.h: CPU driver for 64-bit LOONGARCH CPUs ++ * ++ * Copyright (C) Copyright (C) IBM Corporation, 2010 ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ */ ++ ++#ifndef __VIR_CPU_LOONGARCH_H__ ++# define __VIR_CPU_LOONGARCH_H__ ++ ++# include "cpu.h" ++ ++extern struct cpuArchDriver cpuDriverLoongArch; ++ ++#endif /* __VIR_CPU_LOONGARCH_H__ */ +diff --git a/src/cpu/cpu_loongarch_data.h b/src/cpu/cpu_loongarch_data.h +new file mode 100644 +index 0000000000..1a759e7d16 +--- /dev/null ++++ b/src/cpu/cpu_loongarch_data.h +@@ -0,0 +1,40 @@ ++/* ++ * cpu_loongarch_data.h: 64-bit LOONGARCH CPU specific data ++ * ++ * Copyright (C) 2012 IBM Corporation. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; If not, see ++ * . ++ */ ++ ++#ifndef __VIR_CPU_LOONGARCH_DATA_H__ ++# define __VIR_CPU_LOONGARCH_DATA_H__ ++ ++# include ++ ++typedef struct _virCPULoongArchPrid virCPULoongArchPrid; ++struct _virCPULoongArchPrid { ++ uint32_t value; ++ uint32_t mask; ++}; ++ ++# define VIR_CPU_LOONGARCH_DATA_INIT { 0 } ++ ++typedef struct _virCPULoongArchData virCPULoongArchData; ++struct _virCPULoongArchData { ++ size_t len; ++ virCPULoongArchPrid *prid; ++}; ++ ++#endif /* __VIR_CPU_MIPS64_DATA_H__ */ +diff --git a/src/cpu/meson.build b/src/cpu/meson.build +index b4ad95e46d..ad2f859fd8 100644 +--- a/src/cpu/meson.build ++++ b/src/cpu/meson.build +@@ -5,6 +5,7 @@ cpu_sources = [ + 'cpu_ppc64.c', + 'cpu_s390.c', + 'cpu_x86.c', ++ 'cpu_loongarch.c', + ] + + cpu_lib = static_library( +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index ffe1fa91e5..d302de396a 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -110,4 +110,9 @@ + + + ++ ++ ++ ++ ++ + +diff --git a/src/cpu_map/loongarch_vendors.xml b/src/cpu_map/loongarch_vendors.xml +new file mode 100644 +index 0000000000..c744654617 +--- /dev/null ++++ b/src/cpu_map/loongarch_vendors.xml +@@ -0,0 +1,3 @@ ++ ++ ++ +diff --git a/src/cpu_map/ls_3a5000.xml b/src/cpu_map/ls_3a5000.xml +new file mode 100644 +index 0000000000..f6fe3386f7 +--- /dev/null ++++ b/src/cpu_map/ls_3a5000.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build +index 013fc62a02..9657c5164e 100644 +--- a/src/cpu_map/meson.build ++++ b/src/cpu_map/meson.build +@@ -77,6 +77,8 @@ cpumap_data = [ + 'x86_vendors.xml', + 'x86_Westmere-IBRS.xml', + 'x86_Westmere.xml', ++ 'loongarch_vendors.xml', ++ 'ls_3a5000.xml', + ] + + install_data(cpumap_data, install_dir: pkgdatadir / 'cpu_map') +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index c4f7db55c8..75668c6451 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2073,6 +2073,9 @@ bool virQEMUCapsHasPCIMultiBus(const virDomainDef *def) + if (ARCH_IS_X86(def->os.arch)) + return true; + ++ if (STRPREFIX(def->os.machine,"loongson7a")) ++ return true; ++ + /* PPC supports multibus on all machine types which have pci since qemu-2.0.0 */ + if (def->os.arch == VIR_ARCH_PPC || + ARCH_IS_PPC64(def->os.arch)) { +@@ -2690,6 +2693,7 @@ static const char *preferredMachines[] = + + "malta", /* VIR_ARCH_MIPS64 */ + "malta", /* VIR_ARCH_MIPS64EL */ ++ "loongson7a", /* VIR_ARCH_LOONGARCH64 */ + "or1k-sim", /* VIR_ARCH_OR32 */ + NULL, /* VIR_ARCH_PARISC (no QEMU impl) */ + NULL, /* VIR_ARCH_PARISC64 (no QEMU impl) */ +@@ -5115,6 +5119,7 @@ virQEMUCapsInitQMPBasicArch(virQEMUCaps *qemuCaps) + case VIR_ARCH_MIPSEL: + case VIR_ARCH_MIPS64: + case VIR_ARCH_MIPS64EL: ++ case VIR_ARCH_LOONGARCH64: + case VIR_ARCH_OR32: + case VIR_ARCH_PARISC: + case VIR_ARCH_PARISC64: +diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c +index a0b8076d6b..8cd03261ac 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -101,7 +101,9 @@ qemuDriverUnlock(virQEMUDriver *driver) + "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd:" \ + "/usr/share/OVMF/OVMF_CODE.secboot.fd:/usr/share/OVMF/OVMF_VARS.fd:" \ + "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd:" \ +- "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd" ++ "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd:" \ ++ "/usr/share/qemu-kvm/loongarch_bios.bin:/usr/share/qemu-kvm/loongarch_bios.bin" ++ + #endif + + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 40fe9985e6..814d8cb67d 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -3668,6 +3668,10 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver, + addPCIeRoot = virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_GPEX); + break; + ++ case VIR_ARCH_LOONGARCH64: ++ addPCIeRoot = true; ++ break; ++ + case VIR_ARCH_PPC64: + case VIR_ARCH_PPC64LE: + addPCIRoot = true; +@@ -5065,6 +5069,11 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont, + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; + else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; ++ } else if (ARCH_IS_LOONGARCH(def->os.arch)) { ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI)) ++ cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; ++ else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) ++ cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; + } + } + /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */ +@@ -8324,6 +8333,13 @@ qemuDomainDefCheckABIStability(virQEMUDriver *driver, + } + + ++bool ++qemuDomainIsLoongson(const virDomainDef *def) ++{ ++ return (STRPREFIX(def->os.machine,"loongson3a") || STRPREFIX(def->os.machine,"loongson7a")); ++} ++ ++ + bool + qemuDomainCheckABIStability(virQEMUDriver *driver, + virDomainObj *vm, +@@ -8664,7 +8680,9 @@ qemuDomainMachineHasBuiltinIDE(const char *machine, + return qemuDomainMachineIsI440FX(machine, arch) || + STREQ(machine, "malta") || + STREQ(machine, "sun4u") || +- STREQ(machine, "g3beige"); ++ STREQ(machine, "g3beige") || ++ STREQ(machine, "loongson3a") || ++ STREQ(machine, "loongson7a"); + } + + +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index e5046367e3..57f1f97348 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -770,6 +770,7 @@ bool qemuDomainIsS390CCW(const virDomainDef *def); + bool qemuDomainIsARMVirt(const virDomainDef *def); + bool qemuDomainIsRISCVVirt(const virDomainDef *def); + bool qemuDomainIsPSeries(const virDomainDef *def); ++bool qemuDomainIsLoongson(const virDomainDef *def); + bool qemuDomainHasPCIRoot(const virDomainDef *def); + bool qemuDomainHasPCIeRoot(const virDomainDef *def); + bool qemuDomainHasBuiltinIDE(const virDomainDef *def); +diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c +index 18fc34d049..c3fac1c33b 100644 +--- a/src/qemu/qemu_domain_address.c ++++ b/src/qemu/qemu_domain_address.c +@@ -2026,6 +2026,59 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDef *def, + } + + ++static int ++qemuDomainValidateDevicePCISlotsLoongson(virDomainDef *def, ++ virDomainPCIAddressSet *addrs) ++{ ++ int ret = -1; ++ virPCIDeviceAddress tmp_addr; ++ char *addrStr = NULL; ++ virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_AUTOASSIGN ++ | VIR_PCI_CONNECT_TYPE_PCI_DEVICE); ++ ++ if (addrs->nbuses) { ++ memset(&tmp_addr, 0, sizeof(tmp_addr)); ++ tmp_addr.slot = 1; ++ /* pci-ohci at 00:01.0 */ ++ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) ++ goto cleanup; ++ } ++ ++ if (def->nvideos > 0 && ++ def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_NONE && ++ def->videos[0]->type != VIR_DOMAIN_VIDEO_TYPE_RAMFB) { ++ /*reserve slot 2 for vga device */ ++ virDomainVideoDef *primaryVideo = def->videos[0]; ++ ++ if (virDeviceInfoPCIAddressIsWanted(&primaryVideo->info)) { ++ memset(&tmp_addr, 0, sizeof(tmp_addr)); ++ tmp_addr.slot = 2; ++ ++ if (!(addrStr = virPCIDeviceAddressAsString(&tmp_addr))) ++ goto cleanup; ++ if (!virDomainPCIAddressValidate(addrs, &tmp_addr, ++ addrStr, flags, true)) ++ goto cleanup; ++ ++ if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { ++ if (qemuDomainPCIAddressReserveNextAddr(addrs, ++ &primaryVideo->info) < 0) ++ goto cleanup; ++ } else { ++ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) ++ goto cleanup; ++ primaryVideo->info.addr.pci = tmp_addr; ++ primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; ++ } ++ } ++ } ++ ret = 0; ++ cleanup: ++ VIR_FREE(addrStr); ++ return ret; ++} ++ ++ + static int + qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def, + virDomainPCIAddressSet *addrs) +@@ -2040,6 +2093,11 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def, + return -1; + } + ++ if (qemuDomainIsLoongson(def) && ++ qemuDomainValidateDevicePCISlotsLoongson(def, addrs) < 0) { ++ return -1; ++ } ++ + return 0; + } + +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index 7bc14293d6..7d01d31aaf 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -186,7 +186,8 @@ qemuValidateDomainDefFeatures(const virDomainDef *def, + switch ((virDomainFeature) i) { + case VIR_DOMAIN_FEATURE_IOAPIC: + if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) { +- if (!ARCH_IS_X86(def->os.arch)) { ++ if (!(ARCH_IS_X86(def->os.arch) ++ || ARCH_IS_LOONGARCH(def->os.arch))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The '%s' feature is not supported for " + "architecture '%s' or machine type '%s'"), +diff --git a/src/util/virarch.c b/src/util/virarch.c +index 2134dd6a9d..9f40a7110c 100644 +--- a/src/util/virarch.c ++++ b/src/util/virarch.c +@@ -59,6 +59,7 @@ static const struct virArchData { + + { "mips64", 64, VIR_ARCH_BIG_ENDIAN }, + { "mips64el", 64, VIR_ARCH_LITTLE_ENDIAN }, ++ { "loongarch64", 64, VIR_ARCH_LITTLE_ENDIAN }, + { "openrisc", 32, VIR_ARCH_BIG_ENDIAN }, + { "parisc", 32, VIR_ARCH_BIG_ENDIAN }, + { "parisc64", 64, VIR_ARCH_BIG_ENDIAN }, +@@ -222,6 +223,8 @@ virArch virArchFromHost(void) + arch = VIR_ARCH_X86_64; + } else if (STREQ(ut.machine, "arm64")) { + arch = VIR_ARCH_AARCH64; ++ } else if (STREQ(ut.machine, "loongarch64")) { ++ arch = VIR_ARCH_LOONGARCH64; + } else { + /* Otherwise assume the canonical name */ + if ((arch = virArchFromString(ut.machine)) == VIR_ARCH_NONE) { +diff --git a/src/util/virarch.h b/src/util/virarch.h +index 528f84f8a5..7d396f2fff 100644 +--- a/src/util/virarch.h ++++ b/src/util/virarch.h +@@ -44,6 +44,7 @@ typedef enum { + + VIR_ARCH_MIPS64, /* MIPS 64 BE https://en.wikipedia.org/wiki/MIPS_architecture */ + VIR_ARCH_MIPS64EL, /* MIPS 64 LE https://en.wikipedia.org/wiki/MIPS_architecture */ ++ VIR_ARCH_LOONGARCH64, + VIR_ARCH_OR32, /* OpenRisc 32 BE https://en.wikipedia.org/wiki/OpenRISC#QEMU_support */ + VIR_ARCH_PARISC, /* PA-Risc 32 BE https://en.wikipedia.org/wiki/PA-RISC */ + VIR_ARCH_PARISC64, /* PA-Risc 64 BE https://en.wikipedia.org/wiki/PA-RISC */ +@@ -98,6 +99,8 @@ typedef enum { + #define ARCH_IS_MIPS64(arch) ((arch) == VIR_ARCH_MIPS64 ||\ + (arch) == VIR_ARCH_MIPS64EL) + ++#define ARCH_IS_LOONGARCH(arch) ((arch) == VIR_ARCH_LOONGARCH64) ++ + typedef enum { + VIR_ARCH_LITTLE_ENDIAN, + VIR_ARCH_BIG_ENDIAN, +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index 35f41daef2..137796ea07 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -546,7 +546,7 @@ virHostCPUParseFrequency(FILE *cpuinfo, + char line[1024]; + + /* No sensible way to retrieve CPU frequency */ +- if (ARCH_IS_ARM(arch)) ++ if (ARCH_IS_ARM(arch) || ARCH_IS_LOONGARCH(arch)) + return 0; + + if (ARCH_IS_X86(arch)) +diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c +index af9e03c5ac..9577cf1910 100644 +--- a/src/util/virsysinfo.c ++++ b/src/util/virsysinfo.c +@@ -1247,7 +1247,7 @@ virSysinfoRead(void) + { + #if defined(__powerpc__) + return virSysinfoReadPPC(); +-#elif defined(__arm__) || defined(__aarch64__) ++#elif defined(__arm__) || defined(__aarch64__) || defined(__loongarch__) + return virSysinfoReadARM(); + #elif defined(__s390__) || defined(__s390x__) + return virSysinfoReadS390(); +-- +2.27.0 + diff --git a/libvirt.spec b/libvirt.spec index f0c0e85..17c0692 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -3,19 +3,20 @@ # This spec file assumes you are building on a Fedora or RHEL version # that's still supported by the vendor. It may work on other distros # or versions, but no effort will be made to ensure that going forward. +%define anolis_release .0.1 %define min_rhel 8 %define min_fedora 33 -%define arches_qemu_kvm %{ix86} x86_64 %{power64} %{arm} aarch64 s390x +%define arches_qemu_kvm %{ix86} x86_64 %{power64} %{arm} aarch64 s390x loongarch64 %if 0%{?rhel} %if 0%{?rhel} > 8 - %define arches_qemu_kvm x86_64 aarch64 s390x + %define arches_qemu_kvm x86_64 aarch64 s390x loongarch64 %else - %define arches_qemu_kvm x86_64 %{power64} aarch64 s390x + %define arches_qemu_kvm x86_64 %{power64} aarch64 s390x loongarch64 %endif %endif -%define arches_64bit x86_64 %{power64} aarch64 s390x riscv64 +%define arches_64bit x86_64 %{power64} aarch64 s390x riscv64 loongarch64 %define arches_x86 %{ix86} x86_64 %define arches_systemtap_64bit %{arches_64bit} @@ -23,9 +24,9 @@ %define arches_xen %{arches_x86} aarch64 %define arches_vbox %{arches_x86} %define arches_ceph %{arches_64bit} -%define arches_zfs %{arches_x86} %{power64} %{arm} -%define arches_numactl %{arches_x86} %{power64} aarch64 s390x -%define arches_numad %{arches_x86} %{power64} aarch64 +%define arches_zfs %{arches_x86} %{power64} %{arm} loongarch64 +%define arches_numactl %{arches_x86} %{power64} aarch64 s390x loongarch64 +%define arches_numad %{arches_x86} %{power64} aarch64 loongarch64 # The hypervisor drivers that run in libvirtd %define with_qemu 0%{!?_without_qemu:1} @@ -210,7 +211,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 8.0.0 -Release: 23.4%{?dist}%{?extra_release} +Release: 23.4%{anolis_release}%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -331,6 +332,7 @@ Patch108: libvirt-libvirt-domain-introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_D Patch109: libvirt-qemu_capabilities-filter-deprecated-features-if-requested.patch Patch110: libvirt-virsh-add-disable-deprecated-features-flag-to-domcapabilities.patch Patch111: libvirt-conf-add-deprecated_features-attribute.patch +Patch1000: libvirt-Add-loongarch-support.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2210,6 +2212,9 @@ exit 0 %changelog +* Mon Aug 11 2025 zhaotianrui - 8.0.0-23.4.0.1 +- Add loongarch support + * Thu Jun 5 2025 Jiri Denemark - 8.0.0-23.4.el8 - util: xml: Introduce virXMLNodeGetSubelementList (RHEL-88716) - util: xml: Return GPtrArray from virXMLNodeGetSubelement [partial] (RHEL-88716) -- Gitee From 5cb02823eb939c54e9bb02130fe408a52c7c5435 Mon Sep 17 00:00:00 2001 From: lixianglai Date: Wed, 31 May 2023 02:27:43 -0400 Subject: [PATCH 3/8] Fix loongarch xml validate Signed-off-by: lixianglai --- libvirt-add-loongarch-edit-xml-validate.patch | 20 +++++++++++++++++++ libvirt.spec | 2 ++ 2 files changed, 22 insertions(+) create mode 100644 libvirt-add-loongarch-edit-xml-validate.patch diff --git a/libvirt-add-loongarch-edit-xml-validate.patch b/libvirt-add-loongarch-edit-xml-validate.patch new file mode 100644 index 0000000..7dba7ec --- /dev/null +++ b/libvirt-add-loongarch-edit-xml-validate.patch @@ -0,0 +1,20 @@ +From 6391d1634db6319d852c65c4e384030dcf568103 Mon Sep 17 00:00:00 2001 +From: zhaotianrui +Date: Wed, 13 Oct 2021 15:51:40 +0800 +Subject: [PATCH] Fix loongarch xml validate + +Signed-off-by: zhaotianrui +--- + +diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng +index 8146527..b58a61a 100644 +--- a/docs/schemas/basictypes.rng ++++ b/docs/schemas/basictypes.rng +@@ -425,6 +425,7 @@ + mipsel + mips64 + mips64el ++ loongarch64 + openrisc + parisc + parisc64 diff --git a/libvirt.spec b/libvirt.spec index 17c0692..c72b640 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -333,6 +333,7 @@ Patch109: libvirt-qemu_capabilities-filter-deprecated-features-if-requested.patc Patch110: libvirt-virsh-add-disable-deprecated-features-flag-to-domcapabilities.patch Patch111: libvirt-conf-add-deprecated_features-attribute.patch Patch1000: libvirt-Add-loongarch-support.patch +Patch1001: libvirt-add-loongarch-edit-xml-validate.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2214,6 +2215,7 @@ exit 0 %changelog * Mon Aug 11 2025 zhaotianrui - 8.0.0-23.4.0.1 - Add loongarch support +- Fix loongarch xml validate * Thu Jun 5 2025 Jiri Denemark - 8.0.0-23.4.el8 - util: xml: Introduce virXMLNodeGetSubelementList (RHEL-88716) -- Gitee From 40d168e58f064e71cf909521eb64df29aa1d9d40 Mon Sep 17 00:00:00 2001 From: xianglai li Date: Fri, 4 Aug 2023 11:18:20 +0800 Subject: [PATCH 4/8] Synchronize upstream patches to fix TPM issues. Fix the exception of adding TPM devices via virt-manager by synchronizing upstream patches. Synchronize upstream patches "Use correct tpm device for all non-x86" Synchronize upstream patches "validate: Drop tpm-tis arch validation" Signed-off-by: xianglai li --- libvirt.spec | 4 +++ ...e-correct-tpm-device-for-all-non-x86.patch | 32 +++++++++++++++++ ...alidate-Drop-tpm-tis-arch-validation.patch | 35 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 qemu-command-Use-correct-tpm-device-for-all-non-x86.patch create mode 100644 qemu-validate-Drop-tpm-tis-arch-validation.patch diff --git a/libvirt.spec b/libvirt.spec index c72b640..640e596 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -334,6 +334,8 @@ Patch110: libvirt-virsh-add-disable-deprecated-features-flag-to-domcapabilities. Patch111: libvirt-conf-add-deprecated_features-attribute.patch Patch1000: libvirt-Add-loongarch-support.patch Patch1001: libvirt-add-loongarch-edit-xml-validate.patch +Patch1004: qemu-validate-Drop-tpm-tis-arch-validation.patch +Patch1005: qemu-command-Use-correct-tpm-device-for-all-non-x86.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2216,6 +2218,8 @@ exit 0 * Mon Aug 11 2025 zhaotianrui - 8.0.0-23.4.0.1 - Add loongarch support - Fix loongarch xml validate +- Synchronize upstream patches "Use correct tpm device for all non-x86" (lixianglai@loongson.cn) +- Synchronize upstream patches "validate: Drop tpm-tis arch validation" (lixianglai@loongson.cn) * Thu Jun 5 2025 Jiri Denemark - 8.0.0-23.4.el8 - util: xml: Introduce virXMLNodeGetSubelementList (RHEL-88716) diff --git a/qemu-command-Use-correct-tpm-device-for-all-non-x86.patch b/qemu-command-Use-correct-tpm-device-for-all-non-x86.patch new file mode 100644 index 0000000..8189141 --- /dev/null +++ b/qemu-command-Use-correct-tpm-device-for-all-non-x86.patch @@ -0,0 +1,32 @@ +From 7c9af5730bc83bde24d6788720f92fceba533124 Mon Sep 17 00:00:00 2001 +From: Cole Robinson +Date: Sat, 18 Jun 2022 12:46:03 -0400 +Subject: [PATCH 2/2] qemu: command: Use correct tpm device for all non-x86 + +The qemu `tpm-tis` device is an ISA device, so only really applicable +to x86 archs. For all non-x86 archs we should use `tpm-tis-device` + +This fixes tpm-tis usage on armv7l and riscv + +Reviewed-by: Michal Privoznik +Signed-off-by: Cole Robinson +--- + src/qemu/qemu_command.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index a7855d3..978ce89 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -9733,7 +9733,7 @@ qemuBuildTPMDevCmd(virCommand *cmd, + const char *model = virDomainTPMModelTypeToString(tpm->model); + g_autofree char *tpmdev = g_strdup_printf("tpm-%s", tpm->info.alias); + +- if (tpm->model == VIR_DOMAIN_TPM_MODEL_TIS && def->os.arch == VIR_ARCH_AARCH64) ++ if (tpm->model == VIR_DOMAIN_TPM_MODEL_TIS && !ARCH_IS_X86(def->os.arch)) + model = "tpm-tis-device"; + + if (virJSONValueObjectAdd(&props, +-- +2.31.1 + diff --git a/qemu-validate-Drop-tpm-tis-arch-validation.patch b/qemu-validate-Drop-tpm-tis-arch-validation.patch new file mode 100644 index 0000000..178a943 --- /dev/null +++ b/qemu-validate-Drop-tpm-tis-arch-validation.patch @@ -0,0 +1,35 @@ +From d45d539a4aab6702710b877816d93d70f81c0165 Mon Sep 17 00:00:00 2001 +From: Cole Robinson +Date: Sat, 18 Jun 2022 12:52:29 -0400 +Subject: [PATCH 1/2] qemu: validate: Drop tpm-tis arch validation + +Checking against qemu capabilities should be enough here + +Resolves: https://gitlab.com/libvirt/libvirt/-/issues/329 + +Reviewed-by: Michal Privoznik +Signed-off-by: Cole Robinson +--- + src/qemu/qemu_validate.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index 7d01d31..6b65ce4 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -4618,12 +4618,6 @@ qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm, + + switch (tpm->model) { + case VIR_DOMAIN_TPM_MODEL_TIS: +- if (!ARCH_IS_X86(def->os.arch) && (def->os.arch != VIR_ARCH_AARCH64)) { +- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +- _("TPM model '%s' is only available for x86 and aarch64 guests"), +- virDomainTPMModelTypeToString(tpm->model)); +- return -1; +- } + flag = QEMU_CAPS_DEVICE_TPM_TIS; + break; + case VIR_DOMAIN_TPM_MODEL_CRB: +-- +2.31.1 + -- Gitee From 84e554c9a3d5ec0a2bc262fd571bad0c368f3dcc Mon Sep 17 00:00:00 2001 From: Yanjing Zhou Date: Tue, 18 Jun 2024 16:07:33 +0800 Subject: [PATCH 5/8] Add new Dharma CPU model Add Hygon Dharma CPU model to the processor model. Signed-off-by: Yanjing Zhou --- libvirt-cpu-Add-new-Dharma-CPU-model.patch | 131 +++++++++++++++++++++ libvirt.spec | 2 + 2 files changed, 133 insertions(+) create mode 100644 libvirt-cpu-Add-new-Dharma-CPU-model.patch diff --git a/libvirt-cpu-Add-new-Dharma-CPU-model.patch b/libvirt-cpu-Add-new-Dharma-CPU-model.patch new file mode 100644 index 0000000..39c6176 --- /dev/null +++ b/libvirt-cpu-Add-new-Dharma-CPU-model.patch @@ -0,0 +1,131 @@ +From 654e5425700bcc5ece7a414061a504283ae24727 Mon Sep 17 00:00:00 2001 +From: Yanjing Zhou +Date: Tue, 11 Jun 2024 16:00:14 +0800 +Subject: [PATCH] cpu: Add new Dharma CPU model + +Add Hygon Dharma CPU model to the processor model. + +Signed-off-by: Yanjing Zhou +--- + src/cpu_map/index.xml | 1 + + src/cpu_map/meson.build | 1 + + src/cpu_map/x86_Dharma.xml | 83 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 85 insertions(+) + create mode 100644 src/cpu_map/x86_Dharma.xml + +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index ffe1fa9..9419674 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -72,6 +72,7 @@ + + + ++ + + + +diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build +index 013fc62..c2a7052 100644 +--- a/src/cpu_map/meson.build ++++ b/src/cpu_map/meson.build +@@ -31,6 +31,7 @@ cpumap_data = [ + 'x86_coreduo.xml', + 'x86_cpu64-rhel5.xml', + 'x86_cpu64-rhel6.xml', ++ 'x86_Dharma.xml', + 'x86_Dhyana.xml', + 'x86_EPYC-IBPB.xml', + 'x86_EPYC.xml', +diff --git a/src/cpu_map/x86_Dharma.xml b/src/cpu_map/x86_Dharma.xml +new file mode 100644 +index 0000000..bf20116 +--- /dev/null ++++ b/src/cpu_map/x86_Dharma.xml +@@ -0,0 +1,83 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.39.3 + diff --git a/libvirt.spec b/libvirt.spec index 640e596..873b202 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -336,6 +336,7 @@ Patch1000: libvirt-Add-loongarch-support.patch Patch1001: libvirt-add-loongarch-edit-xml-validate.patch Patch1004: qemu-validate-Drop-tpm-tis-arch-validation.patch Patch1005: qemu-command-Use-correct-tpm-device-for-all-non-x86.patch +Patch1006: libvirt-cpu-Add-new-Dharma-CPU-model.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2220,6 +2221,7 @@ exit 0 - Fix loongarch xml validate - Synchronize upstream patches "Use correct tpm device for all non-x86" (lixianglai@loongson.cn) - Synchronize upstream patches "validate: Drop tpm-tis arch validation" (lixianglai@loongson.cn) +- Add new Dharma CPU model (zhouyanjing@hygon.cn) * Thu Jun 5 2025 Jiri Denemark - 8.0.0-23.4.el8 - util: xml: Introduce virXMLNodeGetSubelementList (RHEL-88716) -- Gitee From 7a26bd0fc4044c0aea679c50ebde0832665ad0db Mon Sep 17 00:00:00 2001 From: Jiakun Shuai Date: Fri, 20 Sep 2024 16:10:31 +0800 Subject: [PATCH 6/8] libvirt: phytium: add Phytium S5000C cpu model add Phytium S5000C cpu model. Signed-off-by: Peng Mengguang Signed-off-by: Jiakun Shuai --- libvirt-cpu-map-add-S5000C-cpu-model.patch | 54 ++++++++++++++++++++++ libvirt.spec | 2 + 2 files changed, 56 insertions(+) create mode 100644 libvirt-cpu-map-add-S5000C-cpu-model.patch diff --git a/libvirt-cpu-map-add-S5000C-cpu-model.patch b/libvirt-cpu-map-add-S5000C-cpu-model.patch new file mode 100644 index 0000000..73c051a --- /dev/null +++ b/libvirt-cpu-map-add-S5000C-cpu-model.patch @@ -0,0 +1,54 @@ +From 0b896a38e152b7350d9f685ec898ff9ff0f86ebe Mon Sep 17 00:00:00 2001 +From: Peng Mengguang +Date: Thu, 12 Sep 2024 10:57:23 -0400 +Subject: [PATCH] cpu_map: add S5000C cpu model + + add Phytium S5000C cpu model. + +Signed-off-by: Peng Mengguang +--- + src/cpu_map/arm_Tengyun-S5000C.xml | 6 ++++++ + src/cpu_map/index.xml | 1 + + src/cpu_map/meson.build | 1 + + 3 files changed, 8 insertions(+) + create mode 100644 src/cpu_map/arm_Tengyun-S5000C.xml + +diff --git a/src/cpu_map/arm_Tengyun-S5000C.xml b/src/cpu_map/arm_Tengyun-S5000C.xml +new file mode 100644 +index 0000000000..f8fa593c19 +--- /dev/null ++++ b/src/cpu_map/arm_Tengyun-S5000C.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 150535fac4..3ae9348bc5 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -110,6 +110,7 @@ + + + ++ + + + +diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build +index 42d2105f2a..baeffa3b70 100644 +--- a/src/cpu_map/meson.build ++++ b/src/cpu_map/meson.build +@@ -7,6 +7,7 @@ cpumap_data = [ + 'arm_features.xml', + 'arm_Kunpeng-920.xml', + 'arm_Tengyun-S2500.xml', ++ 'arm_Tengyun-S5000C.xml', + 'arm_ThunderX299xx.xml', + 'arm_vendors.xml', + 'index.xml', +-- +2.39.3 + diff --git a/libvirt.spec b/libvirt.spec index 873b202..08e5e5b 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -337,6 +337,7 @@ Patch1001: libvirt-add-loongarch-edit-xml-validate.patch Patch1004: qemu-validate-Drop-tpm-tis-arch-validation.patch Patch1005: qemu-command-Use-correct-tpm-device-for-all-non-x86.patch Patch1006: libvirt-cpu-Add-new-Dharma-CPU-model.patch +Patch1007: libvirt-cpu-map-add-S5000C-cpu-model.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2222,6 +2223,7 @@ exit 0 - Synchronize upstream patches "Use correct tpm device for all non-x86" (lixianglai@loongson.cn) - Synchronize upstream patches "validate: Drop tpm-tis arch validation" (lixianglai@loongson.cn) - Add new Dharma CPU model (zhouyanjing@hygon.cn) +- Add Phytium S5000C CPU model (shuaijiakun1288@phytium.com.cn) * Thu Jun 5 2025 Jiri Denemark - 8.0.0-23.4.el8 - util: xml: Introduce virXMLNodeGetSubelementList (RHEL-88716) -- Gitee From 335a6600c8cd0df5046784ec5f3650d5d45b176a Mon Sep 17 00:00:00 2001 From: yujiayi <3076710949@qq.com> Date: Sun, 29 Sep 2024 14:46:29 +0800 Subject: [PATCH 7/8] Add sw64arch support for libvirt-8.0.0 Signed-off-by: lufeifei --- ...w64-architecture-support-for-libvirt.patch | 687 ++++++++++++++++++ libvirt.spec | 8 +- 2 files changed, 692 insertions(+), 3 deletions(-) create mode 100644 libvirt-Add-sw64-architecture-support-for-libvirt.patch diff --git a/libvirt-Add-sw64-architecture-support-for-libvirt.patch b/libvirt-Add-sw64-architecture-support-for-libvirt.patch new file mode 100644 index 0000000..7654027 --- /dev/null +++ b/libvirt-Add-sw64-architecture-support-for-libvirt.patch @@ -0,0 +1,687 @@ +From 6053366caf3573323e1436fc7c3e4e13d26fd3c2 Mon Sep 17 00:00:00 2001 +From: Chen Wang +Date: Wed, 25 May 2022 09:42:04 +0800 +Subject: [PATCH] sw_64: Add sw64 architecture support for libvirt-8.0.0 + +Signed-off-by: Chen Wang +--- + docs/schemas/basictypes.rng | 1 + + docs/schemas/domaincommon.rng | 1 + + meson.build | 2 +- + src/cpu/cpu.c | 2 + + src/cpu/cpu_sw64.c | 302 ++++++++++++++++++++++++++++++++++ + src/cpu/cpu_sw64.h | 31 ++++ + src/cpu/meson.build | 1 + + src/cpu_map/index.xml | 5 + + src/cpu_map/meson.build | 2 + + src/cpu_map/sw64_core3.xml | 4 + + src/cpu_map/sw64_core4.xml | 4 + + src/qemu/qemu_capabilities.c | 12 ++ + src/qemu/qemu_domain.c | 15 +- + src/util/virarch.c | 6 + + src/util/virarch.h | 3 + + src/util/virhostcpu.c | 2 + + src/util/virprocess.c | 2 + + src/util/virsysinfo.c | 3 +- + 18 files changed, 393 insertions(+), 5 deletions(-) + create mode 100644 src/cpu/cpu_sw64.c + create mode 100644 src/cpu/cpu_sw64.h + create mode 100644 src/cpu_map/sw64_core3.xml + create mode 100644 src/cpu_map/sw64_core4.xml + +diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng +index ab18b18..e0724fe 100644 +--- a/docs/schemas/basictypes.rng ++++ b/docs/schemas/basictypes.rng +@@ -460,6 +460,7 @@ + sh4eb + sparc + sparc64 ++ sw_64 + unicore32 + x86_64 + xtensa +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index 79c8979..c2bd970 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -2613,6 +2613,7 @@ + pcie-pci-bridge + + ioh3420 ++ pcie-root + pcie-root-port + + x3130-upstream +diff --git a/meson.build b/meson.build +index 214a3f0..e76cf4e 100644 +--- a/meson.build ++++ b/meson.build +@@ -1596,7 +1596,7 @@ elif get_option('driver_lxc').enabled() + error('linux and remote_driver are required for LXC') + endif + +-if not get_option('driver_ch').disabled() and host_machine.system() == 'linux' and (host_machine.cpu_family() == 'x86_64' or host_machine.cpu_family() == 'aarch64') ++if not get_option('driver_ch').disabled() and host_machine.system() == 'linux' and (host_machine.cpu_family() == 'x86_64' or host_machine.cpu_family() == 'aarch64' or host_machine.cpu_family() == 'sw_64') + use_ch = true + + if not conf.has('WITH_LIBVIRTD') +diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c +index 49527c3..d11bcc9 100644 +--- a/src/cpu/cpu.c ++++ b/src/cpu/cpu.c +@@ -29,6 +29,7 @@ + #include "cpu_ppc64.h" + #include "cpu_s390.h" + #include "cpu_arm.h" ++#include "cpu_sw64.h" + #include "capabilities.h" + #include "virstring.h" + #include "cpu_loongarch.h" +@@ -43,6 +44,7 @@ static struct cpuArchDriver *drivers[] = { + &cpuDriverS390, + &cpuDriverArm, + &cpuDriverLoongArch, ++ &cpuDriverSW64, + }; + + +diff --git a/src/cpu/cpu_sw64.c b/src/cpu/cpu_sw64.c +new file mode 100644 +index 0000000..199ed60 +--- /dev/null ++++ b/src/cpu/cpu_sw64.c +@@ -0,0 +1,302 @@ ++/* ++ * cpu_sw64.c: CPU driver for sw64 CPUs ++ * ++ * Copyright (C) 2021 Lu Feifei ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ * ++ * Authors: ++ * Lu Feifei ++ */ ++ ++#include ++ ++#include "virfile.h" ++#include "viralloc.h" ++#include "cpu.h" ++#include "cpu_sw64.h" ++#include "cpu_map.h" ++#include "virstring.h" ++#include "virhostcpu.h" ++ ++#define VIR_FROM_THIS VIR_FROM_CPU ++#define CPUINFO_PATH "/proc/cpuinfo" ++ ++static const virArch archs[] = { VIR_ARCH_SW_64 }; ++ ++typedef struct _sw64Model sw64Model; ++struct _sw64Model { ++ char *name; ++}; ++ ++typedef struct _sw64Map sw64Map; ++struct _sw64Map { ++ size_t nmodels; ++ sw64Model **models; ++}; ++ ++static virCPUCompareResult ++virCPUsw64Compare(virCPUDef *host ATTRIBUTE_UNUSED, ++ virCPUDef *cpu ATTRIBUTE_UNUSED, ++ bool failMessages ATTRIBUTE_UNUSED) ++{ ++ return VIR_CPU_COMPARE_IDENTICAL; ++} ++ ++static int ++virCPUsw64Update(virCPUDef *guest, ++ const virCPUDef *host, ++ bool relative) ++{ ++ g_autoptr(virCPUDef) updated = NULL; ++ ++ if (!relative || guest->mode != VIR_CPU_MODE_HOST_MODEL) ++ return 0; ++ ++ if (!host) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("unknown host CPU model")); ++ return -1; ++ } ++ ++ if (!(updated = virCPUDefCopyWithoutModel(guest))) ++ return -1; ++ ++ updated->mode = VIR_CPU_MODE_CUSTOM; ++ if (virCPUDefCopyModel(updated, host, true) < 0) ++ return -1; ++ ++ virCPUDefStealModel(guest, updated, false); ++ guest->mode = VIR_CPU_MODE_CUSTOM; ++ guest->match = VIR_CPU_MATCH_EXACT; ++ ++ return 0; ++} ++ ++static void ++sw64ModelFree(sw64Model *model) ++{ ++ if (!model) ++ return; ++ ++ VIR_FREE(model->name); ++ VIR_FREE(model); ++} ++ ++static void ++sw64MapFree(sw64Map *map) ++{ ++ size_t i; ++ ++ if (!map) ++ return; ++ ++ for (i = 0; i < map->nmodels; i++) ++ sw64ModelFree(map->models[i]); ++ VIR_FREE(map->models); ++ VIR_FREE(map); ++} ++ ++static sw64Model * ++sw64ModelFind(const sw64Map *map, ++ const char *name) ++{ ++ size_t i; ++ ++ for (i = 0; i < map->nmodels; i++) { ++ if (STREQ(map->models[i]->name, name)) ++ return map->models[i]; ++ } ++ ++ return NULL; ++} ++ ++static int ++sw64ModelParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, ++ const char *name, ++ void *data) ++{ ++ sw64Map *map = data; ++ sw64Model *model; ++ int ret = -1; ++ ++ model = g_new0(sw64Model, 1); ++ ++ model->name = g_strdup(name); ++ ++ if (sw64ModelFind(map, model->name)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("CPU model %s already defined"), model->name); ++ goto cleanup; ++ } ++ ++ VIR_APPEND_ELEMENT(map->models, map->nmodels, model); ++ ++ ret = 0; ++ ++ cleanup: ++ sw64ModelFree(model); ++ return ret; ++} ++ ++static sw64Map * ++sw64LoadMap(void) ++{ ++ sw64Map *map; ++ ++ map = g_new0(sw64Map, 1); ++ ++ if (cpuMapLoad("sw64", NULL, NULL, sw64ModelParse, map) < 0) ++ goto error; ++ ++ return map; ++ ++ error: ++ sw64MapFree(map); ++ return NULL; ++} ++ ++static int ++sw64CPUParseCpuModeString(const char *str, ++ const char *prefix, ++ unsigned int *mode) ++{ ++ char *p; ++ unsigned int ui; ++ /* If the string doesn't start with the expected prefix, then ++ * we're not looking at the right string and we should move on */ ++ if (!STRPREFIX(str, prefix)) ++ return 1; ++ /* Skip the prefix */ ++ str += strlen(prefix); ++ ++ /* Skip all whitespace */ ++ while (g_ascii_isspace(*str)) ++ str++; ++ if (*str == '\0') ++ goto error; ++ ++ /* Skip the colon. If anything but a colon is found, then we're ++ * not looking at the right string and we should move on */ ++ if (*str != ':') ++ return 1; ++ str++; ++ ++ /* Skip all whitespace */ ++ while (g_ascii_isspace(*str)) ++ str++; ++ if (*str == '\0') ++ goto error; ++ ++ if (virStrToLong_ui(str, &p, 10, &ui) < 0 || ++ (*p != '.' && *p != '\0' && !g_ascii_isspace(*p))) { ++ goto error; ++ } ++ ++ *mode = ui; ++ return 0; ++ ++ error: ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing or invalid CPU variation in %s"), ++ CPUINFO_PATH); ++ return -1; ++} ++ ++static int ++sw64CPUParseCpuMode(FILE *cpuinfo, unsigned int *mode) ++{ ++ const char *prefix = "cpu variation"; ++ char line[1024]; ++ ++ while (fgets(line, sizeof(line), cpuinfo) != NULL) { ++ if (sw64CPUParseCpuModeString(line, prefix, mode) < 0) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ++virCPUsw64GetHost(virCPUDef *cpu, ++ virDomainCapsCPUModels *models ATTRIBUTE_UNUSED) ++{ ++ int ret = -1; ++ unsigned int mode; ++ FILE *cpuinfo = fopen(CPUINFO_PATH, "r"); ++ if (!cpuinfo) { ++ virReportSystemError(errno, ++ _("cannot open %s"), CPUINFO_PATH); ++ return -1; ++ } ++ ++ ret = sw64CPUParseCpuMode(cpuinfo, &mode); ++ if (ret < 0) ++ goto cleanup; ++ ++ if (mode == 3) ++ cpu->model = g_strdup("core3"); ++ else if (mode == 4) ++ cpu->model = g_strdup("core4"); ++ ++ cleanup: ++ VIR_FORCE_FCLOSE(cpuinfo); ++ return ret; ++} ++ ++static int ++virCPUsw64DriverGetModels(char ***models) ++{ ++ sw64Map *map; ++ size_t i; ++ int ret = -1; ++ ++ if (!(map = sw64LoadMap())) ++ goto error; ++ ++ if (models) { ++ *models = g_new0(char *, map->nmodels + 1); ++ ++ for (i = 0; i < map->nmodels; i++) { ++ (*models)[i] = g_strdup(map->models[i]->name); ++ } ++ } ++ ++ ret = map->nmodels; ++ ++ cleanup: ++ sw64MapFree(map); ++ return ret; ++ ++ error: ++ if (models) { ++ g_strfreev(*models); ++ *models = NULL; ++ } ++ goto cleanup; ++} ++ ++struct cpuArchDriver cpuDriverSW64 = { ++ .name = "sw_64", ++ .arch = archs, ++ .narch = G_N_ELEMENTS(archs), ++ .getHost = virCPUsw64GetHost, ++ .compare = virCPUsw64Compare, ++ .decode = NULL, ++ .encode = NULL, ++ .baseline = NULL, ++ .update = virCPUsw64Update, ++ .getModels = virCPUsw64DriverGetModels, ++}; +diff --git a/src/cpu/cpu_sw64.h b/src/cpu/cpu_sw64.h +new file mode 100644 +index 0000000..211a7cf +--- /dev/null ++++ b/src/cpu/cpu_sw64.h +@@ -0,0 +1,31 @@ ++/* ++ * cpu_sw64.h: CPU driver for sw64 CPUs ++ * ++ * Copyright (C) 2021 Lu Feifei ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see ++ * . ++ * ++ * Authors: ++ * Lu Feifei ++ */ ++ ++#ifndef __VIR_CPU_SW64_H__ ++# define __VIR_CPU_SW64_H__ ++ ++# include "cpu.h" ++ ++extern struct cpuArchDriver cpuDriverSW64; ++ ++#endif /* __VIR_CPU_SW64_H__ */ +diff --git a/src/cpu/meson.build b/src/cpu/meson.build +index ad2f859..5e99dbd 100644 +--- a/src/cpu/meson.build ++++ b/src/cpu/meson.build +@@ -1,6 +1,7 @@ + cpu_sources = [ + 'cpu.c', + 'cpu_arm.c', ++ 'cpu_sw64.c', + 'cpu_map.c', + 'cpu_ppc64.c', + 'cpu_s390.c', +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 3ae9348..5d1a999 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -113,6 +113,11 @@ + + + ++ ++ ++ ++ ++ + + + +diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build +index baeffa3..3871f09 100644 +--- a/src/cpu_map/meson.build ++++ b/src/cpu_map/meson.build +@@ -79,6 +79,8 @@ cpumap_data = [ + 'x86_vendors.xml', + 'x86_Westmere-IBRS.xml', + 'x86_Westmere.xml', ++ 'sw64_core3.xml', ++ 'sw64_core4.xml', + 'loongarch_vendors.xml', + 'ls_3a5000.xml', + ] +diff --git a/src/cpu_map/sw64_core3.xml b/src/cpu_map/sw64_core3.xml +new file mode 100644 +index 0000000..ec3fa0e +--- /dev/null ++++ b/src/cpu_map/sw64_core3.xml +@@ -0,0 +1,4 @@ ++ ++ ++ ++ +diff --git a/src/cpu_map/sw64_core4.xml b/src/cpu_map/sw64_core4.xml +new file mode 100644 +index 0000000..11e763b +--- /dev/null ++++ b/src/cpu_map/sw64_core4.xml +@@ -0,0 +1,4 @@ ++ ++ ++ ++ +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 75668c6..ca47a7a 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -771,6 +771,8 @@ virArch virQEMUCapsArchFromString(const char *arch) + return VIR_ARCH_ARMV7L; + if (STREQ(arch, "or32")) + return VIR_ARCH_OR32; ++ if (STREQ(arch, "sw64")) ++ return VIR_ARCH_SW_64; + + return virArchFromString(arch); + } +@@ -784,6 +786,8 @@ const char *virQEMUCapsArchToString(virArch arch) + return "arm"; + if (arch == VIR_ARCH_OR32) + return "or32"; ++ if (arch == VIR_ARCH_SW_64) ++ return "sw64"; + + return virArchToString(arch); + } +@@ -2072,6 +2076,10 @@ bool virQEMUCapsHasPCIMultiBus(const virDomainDef *def) + * since forever */ + if (ARCH_IS_X86(def->os.arch)) + return true; ++ /* sw_64 support PCI-multibus on all machine types ++ * since forever */ ++ if (ARCH_IS_SW64(def->os.arch)) ++ return true; + + if (STRPREFIX(def->os.machine,"loongson7a")) + return true; +@@ -2718,6 +2726,8 @@ static const char *preferredMachines[] = + + "sim", /* VIR_ARCH_XTENSA */ + "sim", /* VIR_ARCH_XTENSAEB */ ++ ++ "core3", /* VIR_ARCH_SW_64 */ + }; + G_STATIC_ASSERT(G_N_ELEMENTS(preferredMachines) == VIR_ARCH_LAST); + +@@ -5129,6 +5139,8 @@ virQEMUCapsInitQMPBasicArch(virQEMUCaps *qemuCaps) + case VIR_ARCH_XTENSAEB: + case VIR_ARCH_NONE: + case VIR_ARCH_LAST: ++ case VIR_ARCH_SW_64: ++ + default: + break; + } +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 7a53b93..f32fdcb 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -3740,6 +3740,10 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver, + addPCIRoot = true; + break; + ++ case VIR_ARCH_SW_64: ++ addPCIeRoot = true; ++ break; ++ + case VIR_ARCH_ARMV7B: + case VIR_ARCH_CRIS: + case VIR_ARCH_ITANIUM: +@@ -5099,7 +5103,10 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont, + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; + else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; +- } ++ } else if (def->os.arch == VIR_ARCH_SW_64) { ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI)) ++ cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; ++ } + } + /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */ + if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1 || +@@ -5396,7 +5403,8 @@ qemuDomainDefaultVideoDevice(const virDomainDef *def, + return VIR_DOMAIN_VIDEO_TYPE_VGA; + if (qemuDomainIsARMVirt(def) || + qemuDomainIsRISCVVirt(def) || +- ARCH_IS_S390(def->os.arch)) { ++ ARCH_IS_S390(def->os.arch) || ++ ARCH_IS_SW64(def->os.arch)) { + return VIR_DOMAIN_VIDEO_TYPE_VIRTIO; + } + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA)) +@@ -8705,7 +8713,8 @@ qemuDomainMachineHasBuiltinIDE(const char *machine, + return qemuDomainMachineIsI440FX(machine, arch) || + STREQ(machine, "malta") || + STREQ(machine, "sun4u") || +- STREQ(machine, "g3beige") || ++ STRPREFIX(machine, "core") || ++ STREQ(machine, "g3beige") || + STREQ(machine, "loongson3a") || + STREQ(machine, "loongson7a"); + } +diff --git a/src/util/virarch.c b/src/util/virarch.c +index 9f40a71..ce149a4 100644 +--- a/src/util/virarch.c ++++ b/src/util/virarch.c +@@ -84,6 +84,8 @@ static const struct virArchData { + + { "xtensa", 32, VIR_ARCH_LITTLE_ENDIAN }, + { "xtensaeb", 32, VIR_ARCH_BIG_ENDIAN }, ++ ++ { "sw_64", 64, VIR_ARCH_LITTLE_ENDIAN }, + }; + + G_STATIC_ASSERT(G_N_ELEMENTS(virArchData) == VIR_ARCH_LAST); +@@ -197,6 +199,8 @@ virArch virArchFromHost(void) + return VIR_ARCH_ARMV7L; + case PROCESSOR_ARCHITECTURE_ARM64: + return VIR_ARCH_AARCH64; ++ case PROCESSOR_ARCHITECTURE_SW64: ++ return VIR_ARCH_SW_64; + default: + VIR_WARN("Unknown host arch '%d', report to libvir-list@redhat.com", + info.wProcessorArchitecture); +@@ -221,6 +225,8 @@ virArch virArchFromHost(void) + arch = VIR_ARCH_I686; + } else if (STREQ(ut.machine, "amd64")) { + arch = VIR_ARCH_X86_64; ++ } else if (STREQ(ut.machine, "sw_64")) { ++ arch = VIR_ARCH_SW_64; + } else if (STREQ(ut.machine, "arm64")) { + arch = VIR_ARCH_AARCH64; + } else if (STREQ(ut.machine, "loongarch64")) { +diff --git a/src/util/virarch.h b/src/util/virarch.h +index 7d396f2..2e4f7c9 100644 +--- a/src/util/virarch.h ++++ b/src/util/virarch.h +@@ -70,6 +70,8 @@ typedef enum { + VIR_ARCH_XTENSA, /* XTensa 32 LE https://en.wikipedia.org/wiki/Xtensa#Processor_Cores */ + VIR_ARCH_XTENSAEB, /* XTensa 32 BE https://en.wikipedia.org/wiki/Xtensa#Processor_Cores */ + ++ VIR_ARCH_SW_64, /* SW_64 64 LE XHB */ ++ + VIR_ARCH_LAST, + } virArch; + +@@ -98,6 +100,7 @@ typedef enum { + + #define ARCH_IS_MIPS64(arch) ((arch) == VIR_ARCH_MIPS64 ||\ + (arch) == VIR_ARCH_MIPS64EL) ++#define ARCH_IS_SW64(arch) ((arch) == VIR_ARCH_SW_64) + + #define ARCH_IS_LOONGARCH(arch) ((arch) == VIR_ARCH_LOONGARCH64) + +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index 137796e..2572229 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -555,6 +555,8 @@ virHostCPUParseFrequency(FILE *cpuinfo, + prefix = "clock"; + else if (ARCH_IS_S390(arch)) + prefix = "cpu MHz dynamic"; ++ else if (ARCH_IS_SW64(arch)) ++ prefix = "cpu frequency [MHz]"; + + if (!prefix) { + VIR_WARN("%s is not supported by the %s parser", +diff --git a/src/util/virprocess.c b/src/util/virprocess.c +index f3933a2..04095e0 100644 +--- a/src/util/virprocess.c ++++ b/src/util/virprocess.c +@@ -89,6 +89,8 @@ VIR_LOG_INIT("util.process"); + # define __NR_setns 350 + # elif defined(__s390__) + # define __NR_setns 339 ++# elif defined(__sw_64__) ++# define __NR_setns 501 + # endif + # endif + +diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c +index 9577cf1..4cdbf32 100644 +--- a/src/util/virsysinfo.c ++++ b/src/util/virsysinfo.c +@@ -1254,7 +1254,8 @@ virSysinfoRead(void) + #elif !defined(WIN32) && \ + (defined(__x86_64__) || \ + defined(__i386__) || \ +- defined(__amd64__)) ++ defined(__amd64__) || \ ++ defined(__sw_64__)) + return virSysinfoReadDMI(); + #else /* WIN32 || not supported arch */ + /* +-- +2.17.1 + diff --git a/libvirt.spec b/libvirt.spec index 08e5e5b..6aa8d5e 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -7,7 +7,7 @@ %define min_rhel 8 %define min_fedora 33 -%define arches_qemu_kvm %{ix86} x86_64 %{power64} %{arm} aarch64 s390x loongarch64 +%define arches_qemu_kvm %{ix86} x86_64 %{power64} %{arm} aarch64 s390x loongarch64 sw_64 %if 0%{?rhel} %if 0%{?rhel} > 8 %define arches_qemu_kvm x86_64 aarch64 s390x loongarch64 @@ -16,7 +16,7 @@ %endif %endif -%define arches_64bit x86_64 %{power64} aarch64 s390x riscv64 loongarch64 +%define arches_64bit x86_64 %{power64} aarch64 s390x riscv64 loongarch64 sw_64 %define arches_x86 %{ix86} x86_64 %define arches_systemtap_64bit %{arches_64bit} @@ -24,7 +24,7 @@ %define arches_xen %{arches_x86} aarch64 %define arches_vbox %{arches_x86} %define arches_ceph %{arches_64bit} -%define arches_zfs %{arches_x86} %{power64} %{arm} loongarch64 +%define arches_zfs %{arches_x86} %{power64} %{arm} loongarch64 sw_64 %define arches_numactl %{arches_x86} %{power64} aarch64 s390x loongarch64 %define arches_numad %{arches_x86} %{power64} aarch64 loongarch64 @@ -338,6 +338,7 @@ Patch1004: qemu-validate-Drop-tpm-tis-arch-validation.patch Patch1005: qemu-command-Use-correct-tpm-device-for-all-non-x86.patch Patch1006: libvirt-cpu-Add-new-Dharma-CPU-model.patch Patch1007: libvirt-cpu-map-add-S5000C-cpu-model.patch +Patch1008: libvirt-Add-sw64-architecture-support-for-libvirt.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2224,6 +2225,7 @@ exit 0 - Synchronize upstream patches "validate: Drop tpm-tis arch validation" (lixianglai@loongson.cn) - Add new Dharma CPU model (zhouyanjing@hygon.cn) - Add Phytium S5000C CPU model (shuaijiakun1288@phytium.com.cn) +- Add sw64arch support (lufeifei@wxiat.com) * Thu Jun 5 2025 Jiri Denemark - 8.0.0-23.4.el8 - util: xml: Introduce virXMLNodeGetSubelementList (RHEL-88716) -- Gitee From fa63893208fe6e6f05af01e6e91c2e98e0c62623 Mon Sep 17 00:00:00 2001 From: hanliyang Date: Wed, 1 Jan 2025 05:44:37 +0000 Subject: [PATCH 8/8] [Feature]Hygon: Support reuse ASID and secret injection for Hygon CSV VMs to #bug13124 Supports ASID reuse for confidential VMs, supports automatic injection of secrets into Hygon confidential VMs. project: TC2024080203 Signed-off-by: hanliyang --- ...bvirt-support-reuse-id-for-hygon-CSV.patch | 89 ++++++++++++ ...t-provide-inject-secret-for-Hygon-CS.patch | 129 ++++++++++++++++++ libvirt.spec | 4 + 3 files changed, 222 insertions(+) create mode 100644 1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch create mode 100644 1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch diff --git a/1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch b/1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch new file mode 100644 index 0000000..b9b178a --- /dev/null +++ b/1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch @@ -0,0 +1,89 @@ +From f5f6b60a6f8d58bbece7db96730cd506cd5703ee Mon Sep 17 00:00:00 2001 +From: panpingsheng +Date: Fri, 8 Sep 2023 15:04:44 +0800 +Subject: [PATCH 1/2] conf: qemu: add libvirt support reuse id for hygon CSV + +csv xml format: + + 0x0081 + 47 + 5 + usertest + + +Signed-off-by: panpingsheng +Signed-off-by: Xin Jiang +Signed-off-by: hanliyang +--- + src/conf/domain_conf.c | 5 +++++ + src/conf/domain_conf.h | 1 + + src/qemu/qemu_command.c | 4 ++++ + 3 files changed, 10 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 427e7d1..85a5d9c 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -3560,6 +3560,7 @@ virDomainSecDefFree(virDomainSecDef *def) + case VIR_DOMAIN_LAUNCH_SECURITY_SEV: + g_free(def->data.sev.dh_cert); + g_free(def->data.sev.session); ++ g_free(def->data.sev.user_id); + break; + case VIR_DOMAIN_LAUNCH_SECURITY_PV: + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: +@@ -14850,6 +14851,7 @@ virDomainSEVDefParseXML(virDomainSEVDef *def, + def->policy = policy; + def->dh_cert = virXPathString("string(./dhCert)", ctxt); + def->session = virXPathString("string(./session)", ctxt); ++ def->user_id = virXPathString("string(./userid)", ctxt); + + return 0; + } +@@ -27179,6 +27181,9 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec) + if (sev->session) + virBufferEscapeString(&childBuf, "%s\n", sev->session); + ++ if (sev->user_id) ++ virBufferEscapeString(&childBuf, "%s\n", sev->user_id); ++ + break; + } + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 930af36..768ba5f 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2717,6 +2717,7 @@ struct _virDomainSEVDef { + bool haveReducedPhysBits; + unsigned int reduced_phys_bits; + virTristateBool kernel_hashes; ++ char *user_id; + }; + + struct _virDomainSecDef { +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 978ce89..d742ac4 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -9930,6 +9930,9 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, + VIR_DEBUG("policy=0x%x cbitpos=%d reduced_phys_bits=%d", + sev->policy, sev->cbitpos, sev->reduced_phys_bits); + ++ if (sev->user_id) ++ VIR_DEBUG("user_id=%s", sev->user_id); ++ + if (sev->dh_cert) + dhpath = g_strdup_printf("%s/dh_cert.base64", priv->libDir); + +@@ -9940,6 +9943,7 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, + "u:cbitpos", sev->cbitpos, + "u:reduced-phys-bits", sev->reduced_phys_bits, + "u:policy", sev->policy, ++ "S:user-id", sev->user_id, + "S:dh-cert-file", dhpath, + "S:session-file", sessionpath, + "T:kernel-hashes", sev->kernel_hashes, +-- +2.43.5 + diff --git a/1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch b/1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch new file mode 100644 index 0000000..788eecc --- /dev/null +++ b/1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch @@ -0,0 +1,129 @@ +From ad62b677c476440b1a831d4fb8f5f7ef3c7a9975 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Wed, 13 Nov 2024 16:12:57 +0800 +Subject: [PATCH 2/2] conf: qemu: support provide inject secret for Hygon CSV + +csv xml format: + + 0x0001 + 47 + 5 + U2FsdGVkX1+rW6B/JbYqNA== + 5aeG4mH2E/OqN1a3uT8hfg== + gW3E30rG/I3L1nD/YfG+DA== + zP1oY9W7ZcPFtL0QeN11vQ== + + +Signed-off-by: hanliyang +--- + src/conf/domain_conf.c | 8 ++++++++ + src/conf/domain_conf.h | 2 ++ + src/qemu/qemu_command.c | 10 ++++++++++ + src/qemu/qemu_process.c | 10 ++++++++++ + 4 files changed, 30 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 85a5d9c..fa108b1 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -3561,6 +3561,8 @@ virDomainSecDefFree(virDomainSecDef *def) + g_free(def->data.sev.dh_cert); + g_free(def->data.sev.session); + g_free(def->data.sev.user_id); ++ g_free(def->data.sev.secret_header); ++ g_free(def->data.sev.secret); + break; + case VIR_DOMAIN_LAUNCH_SECURITY_PV: + case VIR_DOMAIN_LAUNCH_SECURITY_NONE: +@@ -14852,6 +14854,8 @@ virDomainSEVDefParseXML(virDomainSEVDef *def, + def->dh_cert = virXPathString("string(./dhCert)", ctxt); + def->session = virXPathString("string(./session)", ctxt); + def->user_id = virXPathString("string(./userid)", ctxt); ++ def->secret_header = virXPathString("string(./secretHeader)", ctxt); ++ def->secret = virXPathString("string(./secret)", ctxt); + + return 0; + } +@@ -27183,6 +27187,10 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef *sec) + + if (sev->user_id) + virBufferEscapeString(&childBuf, "%s\n", sev->user_id); ++ if (sev->secret_header) ++ virBufferEscapeString(&childBuf, "%s\n", sev->secret_header); ++ if (sev->secret) ++ virBufferEscapeString(&childBuf, "%s\n", sev->secret); + + break; + } +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 768ba5f..2bc4358 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2718,6 +2718,8 @@ struct _virDomainSEVDef { + unsigned int reduced_phys_bits; + virTristateBool kernel_hashes; + char *user_id; ++ char *secret_header; ++ char *secret; + }; + + struct _virDomainSecDef { +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index d742ac4..2b6b5fb 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -9926,6 +9926,8 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, + qemuDomainObjPrivate *priv = vm->privateData; + g_autofree char *dhpath = NULL; + g_autofree char *sessionpath = NULL; ++ g_autofree char *secretheaderpath = NULL; ++ g_autofree char *secretpath = NULL; + + VIR_DEBUG("policy=0x%x cbitpos=%d reduced_phys_bits=%d", + sev->policy, sev->cbitpos, sev->reduced_phys_bits); +@@ -9939,6 +9941,12 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, + if (sev->session) + sessionpath = g_strdup_printf("%s/session.base64", priv->libDir); + ++ if (sev->secret_header) ++ secretheaderpath = g_strdup_printf("%s/secret_header.base64", priv->libDir); ++ ++ if (sev->secret) ++ secretpath = g_strdup_printf("%s/secret.base64", priv->libDir); ++ + if (qemuMonitorCreateObjectProps(&props, "sev-guest", "lsec0", + "u:cbitpos", sev->cbitpos, + "u:reduced-phys-bits", sev->reduced_phys_bits, +@@ -9947,6 +9955,8 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd, + "S:dh-cert-file", dhpath, + "S:session-file", sessionpath, + "T:kernel-hashes", sev->kernel_hashes, ++ "S:secret-header-file", secretheaderpath, ++ "S:secret-file", secretpath, + NULL) < 0) + return -1; + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 73d54f0..dac44ce 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -6650,6 +6650,16 @@ qemuProcessPrepareSEVGuestInput(virDomainObj *vm) + return -1; + } + ++ if (sev->secret_header) { ++ if (qemuProcessSEVCreateFile(vm, "secret_header", sev->secret_header) < 0) ++ return -1; ++ } ++ ++ if (sev->secret) { ++ if (qemuProcessSEVCreateFile(vm, "secret", sev->secret) < 0) ++ return -1; ++ } ++ + return 0; + } + +-- +2.43.5 + diff --git a/libvirt.spec b/libvirt.spec index 6aa8d5e..8943beb 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -339,6 +339,8 @@ Patch1005: qemu-command-Use-correct-tpm-device-for-all-non-x86.patch Patch1006: libvirt-cpu-Add-new-Dharma-CPU-model.patch Patch1007: libvirt-cpu-map-add-S5000C-cpu-model.patch Patch1008: libvirt-Add-sw64-architecture-support-for-libvirt.patch +Patch1009: 1009-conf-qemu-add-libvirt-support-reuse-id-for-hygon-CSV.patch +Patch1010: 1010-conf-qemu-support-provide-inject-secret-for-Hygon-CS.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2226,6 +2228,8 @@ exit 0 - Add new Dharma CPU model (zhouyanjing@hygon.cn) - Add Phytium S5000C CPU model (shuaijiakun1288@phytium.com.cn) - Add sw64arch support (lufeifei@wxiat.com) +- conf: qemu: add libvirt support reuse id for hygon CSV +- conf: qemu: support provide inject secret for Hygon CSV * Thu Jun 5 2025 Jiri Denemark - 8.0.0-23.4.el8 - util: xml: Introduce virXMLNodeGetSubelementList (RHEL-88716) -- Gitee