From a0eba8baddbfd58aa945ccb147f107686e72f8e8 Mon Sep 17 00:00:00 2001 From: Bo Ren Date: Thu, 14 Dec 2023 17:19:37 +0800 Subject: [PATCH 1/5] update to libvirt-8.0.0-22 Signed-off-by: Bo Ren --- libvirt-Add-loongarch-support.patch | 1233 ----------------- libvirt-add-loongarch-edit-xml-validate.patch | 20 - ...-controller-for-restrictive-numatune.patch | 77 + ...-in-virNodeDeviceGetPCIVPDDynamicCap.patch | 18 +- libvirt-nodedev-update-transient-mdevs.patch | 79 ++ ...e-struct-_qemuMonitorMessage-private.patch | 105 ++ ...elds-from-struct-_qemuMonitorMessage.patch | 44 + ...-_qemuMonitor-to-qemu_monitor_priv.h.patch | 157 +++ ...-block-nodes-supports-flat-parameter.patch | 57 + ...NodeData-Remove-pointless-error-path.patch | 53 + ...d-memory-check-for-vhostuser-daemons.patch | 65 + ...flat-mode-of-query-named-block-nodes.patch | 41 + ...in-virPCIVirtualFunctionList-cleanup.patch | 16 +- libvirt.spec | 61 +- ...e-correct-tpm-device-for-all-non-x86.patch | 32 - ...alidate-Drop-tpm-tis-arch-validation.patch | 35 - 16 files changed, 736 insertions(+), 1357 deletions(-) delete mode 100644 libvirt-Add-loongarch-support.patch delete mode 100644 libvirt-add-loongarch-edit-xml-validate.patch create mode 100644 libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.patch rename node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch => libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch (73%) create mode 100644 libvirt-nodedev-update-transient-mdevs.patch create mode 100644 libvirt-qemu-Make-struct-_qemuMonitorMessage-private.patch create mode 100644 libvirt-qemu-monitor-Drop-old-monitor-fields-from-struct-_qemuMonitorMessage.patch create mode 100644 libvirt-qemu-monitor-Move-declaration-of-struct-_qemuMonitor-to-qemu_monitor_priv.h.patch create mode 100644 libvirt-qemu-monitor-Store-whether-query-named-block-nodes-supports-flat-parameter.patch create mode 100644 libvirt-qemu-qemuBlockGetNamedNodeData-Remove-pointless-error-path.patch create mode 100644 libvirt-qemu-relax-shared-memory-check-for-vhostuser-daemons.patch create mode 100644 libvirt-qemuMonitorJSONBlockStatsUpdateCapacityBlockdev-Use-flat-mode-of-query-named-block-nodes.patch rename virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch => libvirt-virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch (79%) 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/libvirt-Add-loongarch-support.patch b/libvirt-Add-loongarch-support.patch deleted file mode 100644 index 94fd22a..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-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-lib-Set-up-cpuset-controller-for-restrictive-numatune.patch b/libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.patch new file mode 100644 index 0000000..e9e7bc6 --- /dev/null +++ b/libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.patch @@ -0,0 +1,77 @@ +From 08ddc711a2e6d94a0fce55fec8e012a434655d2c Mon Sep 17 00:00:00 2001 +Message-ID: <08ddc711a2e6d94a0fce55fec8e012a434655d2c.1690812875.git.jdenemar@redhat.com> +From: Michal Privoznik +Date: Fri, 1 Apr 2022 14:30:05 +0200 +Subject: [PATCH] lib: Set up cpuset controller for restrictive numatune +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The aim of 'restrictive' numatune mode is to rely solely on +CGroups to have QEMU running on configured NUMA nodes. However, +we were never setting the cpuset controller when a domain was +starting up. We are doing so only when +virDomainSetNumaParameters() is called (aka live pinning). + +This is obviously wrong. Fortunately, fix is simple as +'restrictive' is similar to 'strict' - every location where +VIR_DOMAIN_NUMATUNE_MEM_STRICT occurs can be audited and +VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE case can be added. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2070380 +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +(cherry picked from commit 629282d8845407c1aff9a26f5dc026e15121f8cd) + +Conflicts: +- src/ch/ch_process.c: The CH driver diverged because it's + unsupported downstream. Just drop the conflicting hunk from + there. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2223464 +Signed-off-by: Michal Privoznik +--- + src/lxc/lxc_controller.c | 3 ++- + src/qemu/qemu_process.c | 6 ++++-- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c +index 3c930eaacd..6fd8373256 100644 +--- a/src/lxc/lxc_controller.c ++++ b/src/lxc/lxc_controller.c +@@ -812,7 +812,8 @@ static int virLXCControllerSetupResourceLimits(virLXCController *ctrl) + virDomainNumatuneMemMode mode; + + if (virDomainNumatuneGetMode(ctrl->def->numa, -1, &mode) == 0) { +- if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT && ++ if ((mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT || ++ mode == VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) && + virCgroupControllerAvailable(VIR_CGROUP_CONTROLLER_CPUSET)) { + /* Use virNuma* API iff necessary. Once set and child is exec()-ed, + * there's no way for us to change it. Rely on cgroups (if available +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 0fb665bc82..73d54f01cd 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2645,7 +2645,8 @@ qemuProcessSetupPid(virDomainObj *vm, + virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) { + + if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 && +- mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT && ++ (mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT || ++ mem_mode == VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) && + virDomainNumatuneMaybeFormatNodeset(vm->def->numa, + priv->autoNodeset, + &mem_mask, -1) < 0) +@@ -3162,7 +3163,8 @@ static int qemuProcessHook(void *data) + goto cleanup; + + if (virDomainNumatuneGetMode(h->vm->def->numa, -1, &mode) == 0) { +- if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT && ++ if ((mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT || ++ mode == VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) && + h->cfg->cgroupControllers & (1 << VIR_CGROUP_CONTROLLER_CPUSET) && + virCgroupControllerAvailable(VIR_CGROUP_CONTROLLER_CPUSET)) { + /* Use virNuma* API iff necessary. Once set and child is exec()-ed, +-- +2.41.0 diff --git a/node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch b/libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch similarity index 73% rename from node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch rename to libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch index 91aed8d..628809a 100644 --- a/node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch +++ b/libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch @@ -1,8 +1,12 @@ -From 64d32118540aca3d42bc5ee21c8b780cafe04bfa Mon Sep 17 00:00:00 2001 +From 989a569c9c9da0fbf89aab7f292669366b2503f1 Mon Sep 17 00:00:00 2001 +Message-Id: <989a569c9c9da0fbf89aab7f292669366b2503f1@dist-git> From: Michal Privoznik Date: Wed, 30 Nov 2022 14:53:21 +0100 Subject: [PATCH] node_device_conf: Avoid memleak in virNodeDeviceGetPCIVPDDynamicCap() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit The virNodeDeviceGetPCIVPDDynamicCap() function is called from virNodeDeviceGetPCIDynamicCaps() and therefore has to be a wee @@ -14,15 +18,18 @@ as well. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2143235 Signed-off-by: Michal Privoznik Reviewed-by: Peter Krempa +(cherry picked from commit 64d32118540aca3d42bc5ee21c8b780cafe04bfa) +https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2023-2700 +Signed-off-by: Ján Tomko --- src/conf/node_device_conf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c -index 83e66b85e3..af331baaf3 100644 +index 16b9497faf..eee94a3900 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c -@@ -3068,6 +3068,9 @@ virNodeDeviceGetPCIVPDDynamicCap(virNodeDevCapPCIDev *devCapPCIDev) +@@ -3100,6 +3100,9 @@ virNodeDeviceGetPCIVPDDynamicCap(virNodeDevCapPCIDev *devCapPCIDev) virPCIDeviceAddress devAddr; g_autoptr(virPCIVPDResource) res = NULL; @@ -32,7 +39,7 @@ index 83e66b85e3..af331baaf3 100644 devAddr.domain = devCapPCIDev->domain; devAddr.bus = devCapPCIDev->bus; devAddr.slot = devCapPCIDev->slot; -@@ -3081,8 +3084,6 @@ virNodeDeviceGetPCIVPDDynamicCap(virNodeDevCapPCIDev *devCapPCIDev) +@@ -3113,8 +3116,6 @@ virNodeDeviceGetPCIVPDDynamicCap(virNodeDevCapPCIDev *devCapPCIDev) if ((res = virPCIDeviceGetVPD(pciDev))) { devCapPCIDev->flags |= VIR_NODE_DEV_CAP_FLAG_PCI_VPD; devCapPCIDev->vpd = g_steal_pointer(&res); @@ -42,5 +49,4 @@ index 83e66b85e3..af331baaf3 100644 } return 0; -- -GitLab - +2.40.1 diff --git a/libvirt-nodedev-update-transient-mdevs.patch b/libvirt-nodedev-update-transient-mdevs.patch new file mode 100644 index 0000000..f32e5a5 --- /dev/null +++ b/libvirt-nodedev-update-transient-mdevs.patch @@ -0,0 +1,79 @@ +From aebcc09c7060f6eace93821c6a782031cf107d85 Mon Sep 17 00:00:00 2001 +Message-ID: +From: Boris Fiuczynski +Date: Mon, 8 May 2023 19:10:46 +0200 +Subject: [PATCH] nodedev: update transient mdevs + +Instead of updating defined mdevs only add another update for active +devices as well to cover transient mdev devices as well. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2143158 +Signed-off-by: Boris Fiuczynski +Reviewed-by: Jonathon Jongsma + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2143160 + +(cherry picked from commit 44a0f2f0c8ff5e78c238013ed297b8fce223ac5a) +Signed-off-by: Jonathon Jongsma +--- + src/node_device/node_device_driver.c | 31 ++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c +index e6ab4bb94c..943f6121a0 100644 +--- a/src/node_device/node_device_driver.c ++++ b/src/node_device/node_device_driver.c +@@ -1651,6 +1651,24 @@ virMdevctlListDefined(virNodeDeviceDef ***devs, char **errmsg) + } + + ++static int ++virMdevctlListActive(virNodeDeviceDef ***devs, char **errmsg) ++{ ++ int status; ++ g_autofree char *output = NULL; ++ g_autoptr(virCommand) cmd = nodeDeviceGetMdevctlListCommand(false, &output, errmsg); ++ ++ if (virCommandRun(cmd, &status) < 0 || status != 0) { ++ return -1; ++ } ++ ++ if (!output) ++ return -1; ++ ++ return nodeDeviceParseMdevctlJSON(output, devs); ++} ++ ++ + typedef struct _virMdevctlForEachData virMdevctlForEachData; + struct _virMdevctlForEachData { + int ndefs; +@@ -1712,6 +1730,8 @@ int + nodeDeviceUpdateMediatedDevices(void) + { + g_autofree virNodeDeviceDef **defs = NULL; ++ g_autofree virNodeDeviceDef **act_defs = NULL; ++ int act_ndefs = 0; + g_autofree char *errmsg = NULL; + g_autofree char *mdevctl = NULL; + virMdevctlForEachData data = { 0, }; +@@ -1738,6 +1758,17 @@ nodeDeviceUpdateMediatedDevices(void) + if (nodeDeviceUpdateMediatedDevice(defs[i]) < 0) + return -1; + ++ /* Update active/transient mdev devices */ ++ if ((act_ndefs = virMdevctlListActive(&act_defs, &errmsg)) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("failed to query mdevs from mdevctl: %1$s"), errmsg); ++ return -1; ++ } ++ ++ for (i = 0; i < act_ndefs; i++) ++ if (nodeDeviceUpdateMediatedDevice(act_defs[i]) < 0) ++ return -1; ++ + return 0; + } + +-- +2.41.0 diff --git a/libvirt-qemu-Make-struct-_qemuMonitorMessage-private.patch b/libvirt-qemu-Make-struct-_qemuMonitorMessage-private.patch new file mode 100644 index 0000000..ffd8ae6 --- /dev/null +++ b/libvirt-qemu-Make-struct-_qemuMonitorMessage-private.patch @@ -0,0 +1,105 @@ +From 85b7d8295d72214b08f0fff93c473baaa88a569b Mon Sep 17 00:00:00 2001 +Message-Id: <85b7d8295d72214b08f0fff93c473baaa88a569b@dist-git> +From: Peter Krempa +Date: Mon, 14 Feb 2022 15:57:21 +0100 +Subject: [PATCH] qemu: Make 'struct _qemuMonitorMessage' private +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Move the declaration of the struct into 'qemu_monitor_priv.h' as other +code has no business in peeking into the monitor messages. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit f9ae469a6ebb17e0990096e826f049c1c46cd760) +https://bugzilla.redhat.com/show_bug.cgi?id=2170472 +--- + src/qemu/qemu_monitor.h | 14 -------------- + src/qemu/qemu_monitor_json.c | 3 +++ + src/qemu/qemu_monitor_priv.h | 16 ++++++++++++++++ + tests/qemucapsprobemock.c | 3 +++ + 4 files changed, 22 insertions(+), 14 deletions(-) + +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index a4a4edf5a6..d00967d84f 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -34,21 +34,7 @@ + #include "virenum.h" + + typedef struct _qemuMonitor qemuMonitor; +- + typedef struct _qemuMonitorMessage qemuMonitorMessage; +-struct _qemuMonitorMessage { +- int txFD; +- +- const char *txBuffer; +- int txOffset; +- int txLength; +- +- /* Used by the JSON monitor to hold reply / error */ +- void *rxObject; +- +- /* True if rxObject is ready, or a fatal error occurred on the monitor channel */ +- bool finished; +-}; + + typedef enum { + QEMU_MONITOR_EVENT_PANIC_INFO_TYPE_NONE = 0, +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 34a46b9b41..7d8755246f 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -44,6 +44,9 @@ + # include "libvirt_qemu_probes.h" + #endif + ++#define LIBVIRT_QEMU_MONITOR_PRIV_H_ALLOW ++#include "qemu_monitor_priv.h" ++ + #define VIR_FROM_THIS VIR_FROM_QEMU + + VIR_LOG_INIT("qemu.qemu_monitor_json"); +diff --git a/src/qemu/qemu_monitor_priv.h b/src/qemu/qemu_monitor_priv.h +index 31bb3526b9..6115f830de 100644 +--- a/src/qemu/qemu_monitor_priv.h ++++ b/src/qemu/qemu_monitor_priv.h +@@ -24,5 +24,21 @@ + + #include "qemu_monitor.h" + ++ ++struct _qemuMonitorMessage { ++ int txFD; ++ ++ const char *txBuffer; ++ int txOffset; ++ int txLength; ++ ++ /* Used by the JSON monitor to hold reply / error */ ++ void *rxObject; ++ ++ /* True if rxObject is ready, or a fatal error occurred on the monitor channel */ ++ bool finished; ++}; ++ ++ + void + qemuMonitorResetCommandID(qemuMonitor *mon); +diff --git a/tests/qemucapsprobemock.c b/tests/qemucapsprobemock.c +index 915036d178..2717ed5d84 100644 +--- a/tests/qemucapsprobemock.c ++++ b/tests/qemucapsprobemock.c +@@ -25,6 +25,9 @@ + #include "qemu/qemu_monitor.h" + #include "qemu/qemu_monitor_json.h" + ++#define LIBVIRT_QEMU_MONITOR_PRIV_H_ALLOW ++#include "qemu/qemu_monitor_priv.h" ++ + #define REAL_SYM(realFunc) \ + do { \ + if (!realFunc && !(realFunc = dlsym(RTLD_NEXT, __FUNCTION__))) { \ +-- +2.40.1 diff --git a/libvirt-qemu-monitor-Drop-old-monitor-fields-from-struct-_qemuMonitorMessage.patch b/libvirt-qemu-monitor-Drop-old-monitor-fields-from-struct-_qemuMonitorMessage.patch new file mode 100644 index 0000000..f436915 --- /dev/null +++ b/libvirt-qemu-monitor-Drop-old-monitor-fields-from-struct-_qemuMonitorMessage.patch @@ -0,0 +1,44 @@ +From a4d8210ae9fd84740e01b96d28bfb6183f3f3270 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Peter Krempa +Date: Mon, 14 Feb 2022 16:02:29 +0100 +Subject: [PATCH] qemu: monitor: Drop old monitor fields from 'struct + _qemuMonitorMessage' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The fields are no longer used since we've deleted support for HMP-only +qemus. The HMP command pass-through works via a QMP command. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit c5eb99a9d9af8683789e99cc904671e343580058) +https://bugzilla.redhat.com/show_bug.cgi?id=2170472 +--- + src/qemu/qemu_monitor.h | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index d2037914be..a4a4edf5a6 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -43,15 +43,10 @@ struct _qemuMonitorMessage { + int txOffset; + int txLength; + +- /* Used by the text monitor reply / error */ +- char *rxBuffer; +- int rxLength; + /* Used by the JSON monitor to hold reply / error */ + void *rxObject; + +- /* True if rxBuffer / rxObject are ready, or a +- * fatal error occurred on the monitor channel +- */ ++ /* True if rxObject is ready, or a fatal error occurred on the monitor channel */ + bool finished; + }; + +-- +2.40.1 diff --git a/libvirt-qemu-monitor-Move-declaration-of-struct-_qemuMonitor-to-qemu_monitor_priv.h.patch b/libvirt-qemu-monitor-Move-declaration-of-struct-_qemuMonitor-to-qemu_monitor_priv.h.patch new file mode 100644 index 0000000..145de29 --- /dev/null +++ b/libvirt-qemu-monitor-Move-declaration-of-struct-_qemuMonitor-to-qemu_monitor_priv.h.patch @@ -0,0 +1,157 @@ +From c2ed5aeee7bf365877e0764699f032fb749630b0 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Peter Krempa +Date: Mon, 14 Feb 2022 16:07:41 +0100 +Subject: [PATCH] qemu: monitor: Move declaration of struct _qemuMonitor to + qemu_monitor_priv.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In order to mock the SCM_RIGHTS sendmsg to simulate sending +filedescriptors to fake qemu in tests we need access to some fields of +'struct _qemuMonitor'. Move its declaration to the private header file. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 7c35c483eaa78eb847e0865cbb210d5355f75d7a) +https://bugzilla.redhat.com/show_bug.cgi?id=2170472 +--- + src/qemu/qemu_monitor.c | 50 --------------------------------- + src/qemu/qemu_monitor_priv.h | 54 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+), 50 deletions(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 23638d3fe8..bba92592c5 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -65,56 +65,6 @@ VIR_LOG_INIT("qemu.qemu_monitor"); + */ + #define QEMU_MONITOR_MAX_RESPONSE (10 * 1024 * 1024) + +-struct _qemuMonitor { +- virObjectLockable parent; +- +- virCond notify; +- +- int fd; +- +- GMainContext *context; +- GSocket *socket; +- GSource *watch; +- +- virDomainObj *vm; +- char *domainName; +- +- qemuMonitorCallbacks *cb; +- void *callbackOpaque; +- +- /* If there's a command being processed this will be +- * non-NULL */ +- qemuMonitorMessage *msg; +- +- /* Buffer incoming data ready for Text/QMP monitor +- * code to process & find message boundaries */ +- size_t bufferOffset; +- size_t bufferLength; +- char *buffer; +- +- /* If anything went wrong, this will be fed back +- * the next monitor msg */ +- virError lastError; +- +- /* Set to true when EOF is detected on the monitor */ +- bool goteof; +- +- int nextSerial; +- +- bool waitGreeting; +- +- /* If found, path to the virtio memballoon driver */ +- char *balloonpath; +- bool ballooninit; +- +- /* Log file context of the qemu process to dig for usable info */ +- qemuMonitorReportDomainLogError logFunc; +- void *logOpaque; +- virFreeCallback logDestroy; +- +- /* true if qemu no longer wants 'props' sub-object of object-add */ +- bool objectAddNoWrap; +-}; + + /** + * QEMU_CHECK_MONITOR_FULL: +diff --git a/src/qemu/qemu_monitor_priv.h b/src/qemu/qemu_monitor_priv.h +index 6115f830de..606aa79fbd 100644 +--- a/src/qemu/qemu_monitor_priv.h ++++ b/src/qemu/qemu_monitor_priv.h +@@ -24,6 +24,8 @@ + + #include "qemu_monitor.h" + ++#include ++ + + struct _qemuMonitorMessage { + int txFD; +@@ -40,5 +42,57 @@ struct _qemuMonitorMessage { + }; + + ++struct _qemuMonitor { ++ virObjectLockable parent; ++ ++ virCond notify; ++ ++ int fd; ++ ++ GMainContext *context; ++ GSocket *socket; ++ GSource *watch; ++ ++ virDomainObj *vm; ++ char *domainName; ++ ++ qemuMonitorCallbacks *cb; ++ void *callbackOpaque; ++ ++ /* If there's a command being processed this will be ++ * non-NULL */ ++ qemuMonitorMessage *msg; ++ ++ /* Buffer incoming data ready for Text/QMP monitor ++ * code to process & find message boundaries */ ++ size_t bufferOffset; ++ size_t bufferLength; ++ char *buffer; ++ ++ /* If anything went wrong, this will be fed back ++ * the next monitor msg */ ++ virError lastError; ++ ++ /* Set to true when EOF is detected on the monitor */ ++ bool goteof; ++ ++ int nextSerial; ++ ++ bool waitGreeting; ++ ++ /* If found, path to the virtio memballoon driver */ ++ char *balloonpath; ++ bool ballooninit; ++ ++ /* Log file context of the qemu process to dig for usable info */ ++ qemuMonitorReportDomainLogError logFunc; ++ void *logOpaque; ++ virFreeCallback logDestroy; ++ ++ /* true if qemu no longer wants 'props' sub-object of object-add */ ++ bool objectAddNoWrap; ++}; ++ ++ + void + qemuMonitorResetCommandID(qemuMonitor *mon); +-- +2.40.1 diff --git a/libvirt-qemu-monitor-Store-whether-query-named-block-nodes-supports-flat-parameter.patch b/libvirt-qemu-monitor-Store-whether-query-named-block-nodes-supports-flat-parameter.patch new file mode 100644 index 0000000..23ee422 --- /dev/null +++ b/libvirt-qemu-monitor-Store-whether-query-named-block-nodes-supports-flat-parameter.patch @@ -0,0 +1,57 @@ +From b3ffc8876adf777c7baefb6e467d7552c0a03251 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Peter Krempa +Date: Wed, 9 Nov 2022 10:53:49 +0100 +Subject: [PATCH] qemu: monitor: Store whether 'query-named-block-nodes' + supports 'flat' parameter +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Rather than having callers always pass this flag store it in the +qemuMonitor object. Following patches will convert the code to use this +internal flag. + +In the future this will also simplify removal when all supported qemu +versions will support the new mode. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit b0e4ad5263c73a926b8246028c76c552b07fca74) +https://bugzilla.redhat.com/show_bug.cgi?id=2170472 +--- + src/qemu/qemu_monitor.c | 4 +++- + src/qemu/qemu_monitor_priv.h | 2 ++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index bba92592c5..99667fdf2f 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -610,8 +610,10 @@ qemuMonitorOpenInternal(virDomainObj *vm, + mon->cb = cb; + mon->callbackOpaque = opaque; + +- if (priv) ++ if (priv) { + mon->objectAddNoWrap = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_JSON); ++ mon->queryNamedBlockNodesFlat = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QMP_QUERY_NAMED_BLOCK_NODES_FLAT); ++ } + + if (virSetCloseExec(mon->fd) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, +diff --git a/src/qemu/qemu_monitor_priv.h b/src/qemu/qemu_monitor_priv.h +index 606aa79fbd..e32928805f 100644 +--- a/src/qemu/qemu_monitor_priv.h ++++ b/src/qemu/qemu_monitor_priv.h +@@ -91,6 +91,8 @@ struct _qemuMonitor { + + /* true if qemu no longer wants 'props' sub-object of object-add */ + bool objectAddNoWrap; ++ /* query-named-block-nodes supports the 'flat' option */ ++ bool queryNamedBlockNodesFlat; + }; + + +-- +2.40.1 diff --git a/libvirt-qemu-qemuBlockGetNamedNodeData-Remove-pointless-error-path.patch b/libvirt-qemu-qemuBlockGetNamedNodeData-Remove-pointless-error-path.patch new file mode 100644 index 0000000..ac8b3e2 --- /dev/null +++ b/libvirt-qemu-qemuBlockGetNamedNodeData-Remove-pointless-error-path.patch @@ -0,0 +1,53 @@ +From 31986239312c0e460800f5b9921f6593f1556015 Mon Sep 17 00:00:00 2001 +Message-Id: <31986239312c0e460800f5b9921f6593f1556015@dist-git> +From: Peter Krempa +Date: Wed, 9 Nov 2022 10:45:27 +0100 +Subject: [PATCH] qemu: qemuBlockGetNamedNodeData: Remove pointless error path +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We don't need automatic freeing for 'blockNamedNodeData' and we can +directly return it rather than checking it for NULL-ness first. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit 3fe74ebd9037d695df906ed137d22a8d8d77e169) + + Conflicts: + src/qemu/qemu_block.c + + - qemuDomainObjEnter/ExitMonitor still needs 'driver' + +https://bugzilla.redhat.com/show_bug.cgi?id=2170472 +--- + src/qemu/qemu_block.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c +index aa566d0097..c9229d1918 100644 +--- a/src/qemu/qemu_block.c ++++ b/src/qemu/qemu_block.c +@@ -3020,7 +3020,7 @@ qemuBlockGetNamedNodeData(virDomainObj *vm, + { + qemuDomainObjPrivate *priv = vm->privateData; + virQEMUDriver *driver = priv->driver; +- g_autoptr(GHashTable) blockNamedNodeData = NULL; ++ GHashTable *blockNamedNodeData = NULL; + bool supports_flat = virQEMUCapsGet(priv->qemuCaps, + QEMU_CAPS_QMP_QUERY_NAMED_BLOCK_NODES_FLAT); + +@@ -3031,10 +3031,7 @@ qemuBlockGetNamedNodeData(virDomainObj *vm, + + qemuDomainObjExitMonitor(driver, vm); + +- if (!blockNamedNodeData) +- return NULL; +- +- return g_steal_pointer(&blockNamedNodeData); ++ return blockNamedNodeData; + } + + +-- +2.40.1 diff --git a/libvirt-qemu-relax-shared-memory-check-for-vhostuser-daemons.patch b/libvirt-qemu-relax-shared-memory-check-for-vhostuser-daemons.patch new file mode 100644 index 0000000..ae3ebae --- /dev/null +++ b/libvirt-qemu-relax-shared-memory-check-for-vhostuser-daemons.patch @@ -0,0 +1,65 @@ +From e9418cec1ba24b6cf78f85bbbef8586ed612692a Mon Sep 17 00:00:00 2001 +Message-Id: +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Mon, 13 Mar 2023 13:56:47 +0100 +Subject: [PATCH] qemu: relax shared memory check for vhostuser daemons +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +For some vhostuser daemons, we validate that the guest memory is shared +with the host. + +With earlier versions of QEMU, it was only possible to mark memory +as shared by defining an explicit NUMA topology. Later, QEMU exposed +the name of the default memory backend (defaultRAMid) so we can mark +that memory as shared. + +Since libvirt commit: + commit bff2ad5d6b1f25da02802273934d2a519159fec7 + qemu: Relax validation for mem->access if guest has no NUMA +we already check for the case when user requests shared memory, +but QEMU did not expose defaultRAMid. + +Drop the duplicit check from vhostuser device validation, to make +it pass on hotplug even after libvirtd restart. + +This avoids the need to store the defaultRAMid, since we don't really +need it for anything after the VM has been already started. + +https://bugzilla.redhat.com/show_bug.cgi?id=2078693 +https://bugzilla.redhat.com/show_bug.cgi?id=2177701 + +Signed-off-by: Ján Tomko +Reviewed-by: Michal Privoznik +(cherry picked from commit d5c7b7870e45575f81fffcb611c2546d0e02e778) +Signed-off-by: Ján Tomko +--- + src/qemu/qemu_validate.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index 7bc14293d6..4069f47c12 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -1588,16 +1588,12 @@ qemuValidateDomainVirtioOptions(const virDomainVirtioOptions *virtio, + static int + qemuValidateDomainDefVhostUserRequireSharedMemory(const virDomainDef *def, + const char *name, +- virQEMUCaps *qemuCaps) ++ virQEMUCaps *qemuCaps G_GNUC_UNUSED) + { +- const char *defaultRAMId = virQEMUCapsGetMachineDefaultRAMid(qemuCaps, +- def->virtType, +- def->os.machine); + size_t numa_nodes = virDomainNumaGetNodeCount(def->numa); + size_t i; + +- if (numa_nodes == 0 && +- !(defaultRAMId && def->mem.access == VIR_DOMAIN_MEMORY_ACCESS_SHARED)) { ++ if (numa_nodes == 0 && def->mem.access != VIR_DOMAIN_MEMORY_ACCESS_SHARED) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("'%s' requires shared memory"), name); + return -1; +-- +2.40.1 diff --git a/libvirt-qemuMonitorJSONBlockStatsUpdateCapacityBlockdev-Use-flat-mode-of-query-named-block-nodes.patch b/libvirt-qemuMonitorJSONBlockStatsUpdateCapacityBlockdev-Use-flat-mode-of-query-named-block-nodes.patch new file mode 100644 index 0000000..a143d04 --- /dev/null +++ b/libvirt-qemuMonitorJSONBlockStatsUpdateCapacityBlockdev-Use-flat-mode-of-query-named-block-nodes.patch @@ -0,0 +1,41 @@ +From f20062e1fe1e7bca8b97d2383f9e8a06f0f4111a Mon Sep 17 00:00:00 2001 +Message-Id: +From: Peter Krempa +Date: Wed, 9 Nov 2022 11:06:25 +0100 +Subject: [PATCH] qemuMonitorJSONBlockStatsUpdateCapacityBlockdev: Use 'flat' + mode of query-named-block-nodes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +'query-named-block-nodes' in non-flat mode returns redundantly nested +data under the 'backing-image' field. Fortunately we don't need it when +updating the capacity stats. + +This function was unfortunately not fixed originally when the support +for flat mode was added. Use the flat cached in the monitor object to +force flat mode if available. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +(cherry picked from commit bbd4d4899391b3bd1906cce61a3634f42f4b1bdf) +https://bugzilla.redhat.com/show_bug.cgi?id=2170472 +--- + src/qemu/qemu_monitor_json.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 7d8755246f..789554e225 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -2679,7 +2679,7 @@ qemuMonitorJSONBlockStatsUpdateCapacityBlockdev(qemuMonitor *mon, + { + g_autoptr(virJSONValue) nodes = NULL; + +- if (!(nodes = qemuMonitorJSONQueryNamedBlockNodes(mon, false))) ++ if (!(nodes = qemuMonitorJSONQueryNamedBlockNodes(mon, mon->queryNamedBlockNodesFlat))) + return -1; + + if (virJSONValueArrayForeachSteal(nodes, +-- +2.40.1 diff --git a/virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch b/libvirt-virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch similarity index 79% rename from virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch rename to libvirt-virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch index 0004fff..ffc4a36 100644 --- a/virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch +++ b/libvirt-virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch @@ -1,4 +1,5 @@ -From 6425a311b8ad19d6f9c0b315bf1d722551ea3585 Mon Sep 17 00:00:00 2001 +From 0e91f4dc214d01e9d9537b1111ce67010530fd20 Mon Sep 17 00:00:00 2001 +Message-Id: <0e91f4dc214d01e9d9537b1111ce67010530fd20@dist-git> From: Tim Shearer Date: Mon, 1 May 2023 13:15:48 +0000 Subject: [PATCH] virpci: Resolve leak in virPCIVirtualFunctionList cleanup @@ -29,15 +30,21 @@ Valgrind output after getting a single interface's XML description Signed-off-by: Tim Shearer Reviewed-by: Ján Tomko +(cherry picked from commit 6425a311b8ad19d6f9c0b315bf1d722551ea3585) + +https://bugzilla.redhat.com/show_bug.cgi?id=2196351 +https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2023-2700 + +Signed-off-by: Ján Tomko --- src/util/virpci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/virpci.c b/src/util/virpci.c -index 9e564e4a4f..cc2b07bbba 100644 +index 4949d1a3d4..2714d11a7d 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c -@@ -2245,6 +2245,7 @@ virPCIVirtualFunctionListFree(virPCIVirtualFunctionList *list) +@@ -2255,6 +2255,7 @@ virPCIVirtualFunctionListFree(virPCIVirtualFunctionList *list) g_free(list->functions[i].ifname); } @@ -46,5 +53,4 @@ index 9e564e4a4f..cc2b07bbba 100644 } -- -GitLab - +2.40.1 diff --git a/libvirt.spec b/libvirt.spec index ddf51d1..e2d6779 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 21 %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 %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 +%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 -%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: %{anolis_release}%{?dist}%{?extra_release} +Release: 22%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -307,12 +306,17 @@ Patch83: libvirt-vircpi-Add-PCIe-5.0-and-6.0-link-speeds.patch Patch84: libvirt-conf-Make-VIR_DOMAIN_NET_TYPE_ETHERNET-not-share-host-view.patch Patch85: libvirt-qemu-domain-Fix-logic-when-tainting-domain.patch Patch86: libvirt-qemu-agent-Make-fetching-of-can-offline-member-from-guest-query-vcpus-optional.patch -Patch1000: libvirt-Add-loongarch-support.patch -Patch1001: libvirt-add-loongarch-edit-xml-validate.patch -Patch1002: node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch -Patch1003: virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch -Patch1004: qemu-validate-Drop-tpm-tis-arch-validation.patch -Patch1005: qemu-command-Use-correct-tpm-device-for-all-non-x86.patch +Patch87: libvirt-qemu-monitor-Drop-old-monitor-fields-from-struct-_qemuMonitorMessage.patch +Patch88: libvirt-qemu-Make-struct-_qemuMonitorMessage-private.patch +Patch89: libvirt-qemu-monitor-Move-declaration-of-struct-_qemuMonitor-to-qemu_monitor_priv.h.patch +Patch90: libvirt-qemu-qemuBlockGetNamedNodeData-Remove-pointless-error-path.patch +Patch91: libvirt-qemu-monitor-Store-whether-query-named-block-nodes-supports-flat-parameter.patch +Patch92: libvirt-qemuMonitorJSONBlockStatsUpdateCapacityBlockdev-Use-flat-mode-of-query-named-block-nodes.patch +Patch93: libvirt-qemu-relax-shared-memory-check-for-vhostuser-daemons.patch +Patch94: libvirt-virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch +Patch95: libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch +Patch96: libvirt-nodedev-update-transient-mdevs.patch +Patch97: libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2192,17 +2196,22 @@ exit 0 %changelog -* Fri Aug 4 2023 xianglai li - 8.0.0-21 -- Synchronize upstream patches "Use correct tpm device for all non-x86" -- Synchronize upstream patches "validate: Drop tpm-tis arch validation" - -* Thu Jun 29 2023 Liwei Ge - 8.0.0-20 -- Avoid memleak in virNodeDeviceGetPCIVPDDynamicCap (CVE-2023-2700) -- Resolve leak in virPCIVirtualFunctionList cleanup (CVE-2023-2700) - -* Mon Jun 19 2023 zhaotianrui - 8.0.0-19.0.1 -- Add loongarch support -- Fix loongarch xml validate +* Mon Jul 31 2023 Jiri Denemark - 8.0.0-22 +- lib: Set up cpuset controller for restrictive numatune (rhbz#2223464) + +* Thu Jun 22 2023 Jiri Denemark - 8.0.0-21 +- nodedev: update transient mdevs (rhbz#2143160) + +* Fri May 19 2023 Jiri Denemark - 8.0.0-20 +- qemu: monitor: Drop old monitor fields from 'struct _qemuMonitorMessage' (rhbz#2170472) +- qemu: Make 'struct _qemuMonitorMessage' private (rhbz#2170472) +- qemu: monitor: Move declaration of struct _qemuMonitor to qemu_monitor_priv.h (rhbz#2170472) +- qemu: qemuBlockGetNamedNodeData: Remove pointless error path (rhbz#2170472) +- qemu: monitor: Store whether 'query-named-block-nodes' supports 'flat' parameter (rhbz#2170472) +- qemuMonitorJSONBlockStatsUpdateCapacityBlockdev: Use 'flat' mode of query-named-block-nodes (rhbz#2170472) +- qemu: relax shared memory check for vhostuser daemons (rhbz#2177701) +- virpci: Resolve leak in virPCIVirtualFunctionList cleanup (CVE-2023-2700) +- node_device_conf: Avoid memleak in virNodeDeviceGetPCIVPDDynamicCap() (CVE-2023-2700) * Tue Mar 14 2023 Jiri Denemark - 8.0.0-19 - qemu: domain: Fix logic when tainting domain (rhbz#2174447) 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 62207a0c8e88754c8552930b0fac89db3998fcfb Mon Sep 17 00:00:00 2001 From: zhaotianrui Date: Thu, 8 Sep 2022 09:28:25 -0400 Subject: [PATCH 2/5] 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..94fd22a --- /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 e2d6779..61bac5e 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: 22%{?dist}%{?extra_release} +Release: 22%{anolis_release}%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -317,6 +318,7 @@ Patch94: libvirt-virpci-Resolve-leak-in-virPCIVirtualFunctionList-cleanup.patch Patch95: libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamicCap.patch Patch96: libvirt-nodedev-update-transient-mdevs.patch Patch97: libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.patch +Patch1000: libvirt-Add-loongarch-support.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2196,6 +2198,9 @@ exit 0 %changelog +* Thu Dec 14 2023 zhaotianrui - 8.0.0-22.0.1 +- Add loongarch support + * Mon Jul 31 2023 Jiri Denemark - 8.0.0-22 - lib: Set up cpuset controller for restrictive numatune (rhbz#2223464) -- Gitee From 3fd41f1d92a238f22348d83e3052395310334f5b Mon Sep 17 00:00:00 2001 From: lixianglai Date: Wed, 31 May 2023 02:27:43 -0400 Subject: [PATCH 3/5] 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 61bac5e..e591b5a 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -319,6 +319,7 @@ Patch95: libvirt-node_device_conf-Avoid-memleak-in-virNodeDeviceGetPCIVPDDynamic Patch96: libvirt-nodedev-update-transient-mdevs.patch Patch97: libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.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} @@ -2200,6 +2201,7 @@ exit 0 %changelog * Thu Dec 14 2023 zhaotianrui - 8.0.0-22.0.1 - Add loongarch support +- Fix loongarch xml validate * Mon Jul 31 2023 Jiri Denemark - 8.0.0-22 - lib: Set up cpuset controller for restrictive numatune (rhbz#2223464) -- Gitee From 82beb54c4dc12522555c47c05e776eb30cb6c46f Mon Sep 17 00:00:00 2001 From: Liwei Ge Date: Thu, 29 Jun 2023 10:03:16 +0800 Subject: [PATCH 4/5] fix CVE-2023-2700 Signed-off-by: Liwei Ge --- libvirt.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libvirt.spec b/libvirt.spec index e591b5a..dee5106 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -2202,6 +2202,8 @@ exit 0 * Thu Dec 14 2023 zhaotianrui - 8.0.0-22.0.1 - Add loongarch support - Fix loongarch xml validate +- Avoid memleak in virNodeDeviceGetPCIVPDDynamicCap (CVE-2023-2700)(liwei.glw@alibaba-inc.com) +- Resolve leak in virPCIVirtualFunctionList cleanup (CVE-2023-2700)(liwei.glw@alibaba-inc.com) * Mon Jul 31 2023 Jiri Denemark - 8.0.0-22 - lib: Set up cpuset controller for restrictive numatune (rhbz#2223464) -- Gitee From 9ad6d45b8813a09075d8b7abc8ddcab02e7d8535 Mon Sep 17 00:00:00 2001 From: xianglai li Date: Fri, 4 Aug 2023 11:18:20 +0800 Subject: [PATCH 5/5] 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 dee5106..1dda526 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -320,6 +320,8 @@ Patch96: libvirt-nodedev-update-transient-mdevs.patch Patch97: libvirt-lib-Set-up-cpuset-controller-for-restrictive-numatune.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} @@ -2204,6 +2206,8 @@ exit 0 - Fix loongarch xml validate - Avoid memleak in virNodeDeviceGetPCIVPDDynamicCap (CVE-2023-2700)(liwei.glw@alibaba-inc.com) - Resolve leak in virPCIVirtualFunctionList cleanup (CVE-2023-2700)(liwei.glw@alibaba-inc.com) +- 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) * Mon Jul 31 2023 Jiri Denemark - 8.0.0-22 - lib: Set up cpuset controller for restrictive numatune (rhbz#2223464) 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