diff --git a/generic_vdpa/libvirt/Add-loongarch-cpu-model-and-vendor-info.patch b/generic_vdpa/libvirt/Add-loongarch-cpu-model-and-vendor-info.patch new file mode 100644 index 0000000..e4e6651 --- /dev/null +++ b/generic_vdpa/libvirt/Add-loongarch-cpu-model-and-vendor-info.patch @@ -0,0 +1,69 @@ +From 55c7dc34b8ff1a75bb011ca783b6cd3c7f1a5643 Mon Sep 17 00:00:00 2001 +From: zhaotianrui +Date: Wed, 11 Jan 2023 11:41:55 -0500 +Subject: [PATCH 2/4] Add loongarch cpu model and vendor info + +Define loongarch cpu model type and vendor id in +cpu_map/loongarch.xml + +Signed-off-by: zhaotianrui +--- + src/cpu_map/Makefile.inc.am | 2 ++ + src/cpu_map/index.xml | 5 +++++ + src/cpu_map/loongarch_3a5000.xml | 6 ++++++ + src/cpu_map/loongarch_vendors.xml | 3 +++ + 4 files changed, 16 insertions(+) + create mode 100644 src/cpu_map/loongarch_3a5000.xml + create mode 100644 src/cpu_map/loongarch_vendors.xml + +diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am +index 8eb818706a..3c674dea40 100644 +--- a/src/cpu_map/Makefile.inc.am ++++ b/src/cpu_map/Makefile.inc.am +@@ -68,6 +68,8 @@ cpumap_DATA = \ + cpu_map/x86_Skylake-Server-noTSX-IBRS.xml \ + cpu_map/x86_Westmere.xml \ + cpu_map/x86_Westmere-IBRS.xml \ ++ cpu_map/loongarch_vendors.xml \ ++ cpu_map/loongarch_3a5000.xml \ + cpu_map/arm_vendors.xml \ + cpu_map/arm_cortex-a53.xml \ + cpu_map/arm_cortex-a57.xml \ +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 3ccc76b9ed..1c05dd814d 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -101,4 +101,9 @@ + + + ++ ++ ++ ++ ++ + +diff --git a/src/cpu_map/loongarch_3a5000.xml b/src/cpu_map/loongarch_3a5000.xml +new file mode 100644 +index 0000000000..f6fe3386f7 +--- /dev/null ++++ b/src/cpu_map/loongarch_3a5000.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/Add-loongarch-cpu-support.patch b/generic_vdpa/libvirt/Add-loongarch-cpu-support.patch new file mode 100644 index 0000000..7d05755 --- /dev/null +++ b/generic_vdpa/libvirt/Add-loongarch-cpu-support.patch @@ -0,0 +1,994 @@ +From c0b26612cf12d5f0594a9dfa5bd97fcf7acfe9da Mon Sep 17 00:00:00 2001 +From: zhaotianrui +Date: Wed, 11 Jan 2023 10:53:08 -0500 +Subject: [PATCH 1/4] Add loongarch cpu support + +Add loongarch cpu support: Define new cpu type 'loongarch64' +and implement it's driver functions. + +Signed-off-by: zhaotianrui +--- + docs/schemas/basictypes.rng | 1 + + po/POTFILES.in | 1 + + src/cpu/Makefile.inc.am | 3 + + src/cpu/cpu.c | 2 + + src/cpu/cpu.h | 3 +- + src/cpu/cpu_loongarch.c | 739 +++++++++++++++++++++++++++++++++++ + src/cpu/cpu_loongarch.h | 28 ++ + src/cpu/cpu_loongarch_data.h | 40 ++ + src/qemu/qemu_capabilities.c | 1 + + src/qemu/qemu_domain.c | 4 + + src/util/virarch.c | 1 + + src/util/virarch.h | 3 + + 12 files changed, 825 insertions(+), 1 deletion(-) + 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 + +diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng +index 81465273c8..34d285db48 100644 +--- a/docs/schemas/basictypes.rng ++++ b/docs/schemas/basictypes.rng +@@ -444,6 +444,7 @@ + x86_64 + xtensa + xtensaeb ++ loongarch64 + + + +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 197ff2f3d3..24dc8087d6 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -60,6 +60,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/Makefile.inc.am b/src/cpu/Makefile.inc.am +index 1ee1290c2d..e2219bbc1c 100644 +--- a/src/cpu/Makefile.inc.am ++++ b/src/cpu/Makefile.inc.am +@@ -15,6 +15,9 @@ CPU_SOURCES = \ + cpu/cpu_ppc64.h \ + cpu/cpu_ppc64.c \ + cpu/cpu_ppc64_data.h \ ++ cpu/cpu_loongarch.h \ ++ cpu/cpu_loongarch.c \ ++ cpu/cpu_loongarch_data.h \ + cpu/cpu_map.h \ + cpu/cpu_map.c \ + $(NULL) +diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c +index 89c06aceeb..df78a0d33f 100644 +--- a/src/cpu/cpu.c ++++ b/src/cpu/cpu.c +@@ -30,6 +30,7 @@ + #include "cpu_s390.h" + #include "cpu_arm.h" + #include "cpu_sw64.h" ++#include "cpu_loongarch.h" + #include "capabilities.h" + #include "virstring.h" + +@@ -44,6 +45,7 @@ static struct cpuArchDriver *drivers[] = { + &cpuDriverS390, + &cpuDriverArm, + &cpuDriverSW64, ++ &cpuDriverLoongArch, + }; + + +diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h +index ec22a183a1..307c85fb61 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; + typedef virCPUData *virCPUDataPtr; +@@ -38,6 +38,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..953316bf78 +--- /dev/null ++++ b/src/cpu/cpu_loongarch.c +@@ -0,0 +1,739 @@ ++/* ++ * cpu_loongarch.c: CPU driver for 64-bit LOONGARCH CPUs ++ * ++ * Copyright (C) 2023 Loongson Technology. ++ * ++ * 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" ++ ++#define VIR_FROM_THIS VIR_FROM_CPU ++ ++VIR_LOG_INIT("cpu.cpu_loongarch"); ++ ++static const virArch archs[] = { VIR_ARCH_LOONGARCH64 }; ++ ++typedef struct { ++ char *name; ++} LoongArch_vendor; ++ ++typedef struct { ++ char *name; ++ const LoongArch_vendor *vendor; ++ virCPULoongArchData data; ++} LoongArch_model; ++ ++typedef struct { ++ size_t nvendors; ++ LoongArch_vendor **vendors; ++ size_t nmodels; ++ LoongArch_model **models; ++} LoongArch_map; ++ ++static void ++LoongArchDataClear(virCPULoongArchData *data) ++{ ++ if (!data) ++ return; ++ ++ VIR_FREE(data->prid); ++} ++ ++static int ++LoongArchDataCopy(virCPULoongArchData *dst, const virCPULoongArchData *src) ++{ ++ size_t i; ++ ++ if (VIR_ALLOC_N(dst->prid, src->len) < 0) ++ return -1; ++ ++ 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; ++ ++ VIR_FREE(vendor->name); ++ VIR_FREE(vendor); ++} ++ ++static LoongArch_vendor * ++LoongArchVendorFind(const 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); ++ VIR_FREE(model->name); ++ VIR_FREE(model); ++} ++ ++static LoongArch_model * ++LoongArchModelCopy(const LoongArch_model *model) ++{ ++ LoongArch_model *copy; ++ ++ if (VIR_ALLOC(copy) < 0) ++ goto cleanup; ++ ++ copy->name = g_strdup(model->name); ++ ++ if (LoongArchDataCopy(©->data, &model->data) < 0) ++ goto cleanup; ++ ++ copy->vendor = model->vendor; ++ ++ return copy; ++ ++ cleanup: ++ LoongArchModelFree(copy); ++ return NULL; ++} ++ ++static LoongArch_model * ++LoongArchModelFind(const 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(const 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, ++ const 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]); ++ VIR_FREE(map->models); ++ ++ for (i = 0; i < map->nvendors; i++) ++ LoongArchVendorFree(map->vendors[i]); ++ VIR_FREE(map->vendors); ++ ++ VIR_FREE(map); ++} ++ ++static int ++LoongArchVendorParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, ++ const char *name, ++ void *data) ++{ ++ LoongArch_map *map = data; ++ LoongArch_vendor *vendor; ++ int ret = -1; ++ ++ if (VIR_ALLOC(vendor) < 0) ++ return ret; ++ vendor->name = g_strdup(name); ++ ++ if (LoongArchVendorFind(map, vendor->name)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("CPU vendor %s already defined"), vendor->name); ++ goto cleanup; ++ } ++ ++ if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) ++ goto cleanup; ++ ++ 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; ++ ++ if (VIR_ALLOC(model) < 0) ++ goto cleanup; ++ ++ 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; ++ } ++ ++ if (VIR_ALLOC_N(model->data.prid, n) < 0) ++ goto cleanup; ++ ++ 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; ++ } ++ ++ if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0) ++ goto cleanup; ++ ++ ret = 0; ++ ++ cleanup: ++ LoongArchModelFree(model); ++ VIR_FREE(vendor); ++ VIR_FREE(nodes); ++ return ret; ++} ++ ++static LoongArch_map * ++LoongArchLoadMap(void) ++{ ++ LoongArch_map *map; ++ ++ if (VIR_ALLOC(map) < 0) ++ goto cleanup; ++ ++ if (cpuMapLoad("loongarch64", LoongArchVendorParse, NULL, LoongArchModelParse, map) < 0) ++ goto cleanup; ++ ++ return map; ++ ++ cleanup: ++ LoongArchMapFree(map); ++ return NULL; ++} ++ ++static virCPUDataPtr ++LoongArchMakeCPUData(virArch arch, ++ virCPULoongArchData *data) ++{ ++ virCPUDataPtr cpuData; ++ ++ if (VIR_ALLOC(cpuData) < 0) ++ return NULL; ++ ++ cpuData->arch = arch; ++ ++ if (LoongArchDataCopy(&cpuData->data.loongarch, data) < 0) ++ VIR_FREE(cpuData); ++ ++ return cpuData; ++} ++ ++static virCPUCompareResult ++LoongArchCompute(virCPUDefPtr host, ++ const virCPUDef *other, ++ virCPUDataPtr *guestData, ++ char **message) ++{ ++ LoongArch_map *map = NULL; ++ LoongArch_model *host_model = NULL; ++ LoongArch_model *guest_model = NULL; ++ virCPUDefPtr 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(virCPUDefPtr host, ++ virCPUDefPtr 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); ++ } ++ } ++ VIR_FREE(message); ++ ++ return ret; ++} ++ ++static int ++LoongArchDriverDecode(virCPUDefPtr cpu, ++ const virCPUData *data, ++ virDomainCapsCPUModelsPtr models) ++{ ++ int ret = -1; ++ LoongArch_map *map; ++ const 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(virCPUDataPtr data) ++{ ++ if (!data) ++ return; ++ ++ LoongArchDataClear(&data->data.loongarch); ++ VIR_FREE(data); ++} ++ ++static int ++virCPULoongArchGetHostPRID(void) ++{ ++ return 0x14c010; ++} ++ ++static int ++virCPULoongArchGetHost(virCPUDefPtr cpu, ++ virDomainCapsCPUModelsPtr models) ++{ ++ virCPUDataPtr cpuData = NULL; ++ virCPULoongArchData *data; ++ int ret = -1; ++ ++ if (!(cpuData = virCPUDataNew(archs[0]))) ++ goto cleanup; ++ ++ data = &cpuData->data.loongarch; ++ if (VIR_ALLOC(data->prid) < 0) ++ goto cleanup; ++ ++ ++ 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(virCPUDefPtr guest, ++ const virCPUDef *host ATTRIBUTE_UNUSED) ++{ ++ /* ++ * - 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 ++ */ ++ ++ if (guest->mode == VIR_CPU_MODE_CUSTOM) ++ guest->match = VIR_CPU_MATCH_EXACT; ++ ++ return 0; ++} ++ ++static virCPUDefPtr ++LoongArchDriverBaseline(virCPUDefPtr *cpus, ++ unsigned int ncpus, ++ virDomainCapsCPUModelsPtr models ATTRIBUTE_UNUSED, ++ const char **features ATTRIBUTE_UNUSED, ++ bool migratable ATTRIBUTE_UNUSED) ++{ ++ LoongArch_map *map; ++ const LoongArch_model *model; ++ const LoongArch_vendor *vendor = NULL; ++ virCPUDefPtr cpu = NULL; ++ size_t i; ++ ++ 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++) { ++ const 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 = virCPUDefNew(); ++ 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) { ++ if (VIR_ALLOC_N(*models, map->nmodels + 1) < 0) ++ goto error; ++ ++ 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) { ++ virStringListFree(*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..304af628d4 +--- /dev/null ++++ b/src/cpu/cpu_loongarch.h +@@ -0,0 +1,28 @@ ++/* ++ * cpu_loongarch.h: CPU driver for 64-bit LOONGARCH CPUs ++ * ++ * Copyright (C) 2023 Loongson Technology. ++ * ++ * 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..c640a0c6b4 +--- /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) 2023 Loongson Technology. ++ * ++ * 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/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 2e9f2025ba..0c3eb148b2 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2692,6 +2692,7 @@ static const char *preferredMachines[] = + "sim", /* VIR_ARCH_XTENSAEB */ + + "core3", /* VIR_ARCH_SW_64 */ ++ "loongson7a", /* VIR_ARCH_LOONGARCH64 */ + }; + G_STATIC_ASSERT(G_N_ELEMENTS(preferredMachines) == VIR_ARCH_LAST); + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 70835e4efd..37dac3694b 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -4361,6 +4361,10 @@ qemuDomainDefAddDefaultDevices(virDomainDefPtr def, + addPCIeRoot = true; + break; + ++ case VIR_ARCH_LOONGARCH64: ++ addPCIeRoot = true; ++ break; ++ + case VIR_ARCH_ARMV7B: + case VIR_ARCH_CRIS: + case VIR_ARCH_ITANIUM: +diff --git a/src/util/virarch.c b/src/util/virarch.c +index 653136cc73..decdbdd7ac 100644 +--- a/src/util/virarch.c ++++ b/src/util/virarch.c +@@ -85,6 +85,7 @@ static const struct virArchData { + { "xtensaeb", 32, VIR_ARCH_BIG_ENDIAN }, + + { "sw_64", 64, VIR_ARCH_LITTLE_ENDIAN}, ++ { "loongarch64", 64, VIR_ARCH_LITTLE_ENDIAN }, + }; + + G_STATIC_ASSERT(G_N_ELEMENTS(virArchData) == VIR_ARCH_LAST); +diff --git a/src/util/virarch.h b/src/util/virarch.h +index 5eb146eb1b..a7834ae799 100644 +--- a/src/util/virarch.h ++++ b/src/util/virarch.h +@@ -70,6 +70,7 @@ typedef enum { + VIR_ARCH_XTENSAEB, /* XTensa 32 BE http://en.wikipedia.org/wiki/Xtensa#Processor_Cores */ + + VIR_ARCH_SW_64, /* SW64 64 LE XHB*/ ++ VIR_ARCH_LOONGARCH64, /* LoongArch 64 LE */ + + VIR_ARCH_LAST, + } virArch; +@@ -99,6 +100,8 @@ typedef enum { + + #define ARCH_IS_SW64(arch) ((arch) == VIR_ARCH_SW_64) + ++#define ARCH_IS_LOONGARCH(arch) ((arch) == VIR_ARCH_LOONGARCH64) ++ + typedef enum { + VIR_ARCH_LITTLE_ENDIAN, + VIR_ARCH_BIG_ENDIAN, +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/Config-some-capabilities-for-loongarch-virt-machine.patch b/generic_vdpa/libvirt/Config-some-capabilities-for-loongarch-virt-machine.patch new file mode 100644 index 0000000..add6100 --- /dev/null +++ b/generic_vdpa/libvirt/Config-some-capabilities-for-loongarch-virt-machine.patch @@ -0,0 +1,263 @@ +From 4b7f6284eaa3e3b15360e25848fc68b37ee6c768 Mon Sep 17 00:00:00 2001 +From: zhaotianrui +Date: Wed, 11 Jan 2023 11:56:03 -0500 +Subject: [PATCH 3/4] Config some capabilities for loongarch virt machine + +Config some capabilities for loongarch virt machine such as +PCI multi bus and the path of loongarch uefi binary. + +Signed-off-by: zhaotianrui +--- + src/qemu/qemu.conf | 3 +- + src/qemu/qemu_capabilities.c | 4 ++ + src/qemu/qemu_conf.c | 3 +- + src/qemu/qemu_domain.c | 31 ++++++++++- + src/qemu/qemu_domain.h | 1 + + src/qemu/qemu_domain_address.c | 86 ++++++++++++++++++++++++++++++ + src/qemu/test_libvirtd_qemu.aug.in | 1 + + 7 files changed, 125 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf +index abdbf07fec..3856087248 100644 +--- a/src/qemu/qemu.conf ++++ b/src/qemu/qemu.conf +@@ -771,7 +771,8 @@ + # "/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/loongarch_bios.bin:/usr/share/qemu/loongarch_vars.bin" + #] + + # The backend to use for handling stdout/stderr output from +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 0c3eb148b2..21b477cd4d 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -1983,6 +1983,10 @@ bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps, + * since forever */ + if (ARCH_IS_SW64(def->os.arch)) + return true; ++ /* loongarch64 support PCI-multibus on all machine types ++ * since forever */ ++ if (ARCH_IS_LOONGARCH(def->os.arch)) ++ return true; + + if (def->os.arch == VIR_ARCH_PPC || + ARCH_IS_PPC64(def->os.arch)) { +diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c +index 28319a1baf..3253875d6e 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -98,7 +98,8 @@ qemuDriverUnlock(virQEMUDriverPtr 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/loongarch_bios.bin:/usr/share/qemu/loongarch_vars.bin" + #endif + + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 37dac3694b..152c8615d5 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -5186,7 +5186,7 @@ qemuDomainDefValidateFeatures(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'"), +@@ -9089,6 +9089,11 @@ qemuDomainControllerDefPostParse(virDomainControllerDefPtr 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 */ +@@ -12985,6 +12990,20 @@ qemuDomainMachineIsPSeries(const char *machine, + return false; + } + ++static bool ++qemuDomainMachineIsLoongson(const char *machine, ++ const virArch arch) ++{ ++ if (!ARCH_IS_LOONGARCH(arch)) ++ return false; ++ ++ if (STREQ(machine, "loongson7a") || ++ STRPREFIX(machine, "loongson7a-")) { ++ return true; ++ } ++ ++ return false; ++} + + /* You should normally avoid this function and use + * qemuDomainHasBuiltinIDE() instead. */ +@@ -12996,7 +13015,8 @@ qemuDomainMachineHasBuiltinIDE(const char *machine, + STREQ(machine, "malta") || + STREQ(machine, "sun4u") || + STREQ(machine, "core3") || +- STREQ(machine, "g3beige"); ++ STREQ(machine, "g3beige") || ++ STREQ(machine, "loongson7a"); + } + + +@@ -13066,6 +13086,13 @@ qemuDomainIsPSeries(const virDomainDef *def) + } + + ++bool ++qemuDomainIsLoongson(const virDomainDef *def) ++{ ++ return qemuDomainMachineIsLoongson(def->os.machine, def->os.arch); ++} ++ ++ + bool + qemuDomainHasPCIRoot(const virDomainDef *def) + { +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 7603724ccd..368fc4030f 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -999,6 +999,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 ab6bce19f4..7f48773832 100644 +--- a/src/qemu/qemu_domain_address.c ++++ b/src/qemu/qemu_domain_address.c +@@ -2078,6 +2078,87 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, + return 0; + } + ++static int ++qemuDomainValidateDevicePCISlotsLoongson(virDomainDefPtr def, ++ virQEMUCapsPtr qemuCaps, ++ virDomainPCIAddressSetPtr addrs) ++{ ++ int ret = -1; ++ virPCIDeviceAddress tmp_addr; ++ bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); ++ g_autofree char *addrStr = NULL; ++ virDomainPCIConnectFlags flags = 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) ++ return -1; ++ } ++ ++ 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 */ ++ virDomainVideoDefPtr primaryVideo = def->videos[0]; ++ ++ if (virDeviceInfoPCIAddressIsWanted(&primaryVideo->info)) { ++ memset(&tmp_addr, 0, sizeof(tmp_addr)); ++ tmp_addr.slot = 2; ++ ++ if (!(addrStr = virPCIDeviceAddressAsString(&tmp_addr))) ++ return -1; ++ if (!virDomainPCIAddressValidate(addrs, &tmp_addr, ++ addrStr, flags, true)) ++ return ret; ++ ++ if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { ++ if (qemuDeviceVideoUsable) { ++ if (qemuDomainPCIAddressReserveNextAddr(addrs, ++ &primaryVideo->info) < 0) { ++ return ret; ++ } ++ } else { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("PCI address 0:0:2.0 is in use, " ++ "QEMU needs it for primary video")); ++ return ret; ++ } ++ } else { ++ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) ++ return ret; ++ primaryVideo->info.addr.pci = tmp_addr; ++ primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; ++ } ++ } else if (!qemuDeviceVideoUsable) { ++ if (primaryVideo->info.addr.pci.domain != 0 || ++ primaryVideo->info.addr.pci.bus != 0 || ++ primaryVideo->info.addr.pci.slot != 2 || ++ primaryVideo->info.addr.pci.function != 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Primary video card must have PCI address 0:0:2.0")); ++ return ret; ++ } ++ /* If TYPE == PCI, then qemuDomainCollectPCIAddress() function ++ * has already reserved the address, so we must skip */ ++ } ++ } else if (addrs->nbuses && !qemuDeviceVideoUsable) { ++ memset(&tmp_addr, 0, sizeof(tmp_addr)); ++ tmp_addr.slot = 2; ++ ++ if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { ++ VIR_DEBUG("PCI address 0:0:2.0 in use, future addition of a video" ++ " device will not be possible without manual" ++ " intervention"); ++ } else if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) { ++ return ret; ++ } ++ } ++ ++ ret = 0; ++ return ret; ++} + + static int + qemuDomainValidateDevicePCISlotsChipsets(virDomainDefPtr def, +@@ -2094,6 +2175,11 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDefPtr def, + return -1; + } + ++ if (qemuDomainIsLoongson(def) && ++ qemuDomainValidateDevicePCISlotsLoongson(def, qemuCaps, addrs) < 0) { ++ return -1; ++ } ++ + return 0; + } + +diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in +index 19da591aae..caa06a45cb 100644 +--- a/src/qemu/test_libvirtd_qemu.aug.in ++++ b/src/qemu/test_libvirtd_qemu.aug.in +@@ -95,6 +95,7 @@ module Test_libvirtd_qemu = + { "2" = "/usr/share/OVMF/OVMF_CODE.secboot.fd:/usr/share/OVMF/OVMF_VARS.fd" } + { "3" = "/usr/share/AAVMF/AAVMF_CODE.fd:/usr/share/AAVMF/AAVMF_VARS.fd" } + { "4" = "/usr/share/AAVMF/AAVMF32_CODE.fd:/usr/share/AAVMF/AAVMF32_VARS.fd" } ++ { "5" = "/usr/share/qemu/loongarch_bios.bin:/usr/share/qemu/loongarch_vars.bin" } + } + { "stdio_handler" = "logd" } + { "gluster_debug_level" = "9" } +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/Don-t-cache-device-mapper-major.patch b/generic_vdpa/libvirt/Don-t-cache-device-mapper-major.patch new file mode 100644 index 0000000..a4ef223 --- /dev/null +++ b/generic_vdpa/libvirt/Don-t-cache-device-mapper-major.patch @@ -0,0 +1,76 @@ +From 1c5804926a289882ff4a84f1c6ca6df1dd117215 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 31 Aug 2021 08:22:41 -0400 +Subject: [PATCH] Don't cache device-mapper major + +--- + src/util/virdevmapper.c | 19 +++++-------------- + 1 file changed, 5 insertions(+), 14 deletions(-) + +diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c +index a471504..2b9e689 100644 +--- a/src/util/virdevmapper.c ++++ b/src/util/virdevmapper.c +@@ -46,11 +46,8 @@ + + G_STATIC_ASSERT(BUF_SIZE > sizeof(struct dm_ioctl)); + +-static unsigned int virDMMajor; +- +- + static int +-virDevMapperOnceInit(void) ++virDevMapperGetMajor(unsigned int *major) + { + g_autofree char *buf = NULL; + VIR_AUTOSTRINGLIST lines = NULL; +@@ -69,7 +66,7 @@ virDevMapperOnceInit(void) + + if (sscanf(lines[i], "%u %ms\n", &maj, &dev) == 2 && + STREQ(dev, DM_NAME)) { +- virDMMajor = maj; ++ *major = maj; + break; + } + } +@@ -84,10 +81,6 @@ virDevMapperOnceInit(void) + return 0; + } + +- +-VIR_ONCE_GLOBAL_INIT(virDevMapper); +- +- + static void * + virDMIoctl(int controlFD, int cmd, struct dm_ioctl *dm, char **buf) + { +@@ -305,9 +298,6 @@ virDevMapperGetTargets(const char *path, + * consist of devices or yet another targets. If that's the + * case, we have to stop recursion somewhere. */ + +- if (virDevMapperInitialize() < 0) +- return -1; +- + if ((controlFD = virDMOpen()) < 0) + return -1; + +@@ -319,13 +309,14 @@ bool + virIsDevMapperDevice(const char *dev_name) + { + struct stat buf; ++ unsigned int major; + +- if (virDevMapperInitialize() < 0) ++ if (virDevMapperGetMajor(&major) < 0) + return false; + + if (!stat(dev_name, &buf) && + S_ISBLK(buf.st_mode) && +- major(buf.st_rdev) == virDMMajor) ++ major(buf.st_rdev) == major) + return true; + + return false; +-- +2.18.2 + diff --git a/generic_vdpa/libvirt/Don-t-call-qsort-over-NULL.patch b/generic_vdpa/libvirt/Don-t-call-qsort-over-NULL.patch new file mode 100644 index 0000000..6e866a2 --- /dev/null +++ b/generic_vdpa/libvirt/Don-t-call-qsort-over-NULL.patch @@ -0,0 +1,68 @@ +From bfcbf70e99b9fb06468de8135d3a251ef22e0cd3 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 14 Jun 2021 12:46:02 +0200 +Subject: [PATCH 094/108] Don't call qsort() over NULL + +In a few places it may happen that the array we want to sort is +still NULL (e.g. because there were no leases found, no paths for +secdriver to lock or no cache banks). However, passing NULL to +qsort() is undefined and even though glibc plays nicely we +shouldn't rely on undefined behaviour. + +Signed-off-by: Michal Privoznik +Reviewed-by: Tim Wiederhake +(cherry picked from commit 1ab5a37c4a70434a1dacebbdababb91baaa29ef1) +--- + src/conf/capabilities.c | 6 ++++-- + src/security/security_manager.c | 3 ++- + tools/nss/libvirt_nss.c | 3 ++- + 3 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c +index d6ec1f12f4..deb99cecd3 100644 +--- a/src/conf/capabilities.c ++++ b/src/conf/capabilities.c +@@ -1982,8 +1982,10 @@ virCapabilitiesInitCaches(virCapsPtr caps) + /* Sort the array in order for the tests to be predictable. This way we can + * still traverse the directory instead of guessing names (in case there is + * 'index1' and 'index3' but no 'index2'). */ +- qsort(caps->host.cache.banks, caps->host.cache.nbanks, +- sizeof(*caps->host.cache.banks), virCapsHostCacheBankSorter); ++ if (caps->host.cache.banks) { ++ qsort(caps->host.cache.banks, caps->host.cache.nbanks, ++ sizeof(*caps->host.cache.banks), virCapsHostCacheBankSorter); ++ } + + if (virCapabilitiesInitResctrlMemory(caps) < 0) + goto cleanup; +diff --git a/src/security/security_manager.c b/src/security/security_manager.c +index 9d5dfec12b..a74b663685 100644 +--- a/src/security/security_manager.c ++++ b/src/security/security_manager.c +@@ -1302,7 +1302,8 @@ virSecurityManagerMetadataLock(virSecurityManagerPtr mgr G_GNUC_UNUSED, + * paths in the same order and thus no deadlock can occur. + * Lastly, it makes searching for duplicate paths below + * simpler. */ +- qsort(paths, npaths, sizeof(*paths), cmpstringp); ++ if (paths) ++ qsort(paths, npaths, sizeof(*paths), cmpstringp); + + for (i = 0; i < npaths; i++) { + const char *p = paths[i]; +diff --git a/tools/nss/libvirt_nss.c b/tools/nss/libvirt_nss.c +index 3b89f72742..265ef236cc 100644 +--- a/tools/nss/libvirt_nss.c ++++ b/tools/nss/libvirt_nss.c +@@ -69,7 +69,8 @@ static void + sortAddr(leaseAddress *tmpAddress, + size_t ntmpAddress) + { +- qsort(tmpAddress, ntmpAddress, sizeof(*tmpAddress), leaseAddressSorter); ++ if (tmpAddress) ++ qsort(tmpAddress, ntmpAddress, sizeof(*tmpAddress), leaseAddressSorter); + } + + +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/Fix-allocation-of-virDomainFSDef.patch b/generic_vdpa/libvirt/Fix-allocation-of-virDomainFSDef.patch new file mode 100644 index 0000000..fb55fd5 --- /dev/null +++ b/generic_vdpa/libvirt/Fix-allocation-of-virDomainFSDef.patch @@ -0,0 +1,53 @@ +From 805efc1e0446e84c4b9bf9984c92b9e05b6ced62 Mon Sep 17 00:00:00 2001 +From: tangbin +Date: Wed, 23 Nov 2022 16:00:29 +0200 +Subject: [PATCH 09/23] Fix allocation of virDomainFSDef +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some less commonly used drivers were omitted when we switched +the allocator from a plain VIR_ALLOC to virDomainFSDefNew. + +https://bugzilla.redhat.com/show_bug.cgi?id=1846450 + +Fixes: da665fbd4858890fbb3bbf5da2a7b6ca37bb3220 +Signed-off-by: Ján Tomko +Reviewed-by: Andrea Bolognani + +Signed-off-by: tangbin +(cherry-pick from ea3320048897f5279bc49cb49d26f8099706a834) +--- + src/openvz/openvz_conf.c | 2 +- + src/vbox/vbox_common.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c +index 78547b8b28..15e1e2ae9f 100644 +--- a/src/openvz/openvz_conf.c ++++ b/src/openvz/openvz_conf.c +@@ -357,7 +357,7 @@ openvzReadFSConf(virDomainDefPtr def, + goto error; + } + +- if (VIR_ALLOC(fs) < 0) ++ if (!(fs = virDomainFSDefNew(NULL))) + goto error; + + veid_str = g_strdup_printf("%d", veid); +diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c +index e98ae04ec0..d06a5f79ab 100644 +--- a/src/vbox/vbox_common.c ++++ b/src/vbox/vbox_common.c +@@ -3620,7 +3620,7 @@ vboxDumpSharedFolders(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine + char *hostPath = NULL; + PRBool writable = PR_FALSE; + +- if (VIR_ALLOC(def->fss[i]) < 0) ++ if (!(def->fss[i] = virDomainFSDefNew(data->xmlopt))) + goto cleanup; + + def->fss[i]->type = VIR_DOMAIN_FS_TYPE_MOUNT; +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/Fix-potential-crash-during-driver-cleanup.patch b/generic_vdpa/libvirt/Fix-potential-crash-during-driver-cleanup.patch new file mode 100644 index 0000000..ed8ec7d --- /dev/null +++ b/generic_vdpa/libvirt/Fix-potential-crash-during-driver-cleanup.patch @@ -0,0 +1,58 @@ +From: Jim Fehlig +Date: Tue, 11 Apr 2023 09:15:43 -0600 +Subject: [PATCH] qemu: Fix potential crash during driver cleanup + +During qemu driver shutdown, objects are freed in qemuStateCleanup that +could still be used by active worker threads, resulting in crashes. E.g. +a worker thread could be processing a monitor EOF event after the +security manager is already disposed + +Program terminated with signal SIGSEGV, Segmentation fault. +#0 0x00007fd9a9a1e1fe in virSecurityManagerMoveImageMetadata (mgr=0x7fd948012160, pid=-1, src=src@entry=0x7fd98c072c90, dst=dst@entry=0x0) + at ../../src/security/security_manager.c:468 +#1 0x00007fd9646ff0f0 in qemuSecurityMoveImageMetadata (driver=driver@entry=0x7fd948043830, vm=vm@entry=0x7fd98c066db0, src=src@entry=0x7fd98c072c90, + dst=dst@entry=0x0) at ../../src/qemu/qemu_security.c:182 +#2 0x00007fd96462c7b0 in qemuBlockRemoveImageMetadata (driver=driver@entry=0x7fd948043830, vm=vm@entry=0x7fd98c066db0, diskTarget=0x7fd98c072530 "vda", + src=) at ../../src/qemu/qemu_block.c:2628 +#3 0x00007fd9646929d6 in qemuProcessStop (driver=driver@entry=0x7fd948043830, vm=vm@entry=0x7fd98c066db0, reason=reason@entry=VIR_DOMAIN_SHUTOFF_SHUTDOWN, + asyncJob=asyncJob@entry=QEMU_ASYNC_JOB_NONE, flags=) at ../../src/qemu/qemu_process.c:7585 +#4 0x00007fd9646fc842 in processMonitorEOFEvent (vm=0x7fd98c066db0, driver=0x7fd948043830) at ../../src/qemu/qemu_driver.c:4794 +#5 qemuProcessEventHandler (data=0x561a93febb60, opaque=0x7fd948043830) at ../../src/qemu/qemu_driver.c:4900 +#6 0x00007fd9a9971a31 in virThreadPoolWorker (opaque=opaque@entry=0x561a93fb58e0) at ../../src/util/virthreadpool.c:163 +(gdb) p mgr->drv +$2 = (virSecurityDriverPtr) 0x0 + +Prior to commit 7cf76d4e3ab, the worker thread pool was freed before +disposing any driver objects. Let's return to that pattern, but leave +the other changes made by 7cf76d4e3ab. + +Signed-off-by: Tamara Schmitz +Signed-off-by: Jim Fehlig +Reviewed-by: Martin Kletzander +--- + src/qemu/qemu_driver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 32b3ef3..7a70d6c 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -1120,6 +1120,7 @@ qemuStateCleanup(void) + if (!qemu_driver) + return -1; + ++ virThreadPoolFree(qemu_driver->workerPool); + virObjectUnref(qemu_driver->migrationErrors); + virObjectUnref(qemu_driver->closeCallbacks); + virLockManagerPluginUnref(qemu_driver->lockManager); +@@ -1139,7 +1140,6 @@ qemuStateCleanup(void) + ebtablesContextFree(qemu_driver->ebtables); + VIR_FREE(qemu_driver->qemuImgBinary); + virObjectUnref(qemu_driver->domains); +- virThreadPoolFree(qemu_driver->workerPool); + + if (qemu_driver->lockFD != -1) + virPidFileRelease(qemu_driver->config->stateDir, "driver", qemu_driver->lockFD); +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/Hotpatch-introduce-DomainHotpatchManage-API.patch b/generic_vdpa/libvirt/Hotpatch-introduce-DomainHotpatchManage-API.patch new file mode 100644 index 0000000..26b643d --- /dev/null +++ b/generic_vdpa/libvirt/Hotpatch-introduce-DomainHotpatchManage-API.patch @@ -0,0 +1,211 @@ +From 9a12606bb5caf3e213ce1564445d88325592e642 Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Tue, 19 Oct 2021 14:50:32 +0800 +Subject: [PATCH] Hotpatch: introduce DomainHotpatchManage API + +Signed-off-by: Hao Wang +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + include/libvirt/libvirt-domain.h | 18 ++++++++++ + scripts/check-aclrules.py | 1 + + src/driver-hypervisor.h | 8 +++++ + src/libvirt-domain.c | 58 ++++++++++++++++++++++++++++++++ + src/libvirt_public.syms | 4 +++ + src/remote/remote_driver.c | 1 + + src/remote/remote_protocol.x | 20 ++++++++++- + 7 files changed, 109 insertions(+), 1 deletion(-) + +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index 90cb652db1..f91061724b 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -4991,4 +4991,22 @@ int virDomainBackupBegin(virDomainPtr domain, + char *virDomainBackupGetXMLDesc(virDomainPtr domain, + unsigned int flags); + ++typedef enum { ++ VIR_DOMAIN_HOTPATCH_NONE = 0, /* No action */ ++ VIR_DOMAIN_HOTPATCH_APPLY, /* Apply hotpatch */ ++ VIR_DOMAIN_HOTPATCH_UNAPPLY, /* Unapply hotpatch */ ++ VIR_DOMAIN_HOTPATCH_QUERY, /* Query hotpatch */ ++ ++# ifdef VIR_ENUM_SENTINELS ++ VIR_DOMAIN_HOTPATCH_LAST ++# endif ++} virDomainHotpatchAction; ++ ++char * ++virDomainHotpatchManage(virDomainPtr domain, ++ int action, ++ const char *patch, ++ const char *id, ++ unsigned int flags); ++ + #endif /* LIBVIRT_DOMAIN_H */ +diff --git a/scripts/check-aclrules.py b/scripts/check-aclrules.py +index a1fa473174..e196f81de9 100755 +--- a/scripts/check-aclrules.py ++++ b/scripts/check-aclrules.py +@@ -53,6 +53,7 @@ whitelist = { + "connectURIProbe": True, + "localOnly": True, + "domainQemuAttach": True, ++ "domainHotpatchManage": True, + } + + # XXX this vzDomainMigrateConfirm3Params looks +diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h +index bce023017d..afc21a0b3f 100644 +--- a/src/driver-hypervisor.h ++++ b/src/driver-hypervisor.h +@@ -1387,6 +1387,13 @@ typedef char * + (*virDrvDomainBackupGetXMLDesc)(virDomainPtr domain, + unsigned int flags); + ++typedef char * ++(*virDrvDomainHotpatchManage)(virDomainPtr domain, ++ int action, ++ const char *patch, ++ const char *id, ++ unsigned int flags); ++ + typedef struct _virHypervisorDriver virHypervisorDriver; + typedef virHypervisorDriver *virHypervisorDriverPtr; + +@@ -1650,4 +1657,5 @@ struct _virHypervisorDriver { + virDrvDomainAgentSetResponseTimeout domainAgentSetResponseTimeout; + virDrvDomainBackupBegin domainBackupBegin; + virDrvDomainBackupGetXMLDesc domainBackupGetXMLDesc; ++ virDrvDomainHotpatchManage domainHotpatchManage; + }; +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index a12809c2d5..068ab52f54 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -12733,3 +12733,61 @@ virDomainBackupGetXMLDesc(virDomainPtr domain, + virDispatchError(conn); + return NULL; + } ++ ++/** ++ * virDomainHotpatchManage: ++ * @domain: a domain object ++ * @action: the action type from virDomainHotpatchAction ++ * @patch: the target hotpatch file ++ * @id: the patch id of the target hotpatch ++ * @flags: extra flags; not used yet, so callers should always pass 0 ++ * ++ * Manage hotpatch for the current domain according to @action. ++ * ++ * If the @action is set to VIR_DOMAIN_HOTPATCH_APPLY, apply hotpatch ++ * @patch to the current domain. ++ * ++ * If the @action is set to VIR_DOMAIN_HOTPATCH_UNAPPLY, unapply the ++ * hotpatch which is matched with @id from the current domain. ++ * ++ * If the @action is set to VIR_DOMAIN_HOTPATCH_QUERY, query infomations ++ * of the applied hotpatch of the current domain. ++ * ++ * Returns success messages in case of success, NULL otherwise. ++ */ ++char * ++virDomainHotpatchManage(virDomainPtr domain, ++ int action, ++ const char *patch, ++ const char *id, ++ unsigned int flags) ++{ ++ virConnectPtr conn; ++ ++ virResetLastError(); ++ ++ virCheckDomainReturn(domain, NULL); ++ conn = domain->conn; ++ ++ virCheckReadOnlyGoto(conn->flags, error); ++ ++ if (action == VIR_DOMAIN_HOTPATCH_APPLY) ++ virCheckNonNullArgGoto(patch, error); ++ ++ if (action == VIR_DOMAIN_HOTPATCH_UNAPPLY) ++ virCheckNonNullArgGoto(id, error); ++ ++ if (conn->driver->domainHotpatchManage) { ++ char *ret; ++ ret = conn->driver->domainHotpatchManage(domain, action, patch, id, flags); ++ if (!ret) ++ goto error; ++ ++ return ret; ++ } ++ ++ virReportUnsupportedError(); ++ error: ++ virDispatchError(conn); ++ return NULL; ++} +diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms +index 539d2e3943..0ad0b9e489 100644 +--- a/src/libvirt_public.syms ++++ b/src/libvirt_public.syms +@@ -873,4 +873,8 @@ LIBVIRT_6.0.0 { + virDomainBackupGetXMLDesc; + } LIBVIRT_5.10.0; + ++LIBVIRT_6.2.0 { ++ global: ++ virDomainHotpatchManage; ++} LIBVIRT_6.0.0; + # .... define new API here using predicted next version number .... +diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c +index 7bae0c2514..1202d44017 100644 +--- a/src/remote/remote_driver.c ++++ b/src/remote/remote_driver.c +@@ -8684,6 +8684,7 @@ static virHypervisorDriver hypervisor_driver = { + .domainAgentSetResponseTimeout = remoteDomainAgentSetResponseTimeout, /* 5.10.0 */ + .domainBackupBegin = remoteDomainBackupBegin, /* 6.0.0 */ + .domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */ ++ .domainHotpatchManage = remoteDomainHotpatchManage, /* 6.2.0 */ + }; + + static virNetworkDriver network_driver = { +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index 8b05082b61..ee13075ce1 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -3771,6 +3771,18 @@ struct remote_domain_backup_get_xml_desc_ret { + remote_nonnull_string xml; + }; + ++struct remote_domain_hotpatch_manage_args { ++ remote_nonnull_domain dom; ++ int action; ++ remote_string patch; ++ remote_string id; ++ unsigned int flags; ++}; ++ ++struct remote_domain_hotpatch_manage_ret { ++ remote_string info; ++}; ++ + /*----- Protocol. -----*/ + + /* Define the program number, protocol version and procedure numbers here. */ +@@ -6668,5 +6680,11 @@ enum remote_procedure { + * @priority: high + * @acl: domain:read + */ +- REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 422 ++ REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 422, ++ ++ /** ++ * @generate: both ++ * @acl: domain:read ++ */ ++ REMOTE_PROC_DOMAIN_HOTPATCH_MANAGE = 800 + }; +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/Implement-the-method-of-getting-host-info-for-loonga.patch b/generic_vdpa/libvirt/Implement-the-method-of-getting-host-info-for-loonga.patch new file mode 100644 index 0000000..d386a0c --- /dev/null +++ b/generic_vdpa/libvirt/Implement-the-method-of-getting-host-info-for-loonga.patch @@ -0,0 +1,65 @@ +From 4123437e633f05af0ae8091d5db440597394ba36 Mon Sep 17 00:00:00 2001 +From: zhaotianrui +Date: Wed, 11 Jan 2023 14:09:41 -0500 +Subject: [PATCH 4/4] Implement the method of getting host info for loongarch + +Implement method for loongarch to get host info, such as +cpu frequency, system info, etc. + +Signed-off-by: zhaotianrui +--- + src/util/virarch.c | 2 ++ + src/util/virhostcpu.c | 2 +- + src/util/virsysinfo.c | 3 ++- + 3 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/util/virarch.c b/src/util/virarch.c +index decdbdd7ac..0520a1c80b 100644 +--- a/src/util/virarch.c ++++ b/src/util/virarch.c +@@ -227,6 +227,8 @@ virArch virArchFromHost(void) + arch = VIR_ARCH_X86_64; + } else if (STREQ(ut.machine, "sw_64")) { + arch = VIR_ARCH_SW_64; ++ } 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/virhostcpu.c b/src/util/virhostcpu.c +index 5ec98d6016..ce3da7e6ec 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -577,7 +577,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 8a53702224..6d4778fed7 100644 +--- a/src/util/virsysinfo.c ++++ b/src/util/virsysinfo.c +@@ -1190,7 +1190,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(); +@@ -1198,6 +1198,7 @@ virSysinfoRead(void) + (defined(__x86_64__) || \ + defined(__i386__) || \ + defined(__amd64__) || \ ++ defined(__loongarch__) || \ + defined(__sw_64__)) + return virSysinfoReadDMI(); + #else /* WIN32 || not supported arch */ +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/Include-vdpa-devices-in-node-device-list.patch b/generic_vdpa/libvirt/Include-vdpa-devices-in-node-device-list.patch new file mode 100644 index 0000000..9fb0674 --- /dev/null +++ b/generic_vdpa/libvirt/Include-vdpa-devices-in-node-device-list.patch @@ -0,0 +1,322 @@ +From e8597e64126a5cf77fbb9422977268878a6376b6 Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Wed, 14 Oct 2020 12:08:30 -0500 +Subject: [PATCH] Include vdpa devices in node device list + +The current udev node device driver ignores all events related to vdpa +devices. Since libvirt now supports vDPA network devices, include these +devices in the device list. + +Example output: + +virsh # nodedev-list +[...ommitted long list of nodedevs...] +vdpa_vdpa0 + +virsh # nodedev-dumpxml vdpa_vdpa0 + + vdpa_vdpa0 + /sys/devices/vdpa0 + computer + + vhost_vdpa + + + /dev/vhost-vdpa-0 + + + +NOTE: normally the 'parent' would be a PCI device instead of 'computer', +but this example output is from the vdpa_sim kernel module, so it +doesn't have a normal parent device. + +Signed-off-by: Jonathon Jongsma +Signed-off-by: AlexChen +--- + docs/formatnode.html.in | 9 ++++++ + docs/schemas/nodedev.rng | 10 ++++++ + include/libvirt/libvirt-nodedev.h | 1 + + src/conf/node_device_conf.c | 13 ++++++++ + src/conf/node_device_conf.h | 11 ++++++- + src/conf/virnodedeviceobj.c | 4 ++- + src/node_device/node_device_udev.c | 51 ++++++++++++++++++++++++++++++ + tools/virsh-nodedev.c | 3 ++ + 8 files changed, 100 insertions(+), 2 deletions(-) + +diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in +index c2a8f8fb7a..573391ef0f 100644 +--- a/docs/formatnode.html.in ++++ b/docs/formatnode.html.in +@@ -341,6 +341,15 @@ +
The device number.
+ + ++
vdpa
++
Describes a virtual datapath acceleration (vDPA) network device. ++ Since 6.9.0. Sub-elements include: ++
++
chardev
++
The path to the character device that is used to access the ++ device.
++
++
+ + + +diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng +index fe6ffa0b53..4f197b327a 100644 +--- a/docs/schemas/nodedev.rng ++++ b/docs/schemas/nodedev.rng +@@ -85,6 +85,7 @@ + + + ++ + + + +@@ -651,6 +652,15 @@ + + + ++ ++ ++ vdpa ++ ++ ++ ++ ++ ++ + + + +diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h +index a2ad61ac6d..4129f1afed 100644 +--- a/include/libvirt/libvirt-nodedev.h ++++ b/include/libvirt/libvirt-nodedev.h +@@ -81,6 +81,7 @@ typedef enum { + VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES = 1 << 13, /* Capable of mediated devices */ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV = 1 << 14, /* Mediated device */ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV = 1 << 15, /* CCW device */ ++ VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA = 1 << 17, /* vDPA device */ + } virConnectListAllNodeDeviceFlags; + + int virConnectListAllNodeDevices (virConnectPtr conn, +diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c +index d64f6d3986..41d7c7d12e 100644 +--- a/src/conf/node_device_conf.c ++++ b/src/conf/node_device_conf.c +@@ -65,6 +65,7 @@ VIR_ENUM_IMPL(virNodeDevCap, + "mdev_types", + "mdev", + "ccw", ++ "vdpa", + ); + + VIR_ENUM_IMPL(virNodeDevNetCap, +@@ -500,6 +501,12 @@ virNodeDeviceCapStorageDefFormat(virBufferPtr buf, + virBufferAddLit(buf, "\n"); + } + ++static void ++virNodeDeviceCapVDPADefFormat(virBufferPtr buf, ++ const virNodeDevCapData *data) ++{ ++ virBufferEscapeString(buf, "%s\n", data->vdpa.chardev); ++} + + char * + virNodeDeviceDefFormat(const virNodeDeviceDef *def) +@@ -595,6 +602,9 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) + virBufferAsprintf(&buf, "0x%04x\n", + data->ccw_dev.devno); + break; ++ case VIR_NODE_DEV_CAP_VDPA: ++ virNodeDeviceCapVDPADefFormat(&buf, data); ++ break; + case VIR_NODE_DEV_CAP_MDEV_TYPES: + case VIR_NODE_DEV_CAP_FC_HOST: + case VIR_NODE_DEV_CAP_VPORTS: +@@ -1897,6 +1907,7 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, + case VIR_NODE_DEV_CAP_FC_HOST: + case VIR_NODE_DEV_CAP_VPORTS: + case VIR_NODE_DEV_CAP_SCSI_GENERIC: ++ case VIR_NODE_DEV_CAP_VDPA: + case VIR_NODE_DEV_CAP_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown capability type '%d' for '%s'"), +@@ -2209,6 +2220,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) + case VIR_NODE_DEV_CAP_FC_HOST: + case VIR_NODE_DEV_CAP_VPORTS: + case VIR_NODE_DEV_CAP_CCW_DEV: ++ case VIR_NODE_DEV_CAP_VDPA: + case VIR_NODE_DEV_CAP_LAST: + /* This case is here to shutup the compiler */ + break; +@@ -2262,6 +2274,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) + case VIR_NODE_DEV_CAP_MDEV_TYPES: + case VIR_NODE_DEV_CAP_MDEV: + case VIR_NODE_DEV_CAP_CCW_DEV: ++ case VIR_NODE_DEV_CAP_VDPA: + case VIR_NODE_DEV_CAP_LAST: + break; + } +diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h +index 9e4b0847fb..a14eaef742 100644 +--- a/src/conf/node_device_conf.h ++++ b/src/conf/node_device_conf.h +@@ -64,6 +64,7 @@ typedef enum { + VIR_NODE_DEV_CAP_MDEV_TYPES, /* Device capable of mediated devices */ + VIR_NODE_DEV_CAP_MDEV, /* Mediated device */ + VIR_NODE_DEV_CAP_CCW_DEV, /* s390 CCW device */ ++ VIR_NODE_DEV_CAP_VDPA, /* vDPA device */ + + VIR_NODE_DEV_CAP_LAST + } virNodeDevCapType; +@@ -271,6 +272,12 @@ struct _virNodeDevCapCCW { + unsigned int devno; + }; + ++typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA; ++typedef virNodeDevCapVDPA *virNodeDevCapVDPAPtr; ++struct _virNodeDevCapVDPA { ++ char *chardev; ++}; ++ + typedef struct _virNodeDevCapData virNodeDevCapData; + typedef virNodeDevCapData *virNodeDevCapDataPtr; + struct _virNodeDevCapData { +@@ -289,6 +296,7 @@ struct _virNodeDevCapData { + virNodeDevCapDRM drm; + virNodeDevCapMdev mdev; + virNodeDevCapCCW ccw_dev; ++ virNodeDevCapVDPA vdpa; + }; + }; + +@@ -364,7 +372,8 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps); + VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM | \ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES | \ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV | \ +- VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV) ++ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV | \ ++ VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA) + + int + virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host); +diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c +index 3a34a324ca..be111741bf 100644 +--- a/src/conf/virnodedeviceobj.c ++++ b/src/conf/virnodedeviceobj.c +@@ -676,6 +676,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, + case VIR_NODE_DEV_CAP_MDEV_TYPES: + case VIR_NODE_DEV_CAP_MDEV: + case VIR_NODE_DEV_CAP_CCW_DEV: ++ case VIR_NODE_DEV_CAP_VDPA: + case VIR_NODE_DEV_CAP_LAST: + break; + } +@@ -826,7 +827,8 @@ virNodeDeviceObjMatch(virNodeDeviceObjPtr obj, + MATCH(DRM) || + MATCH(MDEV_TYPES) || + MATCH(MDEV) || +- MATCH(CCW_DEV))) ++ MATCH(CCW_DEV) || ++ MATCH(VDPA))) + return false; + } + +diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c +index 0d8a7db5c6..2764315325 100644 +--- a/src/node_device/node_device_udev.c ++++ b/src/node_device/node_device_udev.c +@@ -1089,6 +1089,53 @@ udevProcessCCW(struct udev_device *device, + return 0; + } + ++static int ++udevGetVDPACharDev(const char *sysfs_path, ++ virNodeDevCapDataPtr data) ++{ ++ struct dirent *entry; ++ DIR *dir = NULL; ++ int direrr; ++ ++ if (virDirOpenIfExists(&dir, sysfs_path) <= 0) ++ return -1; ++ ++ while ((direrr = virDirRead(dir, &entry, NULL)) > 0) { ++ if (g_str_has_prefix(entry->d_name, "vhost-vdpa")) { ++ g_autofree char *chardev = g_strdup_printf("/dev/%s", entry->d_name); ++ ++ if (!virFileExists(chardev)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("vDPA chardev path '%s' does not exist"), ++ chardev); ++ return -1; ++ } ++ VIR_DEBUG("vDPA chardev is at '%s'", chardev); ++ ++ data->vdpa.chardev = g_steal_pointer(&chardev); ++ break; ++ } ++ } ++ ++ if (direrr < 0) ++ return -1; ++ ++ return 0; ++} ++ ++static int ++udevProcessVDPA(struct udev_device *device, ++ virNodeDeviceDefPtr def) ++{ ++ if (udevGenerateDeviceName(device, def, NULL) != 0) ++ return -1; ++ ++ if (udevGetVDPACharDev(def->sysfs_path, &def->caps->data) < 0) ++ return -1; ++ ++ return 0; ++} ++ + + static int + udevGetDeviceNodes(struct udev_device *device, +@@ -1168,6 +1215,8 @@ udevGetDeviceType(struct udev_device *device, + *type = VIR_NODE_DEV_CAP_MDEV; + else if (STREQ_NULLABLE(subsystem, "ccw")) + *type = VIR_NODE_DEV_CAP_CCW_DEV; ++ else if (STREQ_NULLABLE(subsystem, "vdpa")) ++ *type = VIR_NODE_DEV_CAP_VDPA; + + VIR_FREE(subsystem); + } +@@ -1212,6 +1261,8 @@ udevGetDeviceDetails(struct udev_device *device, + return udevProcessMediatedDevice(device, def); + case VIR_NODE_DEV_CAP_CCW_DEV: + return udevProcessCCW(device, def); ++ case VIR_NODE_DEV_CAP_VDPA: ++ return udevProcessVDPA(device, def); + case VIR_NODE_DEV_CAP_MDEV_TYPES: + case VIR_NODE_DEV_CAP_SYSTEM: + case VIR_NODE_DEV_CAP_FC_HOST: +diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c +index 7f091d7cf8..f831b36054 100644 +--- a/tools/virsh-nodedev.c ++++ b/tools/virsh-nodedev.c +@@ -462,6 +462,9 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) + case VIR_NODE_DEV_CAP_CCW_DEV: + flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV; + break; ++ case VIR_NODE_DEV_CAP_VDPA: ++ flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_VDPA; ++ break; + case VIR_NODE_DEV_CAP_LAST: + break; + } +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/Revert-libvirt-support-aarch64-vtpm-with-parameter-t.patch b/generic_vdpa/libvirt/Revert-libvirt-support-aarch64-vtpm-with-parameter-t.patch new file mode 100644 index 0000000..a26b4ce --- /dev/null +++ b/generic_vdpa/libvirt/Revert-libvirt-support-aarch64-vtpm-with-parameter-t.patch @@ -0,0 +1,108 @@ +From 78c25600daf2a2822e7ecec2af9e7458b9f44eff Mon Sep 17 00:00:00 2001 +From: yezengruan +Date: Sat, 12 Mar 2022 09:35:07 +0800 +Subject: [PATCH 1/6] Revert libvirt: support aarch64 vtpm with parameter + tpm-tis-device + +Before backport the patch support aarch64 vtpm, let's +revert it first. + +Signed-off-by: yezengruan +--- + src/conf/domain_conf.c | 1 - + src/conf/domain_conf.h | 1 - + src/qemu/qemu_capabilities.c | 9 +-------- + src/qemu/qemu_capabilities.h | 4 +--- + src/qemu/qemu_domain.c | 3 --- + 5 files changed, 2 insertions(+), 16 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 4e3bcf479c..54228a2151 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -1141,7 +1141,6 @@ VIR_ENUM_IMPL(virDomainTPMModel, + "tpm-tis", + "tpm-crb", + "tpm-spapr", +- "tpm-tis-device", + ); + + VIR_ENUM_IMPL(virDomainTPMBackend, +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index ccee986849..e057c384c6 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -1280,7 +1280,6 @@ typedef enum { + VIR_DOMAIN_TPM_MODEL_TIS, + VIR_DOMAIN_TPM_MODEL_CRB, + VIR_DOMAIN_TPM_MODEL_SPAPR, +- VIR_DOMAIN_TPM_MODEL_TIS_DEVICE, + + VIR_DOMAIN_TPM_MODEL_LAST + } virDomainTPMModel; +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 6013be9d05..0fb3e74c77 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -568,9 +568,7 @@ VIR_ENUM_IMPL(virQEMUCaps, + "blockdev-snapshot.allow-write-only-overlay", + "blockdev-reopen", + "storage.werror", +- +- /* 360 */ +- "tpm-tis-device", ++ + "migration-param.bandwidth", + "migration-param.downtime", + "migration-param.xbzrle-cache-size", +@@ -1292,7 +1290,6 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { + { "rng-builtin", QEMU_CAPS_OBJECT_RNG_BUILTIN }, + { "tpm-spapr", QEMU_CAPS_DEVICE_TPM_SPAPR }, + { "vhost-user-fs-device", QEMU_CAPS_DEVICE_VHOST_USER_FS }, +- { "tpm-tis-device", QEMU_CAPS_DEVICE_TPM_TIS_DEVICE }, + }; + + static struct virQEMUCapsStringFlags virQEMUCapsDevicePropsVirtioBalloon[] = { +@@ -3100,10 +3097,6 @@ const struct tpmTypeToCaps virQEMUCapsTPMModelsToCaps[] = { + .type = VIR_DOMAIN_TPM_MODEL_SPAPR, + .caps = QEMU_CAPS_DEVICE_TPM_SPAPR, + }, +- { +- .type = VIR_DOMAIN_TPM_MODEL_TIS_DEVICE, +- .caps = QEMU_CAPS_DEVICE_TPM_TIS_DEVICE, +- }, + }; + + static int +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 5f28006b48..10a6ce50e7 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -549,9 +549,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY, /* blockdev-snapshot has the 'allow-write-only-overlay' feature */ + QEMU_CAPS_BLOCKDEV_REOPEN, /* 'blockdev-reopen' qmp command is supported */ + QEMU_CAPS_STORAGE_WERROR, /* virtio-blk,scsi-hd.werror */ +- +- /* 360 */ +- QEMU_CAPS_DEVICE_TPM_TIS_DEVICE, /* -device tpm-tis-device */ ++ + QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH, /* max-bandwidth field in migrate-set-parameters */ + QEMU_CAPS_MIGRATION_PARAM_DOWNTIME, /* downtime-limit field in migrate-set-parameters */ + QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, /* xbzrle-cache-size field in migrate-set-parameters */ +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 2351cac120..cb2fbdc179 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -8130,9 +8130,6 @@ qemuDomainDeviceDefValidateTPM(virDomainTPMDef *tpm, + case VIR_DOMAIN_TPM_MODEL_SPAPR: + flag = QEMU_CAPS_DEVICE_TPM_SPAPR; + break; +- case VIR_DOMAIN_TPM_MODEL_TIS_DEVICE: +- flag = QEMU_CAPS_DEVICE_TPM_TIS_DEVICE; +- break; + case VIR_DOMAIN_TPM_MODEL_LAST: + default: + virReportEnumRangeError(virDomainTPMModel, tpm->model); +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/Revert-selinux-adapt-to-libselinux.patch b/generic_vdpa/libvirt/Revert-selinux-adapt-to-libselinux.patch new file mode 100644 index 0000000..9f5e6ae --- /dev/null +++ b/generic_vdpa/libvirt/Revert-selinux-adapt-to-libselinux.patch @@ -0,0 +1,36 @@ +From 3dc1e0f37c013c317f3e868d1e4a6668d8f18a03 Mon Sep 17 00:00:00 2001 +From: mayunlong +Date: Wed, 9 Aug 2023 20:51:37 +0800 +Subject: [PATCH] Revert "selinux: adapt to libselinux" + +use the solution modified by the upstream community torevert this patch +This reverts commit 20fd0fb6b915363efecd2d108363995d8dea8e1a. +--- + src/security/security_selinux.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c +index cb4dc3e101..c91c7ca484 100644 +--- a/src/security/security_selinux.c ++++ b/src/security/security_selinux.c +@@ -541,7 +541,7 @@ static char * + virSecuritySELinuxContextAddRange(char *src, + char *dst) + { +- const char *str = NULL; ++ char *str = NULL; + char *ret = NULL; + context_t srccon = NULL; + context_t dstcon = NULL; +@@ -582,7 +582,7 @@ virSecuritySELinuxGenNewContext(const char *basecontext, + { + context_t context = NULL; + char *ret = NULL; +- const char *str; ++ char *str; + char *ourSecContext = NULL; + context_t ourContext = NULL; + +-- +2.41.0.windows.1 + diff --git a/generic_vdpa/libvirt/Revert-tests-disabale-storage-tests.patch b/generic_vdpa/libvirt/Revert-tests-disabale-storage-tests.patch new file mode 100644 index 0000000..78cab82 --- /dev/null +++ b/generic_vdpa/libvirt/Revert-tests-disabale-storage-tests.patch @@ -0,0 +1,42 @@ +From 8629a253113a019215b38f7206db03892157a370 Mon Sep 17 00:00:00 2001 +From: imxcc +Date: Sat, 29 Jan 2022 17:14:59 +0800 +Subject: [PATCH] Revert tests: disabale storage tests + +Signed-off-by: imxcc +--- + tests/Makefile.am | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index abb261e..ada5b8f 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -363,10 +363,16 @@ endif WITH_NWFILTER + + if WITH_STORAGE + test_programs += storagevolxml2argvtest ++test_programs += storagepoolxml2argvtest + test_programs += virstorageutiltest ++test_programs += storagepoolxml2xmltest + test_programs += storagepoolcapstest + endif WITH_STORAGE + ++if WITH_STORAGE_FS ++test_programs += virstoragetest ++endif WITH_STORAGE_FS ++ + if WITH_LINUX + test_programs += virscsitest + endif WITH_LINUX +@@ -424,6 +430,7 @@ test_scripts += $(libvirtd_test_scripts) + + test_programs += \ + eventtest \ ++ virdrivermoduletest \ + virdriverconnvalidatetest + else ! WITH_LIBVIRTD + EXTRA_DIST += $(libvirtd_test_scripts) +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/Use-un-signed-printf-specifiers-correctly.patch b/generic_vdpa/libvirt/Use-un-signed-printf-specifiers-correctly.patch new file mode 100644 index 0000000..04f90f4 --- /dev/null +++ b/generic_vdpa/libvirt/Use-un-signed-printf-specifiers-correctly.patch @@ -0,0 +1,100 @@ +From 37a05df2eb7e880c1bde301adf2b2eb32fc9a891 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 22 Sep 2020 22:17:03 +0200 +Subject: [PATCH] Use (un)signed printf specifiers correctly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Various places reported by cppcheck's invalidPrintfArgType_sint +and invalidPrintfArgType_uint. + +Signed-off-by: Ján Tomko +Reviewed-by: Peter Krempa +Signed-off-by: zhujun2 +(cherry-pick from 8b80d9f0f924ddf900b726871916f8ba5ae29243) +--- + examples/c/domain/domtop.c | 2 +- + examples/c/domain/suspend.c | 2 +- + tests/qemusecuritymock.c | 2 +- + tests/virhashtest.c | 4 ++-- + tests/virpcimock.c | 2 +- + 5 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/examples/c/domain/domtop.c b/examples/c/domain/domtop.c +index 15611c586d..5228445b7c 100644 +--- a/examples/c/domain/domtop.c ++++ b/examples/c/domain/domtop.c +@@ -115,7 +115,7 @@ parse_argv(int argc, char *argv[], + } + *milliseconds = val; + if (*milliseconds != val) { +- ERROR("Integer overflow: %ld", val); ++ ERROR("Integer overflow: %lu", val); + exit(EXIT_FAILURE); + } + break; +diff --git a/examples/c/domain/suspend.c b/examples/c/domain/suspend.c +index 980c4584c7..3ff24f6861 100644 +--- a/examples/c/domain/suspend.c ++++ b/examples/c/domain/suspend.c +@@ -105,7 +105,7 @@ parse_argv(int argc, char *argv[], + } + *seconds = val; + if (*seconds != val) { +- ERROR("Integer overflow: %ld", val); ++ ERROR("Integer overflow: %lu", val); + return -1; + } + break; +diff --git a/tests/qemusecuritymock.c b/tests/qemusecuritymock.c +index ad182c7bf7..e1057bef7b 100644 +--- a/tests/qemusecuritymock.c ++++ b/tests/qemusecuritymock.c +@@ -269,7 +269,7 @@ mock_chown(const char *path, + int ret = -1; + + if (gid >> 16 || uid >> 16) { +- fprintf(stderr, "Attempt to set too high UID or GID: %lld %lld", ++ fprintf(stderr, "Attempt to set too high UID or GID: %llu %llu", + (unsigned long long) uid, (unsigned long long) gid); + abort(); + } +diff --git a/tests/virhashtest.c b/tests/virhashtest.c +index 4d05cbb0f8..af30791241 100644 +--- a/tests/virhashtest.c ++++ b/tests/virhashtest.c +@@ -34,7 +34,7 @@ testHashInit(int size) + } + + if (virHashTableSize(hash) != oldsize) { +- VIR_TEST_DEBUG("hash grown from %zd to %zd", ++ VIR_TEST_DEBUG("hash grown from %zu to %zu", + (size_t)oldsize, (size_t)virHashTableSize(hash)); + } + } +@@ -313,7 +313,7 @@ testHashRemoveSet(const void *data G_GNUC_UNUSED) + + if (count != rcount) { + VIR_TEST_VERBOSE("\nvirHashRemoveSet didn't remove expected number of" +- " entries, %d != %u", ++ " entries, %d != %d", + rcount, count); + goto cleanup; + } +diff --git a/tests/virpcimock.c b/tests/virpcimock.c +index 92b6f810d8..d0fe11e5f1 100644 +--- a/tests/virpcimock.c ++++ b/tests/virpcimock.c +@@ -120,7 +120,7 @@ struct pciDeviceAddress { + unsigned int device; + unsigned int function; + }; +-# define ADDR_STR_FMT "%04x:%02x:%02x.%d" ++# define ADDR_STR_FMT "%04x:%02x:%02x.%u" + + struct pciDevice { + struct pciDeviceAddress addr; +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/add-phytium-2000plus-and-s2500-support-on-arm-archit.patch b/generic_vdpa/libvirt/add-phytium-2000plus-and-s2500-support-on-arm-archit.patch new file mode 100644 index 0000000..0501e10 --- /dev/null +++ b/generic_vdpa/libvirt/add-phytium-2000plus-and-s2500-support-on-arm-archit.patch @@ -0,0 +1,80 @@ +From 0ef9a886d3d8bd468800ee3d6aadac2231359501 Mon Sep 17 00:00:00 2001 +From: root +Date: Thu, 4 Feb 2021 17:35:46 +0800 +Subject: [PATCH] add phytium 2000plus and s2500 support on arm architecture + for capability + +--- + src/cpu_map/Makefile.inc.am | 2 ++ + src/cpu_map/arm_FT-2000plus.xml | 6 ++++++ + src/cpu_map/arm_Tengyun-S2500.xml | 6 ++++++ + src/cpu_map/arm_vendors.xml | 1 + + src/cpu_map/index.xml | 4 ++++ + 5 files changed, 19 insertions(+) + create mode 100644 src/cpu_map/arm_FT-2000plus.xml + create mode 100644 src/cpu_map/arm_Tengyun-S2500.xml + +diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am +index 8663877b97..ab5268d94f 100644 +--- a/src/cpu_map/Makefile.inc.am ++++ b/src/cpu_map/Makefile.inc.am +@@ -72,6 +72,8 @@ cpumap_DATA = \ + cpu_map/arm_cortex-a57.xml \ + cpu_map/arm_cortex-a72.xml \ + cpu_map/arm_Kunpeng-920.xml \ ++ cpu_map/arm_FT-2000plus.xml \ ++ cpu_map/arm_Tengyun-S2500.xml \ + $(NULL) + + EXTRA_DIST += $(cpumap_DATA) +diff --git a/src/cpu_map/arm_FT-2000plus.xml b/src/cpu_map/arm_FT-2000plus.xml +new file mode 100644 +index 0000000000..b532f65f68 +--- /dev/null ++++ b/src/cpu_map/arm_FT-2000plus.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/arm_Tengyun-S2500.xml b/src/cpu_map/arm_Tengyun-S2500.xml +new file mode 100644 +index 0000000000..22b865e368 +--- /dev/null ++++ b/src/cpu_map/arm_Tengyun-S2500.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/arm_vendors.xml b/src/cpu_map/arm_vendors.xml +index 840bf9a2f8..05175495a0 100644 +--- a/src/cpu_map/arm_vendors.xml ++++ b/src/cpu_map/arm_vendors.xml +@@ -11,4 +11,5 @@ + + + ++ + +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 985af86ba2..672d0a3c92 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -95,5 +95,9 @@ + + + ++ ++ ++ ++ + + +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/admin-fix-leak-of-typed-parameters-on-error.patch b/generic_vdpa/libvirt/admin-fix-leak-of-typed-parameters-on-error.patch new file mode 100644 index 0000000..66b0adf --- /dev/null +++ b/generic_vdpa/libvirt/admin-fix-leak-of-typed-parameters-on-error.patch @@ -0,0 +1,62 @@ +From 90b8168fd93490f3a0fadadb38030163712a0e85 Mon Sep 17 00:00:00 2001 +From: wangmeiyang +Date: Fri, 21 Apr 2023 14:43:45 +0800 +Subject: [PATCH] admin: fix leak of typed parameters on error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A few admin client methods had the xdr_free call the wrong +side of the cleanup label, so typed parameters would not +be freed on error. + +origin commit: https://gitlab.com/libvirt/libvirt/-/commit/0edf44664e9f2f75c7ba5faab91e2e190b5626af +Reviewed-by: Martin Kletzander +Signed-off-by: Daniel P. Berrangé +Signed-off-by: Meiyang Wang +--- + src/admin/admin_remote.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c +index ca5e0c9fe4..2499fb8b0f 100644 +--- a/src/admin/admin_remote.c ++++ b/src/admin/admin_remote.c +@@ -271,9 +271,9 @@ remoteAdminServerGetThreadPoolParameters(virAdmServerPtr srv, + goto cleanup; + + rv = 0; +- xdr_free((xdrproc_t)xdr_admin_server_get_threadpool_parameters_ret, (char *) &ret); + + cleanup: ++ xdr_free((xdrproc_t)xdr_admin_server_get_threadpool_parameters_ret, (char *) &ret); + virObjectUnlock(priv); + return rv; + } +@@ -344,9 +344,9 @@ remoteAdminClientGetInfo(virAdmClientPtr client, + goto cleanup; + + rv = 0; +- xdr_free((xdrproc_t)xdr_admin_client_get_info_ret, (char *) &ret); + + cleanup: ++ xdr_free((xdrproc_t)xdr_admin_client_get_info_ret, (char *) &ret); + virObjectUnlock(priv); + return rv; + } +@@ -382,10 +382,10 @@ remoteAdminServerGetClientLimits(virAdmServerPtr srv, + goto cleanup; + + rv = 0; +- xdr_free((xdrproc_t) xdr_admin_server_get_client_limits_ret, +- (char *) &ret); + + cleanup: ++ xdr_free((xdrproc_t) xdr_admin_server_get_client_limits_ret, ++ (char *) &ret); + virObjectUnlock(priv); + return rv; + } +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/apibuild-Fix-self.waring-method-call.patch b/generic_vdpa/libvirt/apibuild-Fix-self.waring-method-call.patch new file mode 100644 index 0000000..97ccecc --- /dev/null +++ b/generic_vdpa/libvirt/apibuild-Fix-self.waring-method-call.patch @@ -0,0 +1,31 @@ +From 58d0830491d3be2fedec55f42f6f832d32783a73 Mon Sep 17 00:00:00 2001 +From: luzhipeng +Date: Sat, 7 May 2022 09:17:31 +0800 +Subject: [PATCH] apibuild: Fix self.waring method call + +The parameters of self.warning is inconsistent with its definition, So +fix it. + +Signed-off-by: dinglimin +Signed-off-by: luzhipeng +Reviewed-by: Martin Kletzander +--- + scripts/apibuild.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/apibuild.py b/scripts/apibuild.py +index 05a169c30d..c98bcf6091 100755 +--- a/scripts/apibuild.py ++++ b/scripts/apibuild.py +@@ -315,7 +315,7 @@ class index: + if type in type_map: + type_map[type][name] = d + else: +- self.warning("Unable to register type ", type) ++ self.warning("Unable to register type %s" % type) + + if name == debugsym and not quiet: + print("New symbol: %s" % (d)) +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/apparmor-Permit-new-capabilities-required-by-libvirt.patch b/generic_vdpa/libvirt/apparmor-Permit-new-capabilities-required-by-libvirt.patch new file mode 100644 index 0000000..9efd2e6 --- /dev/null +++ b/generic_vdpa/libvirt/apparmor-Permit-new-capabilities-required-by-libvirt.patch @@ -0,0 +1,38 @@ +From 9abebfb36b2380829be4a901d7c9785a7a8f5f6a Mon Sep 17 00:00:00 2001 +From: Jim Fehlig +Date: Mon, 7 Jun 2021 16:21:28 -0600 +Subject: [PATCH] apparmor: Permit new capabilities required by libvirtd + +The audit log contains the following denials from libvirtd + +apparmor="DENIED" operation="capable" profile="libvirtd" pid=6012 comm="daemon-init" capability=17 capname="sys_rawio" +apparmor="DENIED" operation="capable" profile="libvirtd" pid=6012 comm="rpc-worker" capability=39 capname="bpf" +apparmor="DENIED" operation="capable" profile="libvirtd" pid=6012 comm="rpc-worker" capability=38 capname="perfmon" + +Squelch the denials and allow the capabilities in the libvirtd +apparmor profile. + +Signed-off-by: Jim Fehlig +Reviewed-by: Neal Gompa +Reviewed-by: Michal Privoznik +--- + src/security/apparmor/usr.sbin.libvirtd.in | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/security/apparmor/usr.sbin.libvirtd.in b/src/security/apparmor/usr.sbin.libvirtd.in +index 1e137039e9..49266743f5 100644 +--- a/src/security/apparmor/usr.sbin.libvirtd.in ++++ b/src/security/apparmor/usr.sbin.libvirtd.in +@@ -25,6 +25,9 @@ profile libvirtd @sbindir@/libvirtd flags=(attach_disconnected) { + capability fsetid, + capability audit_write, + capability ipc_lock, ++ capability sys_rawio, ++ capability bpf, ++ capability perfmon, + + # Needed for vfio + capability sys_resource, +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/backport-meson-drop-debug_logs-configure-argument.patch b/generic_vdpa/libvirt/backport-meson-drop-debug_logs-configure-argument.patch new file mode 100644 index 0000000..fac1c12 --- /dev/null +++ b/generic_vdpa/libvirt/backport-meson-drop-debug_logs-configure-argument.patch @@ -0,0 +1,155 @@ +From 2b3bbbc1b7f8723c4947c6d1e4fb43cabc25fb2e Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Fri, 24 Jul 2020 16:30:06 +0200 +Subject: [PATCH 2/4] meson: drop debug_logs configure argument + +There is no point of having this option in libvirt because the debug +logs can be configured using log filters. + +origin commit: https://gitlab.com/libvirt/libvirt/-/commit/da6d644ea7b49500680a3d4a403571234fecefad +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +Reviewed-by: Neal Gompa +Signed-off-by: Chenxi Mao +--- + configure.ac | 3 --- + m4/virt-debug.m4 | 33 --------------------------------- + src/util/virlog.h | 23 +---------------------- + tools/virsh.c | 2 -- + tools/virt-admin.c | 2 -- + 5 files changed, 1 insertion(+), 62 deletions(-) + delete mode 100644 m4/virt-debug.m4 + +diff --git a/configure.ac b/configure.ac +index cb62e5aac8..93d13496f3 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -496,7 +496,6 @@ dnl + dnl Miscellaneous checks + dnl + +-LIBVIRT_ARG_DEBUG + LIBVIRT_ARG_DTRACE + LIBVIRT_ARG_NUMAD + LIBVIRT_ARG_INIT_SCRIPT +@@ -509,7 +508,6 @@ LIBVIRT_ARG_TLS_PRIORITY + LIBVIRT_ARG_SYSCTL_CONFIG + + +-LIBVIRT_CHECK_DEBUG + LIBVIRT_CHECK_DTRACE + LIBVIRT_CHECK_NUMAD + LIBVIRT_CHECK_INIT_SCRIPT +@@ -1038,7 +1036,6 @@ LIBVIRT_RESULT([Coverage], [$enable_test_coverage]) + AC_MSG_NOTICE([]) + AC_MSG_NOTICE([Miscellaneous]) + AC_MSG_NOTICE([]) +-LIBVIRT_RESULT_DEBUG + LIBVIRT_RESULT([Use -Werror], [$enable_werror]) + LIBVIRT_RESULT([Warning Flags], [$WARN_CFLAGS]) + LIBVIRT_RESULT_DTRACE +diff --git a/m4/virt-debug.m4 b/m4/virt-debug.m4 +deleted file mode 100644 +index d3ac0564f2..0000000000 +--- a/m4/virt-debug.m4 ++++ /dev/null +@@ -1,33 +0,0 @@ +-dnl The debug check +-dnl +-dnl Copyright (C) 2016 Red Hat, Inc. +-dnl +-dnl This library is free software; you can redistribute it and/or +-dnl modify it under the terms of the GNU Lesser General Public +-dnl License as published by the Free Software Foundation; either +-dnl version 2.1 of the License, or (at your option) any later version. +-dnl +-dnl This library is distributed in the hope that it will be useful, +-dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-dnl Lesser General Public License for more details. +-dnl +-dnl You should have received a copy of the GNU Lesser General Public +-dnl License along with this library. If not, see +-dnl . +-dnl +- +-AC_DEFUN([LIBVIRT_ARG_DEBUG], [ +- LIBVIRT_ARG_ENABLE([DEBUG], [enable debugging output], [yes]) +-]) +- +-AC_DEFUN([LIBVIRT_CHECK_DEBUG], [ +- AM_CONDITIONAL([ENABLE_DEBUG], test x"$enable_debug" = x"yes") +- if test x"$enable_debug" = x"yes"; then +- AC_DEFINE([ENABLE_DEBUG], [], [whether debugging is enabled]) +- fi +-]) +- +-AC_DEFUN([LIBVIRT_RESULT_DEBUG], [ +- LIBVIRT_RESULT([Debug], [$enable_debug]) +-]) +diff --git a/src/util/virlog.h b/src/util/virlog.h +index feb2f85904..716fb9a378 100644 +--- a/src/util/virlog.h ++++ b/src/util/virlog.h +@@ -78,29 +78,8 @@ struct _virLogSource { + .serial = 0, \ + } + +-/* +- * If configured with --enable-debug=yes then library calls +- * are printed to stderr for debugging or to an appropriate channel +- * defined at runtime from the libvirt daemon configuration file +- */ +-#ifdef ENABLE_DEBUG +-# define VIR_DEBUG_INT(src, filename, linenr, funcname, ...) \ ++#define VIR_DEBUG_INT(src, filename, linenr, funcname, ...) \ + virLogMessage(src, VIR_LOG_DEBUG, filename, linenr, funcname, NULL, __VA_ARGS__) +-#else +-/** +- * virLogEatParams: +- * +- * Do nothing but eat parameters. +- */ +-static inline void virLogEatParams(virLogSourcePtr unused, ...) +-{ +- /* Silence gcc */ +- unused = unused; +-} +-# define VIR_DEBUG_INT(src, filename, linenr, funcname, ...) \ +- virLogEatParams(src, filename, linenr, funcname, __VA_ARGS__) +-#endif /* !ENABLE_DEBUG */ +- + #define VIR_INFO_INT(src, filename, linenr, funcname, ...) \ + virLogMessage(src, VIR_LOG_INFO, filename, linenr, funcname, NULL, __VA_ARGS__) + #define VIR_WARN_INT(src, filename, linenr, funcname, ...) \ +diff --git a/tools/virsh.c b/tools/virsh.c +index 197a90636d..06ff5e8336 100644 +--- a/tools/virsh.c ++++ b/tools/virsh.c +@@ -614,9 +614,7 @@ virshShowVersion(vshControl *ctl G_GNUC_UNUSED) + #ifdef WITH_SECRETS + vshPrint(ctl, " Secrets"); + #endif +-#ifdef ENABLE_DEBUG + vshPrint(ctl, " Debug"); +-#endif + #ifdef WITH_DTRACE_PROBES + vshPrint(ctl, " DTrace"); + #endif +diff --git a/tools/virt-admin.c b/tools/virt-admin.c +index a8e5e0a5af..df23330ee1 100644 +--- a/tools/virt-admin.c ++++ b/tools/virt-admin.c +@@ -1277,9 +1277,7 @@ vshAdmShowVersion(vshControl *ctl G_GNUC_UNUSED) + #ifdef WITH_LIBVIRTD + vshPrint(ctl, " Daemon"); + #endif +-#ifdef ENABLE_DEBUG + vshPrint(ctl, " Debug"); +-#endif + #if WITH_READLINE + vshPrint(ctl, " Readline"); + #endif +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/backport-virhostcpu-Fix-build-with-clang-and-newest-kernel-he.patch b/generic_vdpa/libvirt/backport-virhostcpu-Fix-build-with-clang-and-newest-kernel-he.patch new file mode 100644 index 0000000..42211ca --- /dev/null +++ b/generic_vdpa/libvirt/backport-virhostcpu-Fix-build-with-clang-and-newest-kernel-he.patch @@ -0,0 +1,67 @@ +From f6c9bb6adbee8f74172707845dcdf221e79e35d4 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Tue, 23 Aug 2022 15:29:43 +0200 +Subject: [PATCH 1/4] virhostcpu: Fix build with clang and newest kernel + headers + +The most recent environment e.g. present in our Fedora Rawhide builds +fail to build the tree with clang with the following error: + +../src/util/virhostcpu.c:1291:25: error: field 'header' with variable sized type 'struct kvm_msrs' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end] + struct kvm_msrs header; + ^ + +The problem seems to be that clang doesn't like the new way the +'entries' field in struct kvm_msrs is declared. + +To work around the issue we can simply allocate the variable dynamically +and use the 'entries' member as it was intended to to access the +members. + +origin commit: https://gitlab.com/libvirt/libvirt/-/commit/56b3ee743916c8951a32a1650616621d78afe8c7 +Signed-off-by: Peter Krempa +Reviewed-by: Jiri Denemark +Signed-off-by: Chenxi Mao +--- + src/util/virhostcpu.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index ce3da7e6ec..8c8fc3a476 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -1275,25 +1275,22 @@ virHostCPUGetMSRFromKVM(unsigned long index, + uint64_t *result) + { + VIR_AUTOCLOSE fd = -1; +- struct { +- struct kvm_msrs header; +- struct kvm_msr_entry entry; +- } msr = { +- .header = { .nmsrs = 1 }, +- .entry = { .index = index }, +- }; ++ g_autofree struct kvm_msrs *msr = g_malloc0(sizeof(struct kvm_msrs) + ++ sizeof(struct kvm_msr_entry)); ++ msr->nmsrs = 1; ++ msr->entries[0].index = index; + + if ((fd = open(KVM_DEVICE, O_RDONLY)) < 0) { + virReportSystemError(errno, _("Unable to open %s"), KVM_DEVICE); + return -1; + } + +- if (ioctl(fd, KVM_GET_MSRS, &msr) < 0) { ++ if (ioctl(fd, KVM_GET_MSRS, msr) < 0) { + VIR_DEBUG("Cannot get MSR 0x%lx from KVM", index); + return 1; + } + +- *result = msr.entry.data; ++ *result = msr->entries[0].data; + return 0; + } + +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/backport-vshCommandStringGetArg-Drop-sz.patch b/generic_vdpa/libvirt/backport-vshCommandStringGetArg-Drop-sz.patch new file mode 100644 index 0000000..0f19fcb --- /dev/null +++ b/generic_vdpa/libvirt/backport-vshCommandStringGetArg-Drop-sz.patch @@ -0,0 +1,42 @@ +From 6d3c4b49c08d5fcf42f324af0d04551619e4109f Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 7 Jan 2021 17:59:55 +0100 +Subject: [PATCH 3/4] vshCommandStringGetArg: Drop @sz +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This variable is unused since introduction of the function in +v0.8.5~150. + +origin commit: https://gitlab.com/libvirt/libvirt/-/commit/9b9542586cc047075469053606d1e12cb017b5ca +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +Signed-off-by: Chenxi Mao +--- + tools/vsh.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/tools/vsh.c b/tools/vsh.c +index 3646f37cea..f5fa7b6f6f 100644 +--- a/tools/vsh.c ++++ b/tools/vsh.c +@@ -1641,7 +1641,6 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res, + { + bool single_quote = false; + bool double_quote = false; +- int sz = 0; + char *p = parser->pos; + char *q = g_strdup(p); + +@@ -1695,7 +1694,6 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandParser *parser, char **res, + } + + *q++ = *p++; +- sz++; + } + if (double_quote) { + if (report) +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/bash-completion-fix-variable-leaks-of-word.patch b/generic_vdpa/libvirt/bash-completion-fix-variable-leaks-of-word.patch new file mode 100644 index 0000000..07ec5d3 --- /dev/null +++ b/generic_vdpa/libvirt/bash-completion-fix-variable-leaks-of-word.patch @@ -0,0 +1,31 @@ +From 4bdf8aeb2e907b53cc71c07b3c6be8f82e3f1e4a Mon Sep 17 00:00:00 2001 +From: Xu Zheng +Date: Thu, 24 Nov 2022 17:58:28 +0800 +Subject: [PATCH 20/23] bash-completion: fix variable leaks of "word" + +cherry-pick from 097296c30b72f472bcf4e72cf8ab2aeb55903c49 + +Signed-off-by: Koichi Murase +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +Signed-off-by: Xu Zheng +--- + tools/bash-completion/vsh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/bash-completion/vsh b/tools/bash-completion/vsh +index 8493cad28b..363097c601 100644 +--- a/tools/bash-completion/vsh ++++ b/tools/bash-completion/vsh +@@ -21,7 +21,7 @@ _vsh_complete() + # See what URI is user trying to connect to and if they are + # connecting RO. Honour that. + while [ $c -le $COMP_CWORD ]; do +- word="${COMP_WORDS[c]}" ++ local word="${COMP_WORDS[c]}" + case "$word" in + -r|--readonly) RO=1 ;; + -c|--connect) c=$((++c)); URI=${COMP_WORDS[c]} ;; +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/bugfix-fix-warnings-found-by-clang.patch b/generic_vdpa/libvirt/bugfix-fix-warnings-found-by-clang.patch new file mode 100644 index 0000000..378bc20 --- /dev/null +++ b/generic_vdpa/libvirt/bugfix-fix-warnings-found-by-clang.patch @@ -0,0 +1,30 @@ +From 0559dfd4d4fa74484dae487711a986cc9acdfbfc Mon Sep 17 00:00:00 2001 +From: Chenxi Mao +Date: Tue, 4 Apr 2023 14:25:17 +0800 +Subject: [PATCH 4/4] Fix warnings found by clang + +Warnings found if build with clang 15: + +[ 257s] ../../src/qemu/qemu_hotpatch.c:217:22: error: unused variable 'libvirtd_conf' [-Werror,-Wunused-variable] +[ 257s] g_autofree char *libvirtd_conf = NULL; + +Signed-off-by: Chenxi Mao +--- + src/qemu/qemu_hotpatch.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c +index 02f511cc38..64aac9bb4c 100644 +--- a/src/qemu/qemu_hotpatch.c ++++ b/src/qemu/qemu_hotpatch.c +@@ -214,7 +214,6 @@ qemuDomainHotpatchAutoload(virDomainObjPtr vm, char *hotpatch_path) + VIR_AUTOSTRINGLIST applied_patches = NULL; + VIR_AUTOSTRINGLIST lines = NULL; + g_autofree char *applied_patch = NULL; +- g_autofree char *libvirtd_conf = NULL; + g_autofree char *patch_conf = NULL; + g_autofree char *buf = NULL; + char *ret = NULL; +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/bugfix-move-the-check-function-qemuDomainDiskBlockIo.patch b/generic_vdpa/libvirt/bugfix-move-the-check-function-qemuDomainDiskBlockIo.patch new file mode 100644 index 0000000..d5a1166 --- /dev/null +++ b/generic_vdpa/libvirt/bugfix-move-the-check-function-qemuDomainDiskBlockIo.patch @@ -0,0 +1,43 @@ +From 35de7404370eb24089b6160d109f6fe559a91864 Mon Sep 17 00:00:00 2001 +From: mayunlong +Date: Fri, 24 Mar 2023 11:31:49 +0800 +Subject: [PATCH] bugfix: move the check function + qemuDomainDiskBlockIoTuneIsSupported to currect place. + +move the check function qemuDomainDiskBlockIoTuneIsSupported for +conf_disk to currect place in function: qemuDomainSetBlockIotTune. + +fix commit: e07709c7275349eac376660c08bacc6d18f28ff8 +origin commit: https://libvirt.org/git/?p=libvirt.git;a=commitdiff;h=d763466edc6e8d4965fb42092c6e8f4296acf6c6 +Signed-off-by:mayunlong +--- + src/qemu/qemu_driver.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 32b3ef3cf1..c7545a7a98 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -19301,9 +19301,6 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, + goto endjob; + } + +- if (!qemuDomainDiskBlockIoTuneIsSupported(conf_disk->src)) +- goto endjob; +- + cur_info = qemuDomainFindGroupBlockIoTune(def, disk, &info); + + if (qemuDomainSetBlockIoTuneDefaults(&info, cur_info, +@@ -19386,6 +19383,9 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, + goto endjob; + } + ++ if (!qemuDomainDiskBlockIoTuneIsSupported(conf_disk->src)) ++ goto endjob; ++ + conf_cur_info = qemuDomainFindGroupBlockIoTune(persistentDef, conf_disk, &info); + + if (qemuDomainSetBlockIoTuneDefaults(&conf_info, conf_cur_info, +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/check-for-NULL-before-calling-g_regex_unref.patch b/generic_vdpa/libvirt/check-for-NULL-before-calling-g_regex_unref.patch new file mode 100644 index 0000000..bbb2212 --- /dev/null +++ b/generic_vdpa/libvirt/check-for-NULL-before-calling-g_regex_unref.patch @@ -0,0 +1,70 @@ +From 61de276ed3cd5692b99ebc6d5b700a21b16ab5e8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=C3=A1n=20Tomko?= +Date: Tue, 8 Sep 2020 14:57:14 +0200 +Subject: [PATCH 014/108] check for NULL before calling g_regex_unref +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +g_regex_unref reports an error if called with a NULL argument. + +We have two cases in the code where we (possibly) call it on a NULL +argument. The interesting one is in virDomainQemuMonitorEventCleanup. + +Based on VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX, we unref +data->regex, which has two problems: + +* On the client side, flags is -1 so the comparison is true even if no + regex was used, reproducible by: + $ virsh qemu-monitor-event --timeout 1 + which results in an ugly error: +(process:1289846): GLib-CRITICAL **: 14:58:42.631: g_regex_unref: assertion 'regex != NULL' failed +* On the server side, we only create the regex if both the flag and the + string are present, so it's possible to trigger this message by: + $ virsh qemu-monitor-event --regex --timeout 1 + +Use a non-NULL comparison instead of the flag to decide whether we need +to unref the regex. And add a non-NULL check to the unref in the +VirtualBox test too. + +Signed-off-by: Ján Tomko +Fixes: 71efb59a4de7c51b1bc889a316f1796ebf55738f +https://bugzilla.redhat.com/show_bug.cgi?id=1876907 +Reviewed-by: Peter Krempa +Reviewed-by: Martin Kletzander +(cherry picked from commit 92b252456ee6d6ffc6e39e62ce1ce6c50113e00e) +--- + src/conf/domain_event.c | 2 +- + tests/vboxsnapshotxmltest.c | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c +index 33fbf10406..d3acde0236 100644 +--- a/src/conf/domain_event.c ++++ b/src/conf/domain_event.c +@@ -2194,7 +2194,7 @@ virDomainQemuMonitorEventCleanup(void *opaque) + virDomainQemuMonitorEventData *data = opaque; + + VIR_FREE(data->event); +- if (data->flags & VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX) ++ if (data->regex) + g_regex_unref(data->regex); + if (data->freecb) + (data->freecb)(data->opaque); +diff --git a/tests/vboxsnapshotxmltest.c b/tests/vboxsnapshotxmltest.c +index 2ea460d8bd..853d930865 100644 +--- a/tests/vboxsnapshotxmltest.c ++++ b/tests/vboxsnapshotxmltest.c +@@ -136,7 +136,8 @@ mymain(void) + DO_TEST("2disks-3snap-brother"); + + cleanup: +- g_regex_unref(testSnapshotXMLVariableLineRegex); ++ if (testSnapshotXMLVariableLineRegex) ++ g_regex_unref(testSnapshotXMLVariableLineRegex); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } + +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/checkpoint-Fix-a-typo-of-comments.patch b/generic_vdpa/libvirt/checkpoint-Fix-a-typo-of-comments.patch new file mode 100644 index 0000000..31e7b36 --- /dev/null +++ b/generic_vdpa/libvirt/checkpoint-Fix-a-typo-of-comments.patch @@ -0,0 +1,34 @@ +From 5d84740e04d99a8503f20b2281f3fd70fa1f69ab Mon Sep 17 00:00:00 2001 +From: jipengfei +Date: Thu, 24 Nov 2022 16:43:51 +0800 +Subject: [PATCH 16/23] checkpoint: Fix a typo of comments +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry-pick from 75134a3a7d1ca6976dfc2af7cd53461cb0aee529 + +Signed-off-by: Han Han +Signed-off-by: jipengfei +Reviewed-by: Ján Tomko +Signed-off-by: Ján Tomko +--- + src/libvirt-domain-checkpoint.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libvirt-domain-checkpoint.c b/src/libvirt-domain-checkpoint.c +index 432c2d5a52..58668c391c 100644 +--- a/src/libvirt-domain-checkpoint.c ++++ b/src/libvirt-domain-checkpoint.c +@@ -236,7 +236,7 @@ virDomainCheckpointGetXMLDesc(virDomainCheckpointPtr checkpoint, + * @checkpoints: pointer to variable to store the array containing checkpoint + * object, or NULL if the list is not required (just returns + * number of checkpoints) +- * @flags: bitwise-OR of supported virDomainCheckpoinListFlags ++ * @flags: bitwise-OR of supported virDomainCheckpointListFlags + * + * Collect the list of domain checkpoints for the given domain and allocate + * an array to store those objects. +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/client-fix-memory-leak-in-client-msg.patch b/generic_vdpa/libvirt/client-fix-memory-leak-in-client-msg.patch new file mode 100644 index 0000000..cda5438 --- /dev/null +++ b/generic_vdpa/libvirt/client-fix-memory-leak-in-client-msg.patch @@ -0,0 +1,47 @@ +From ea9860d9f89252f0890dae01c6b92af2a82227f4 Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Tue, 29 Nov 2022 08:19:29 +0000 +Subject: [PATCH 02/24] client: fix memory leak in client msg When closing + client->waitDispatch in virNetClientIOEventLoopRemoveAll or + virNetClientIOEventLoopRemoveDone, VIR_FREE() is called to free call->msg + directly, resulting in leak of the memory call->msg->buffer points to. Use + virNetMessageFree(call->msg) instead of VIR_FREE(call->msg). +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Hao Wang +Reviewed-by: Ján Tomko +Signed-off-by: Ján Tomko + +Signed-off-by: tangbin +(cherry-pick from 0011ec3191a5bffff14fc2c53fbdf457a805cfb1) +--- + src/rpc/virnetclient.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c +index 1c5bef86a1..70ace5d0e8 100644 +--- a/src/rpc/virnetclient.c ++++ b/src/rpc/virnetclient.c +@@ -1519,7 +1519,7 @@ static bool virNetClientIOEventLoopRemoveDone(virNetClientCallPtr call, + if (call->expectReply) + VIR_WARN("Got a call expecting a reply but without a waiting thread"); + virCondDestroy(&call->cond); +- VIR_FREE(call->msg); ++ virNetMessageFree(call->msg); + VIR_FREE(call); + } + +@@ -1546,7 +1546,7 @@ virNetClientIOEventLoopRemoveAll(virNetClientCallPtr call, + + VIR_DEBUG("Removing call %p", call); + virCondDestroy(&call->cond); +- VIR_FREE(call->msg); ++ virNetMessageFree(call->msg); + VIR_FREE(call); + return true; + } +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/cmdCheckpointList-Fix-memory-leak.patch b/generic_vdpa/libvirt/cmdCheckpointList-Fix-memory-leak.patch new file mode 100644 index 0000000..89bae26 --- /dev/null +++ b/generic_vdpa/libvirt/cmdCheckpointList-Fix-memory-leak.patch @@ -0,0 +1,36 @@ +From dd54dd905f334ee31ebd9d667dc0fd2db9ddeaf0 Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Mon, 19 Apr 2021 13:54:13 +0200 +Subject: [PATCH 061/108] cmdCheckpointList: Fix memory leak + +Fixes: 3caa28dc50df7ec215713075d669b20bef6473a2 +Signed-off-by: Tim Wiederhake +Reviewed-by: Laine Stump +(cherry picked from commit 8b8c91f487592c6c067847ca59dde405ca17573f) +--- + tools/virsh-checkpoint.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virsh-checkpoint.c b/tools/virsh-checkpoint.c +index e82a67f075..1a3a74b2d5 100644 +--- a/tools/virsh-checkpoint.c ++++ b/tools/virsh-checkpoint.c +@@ -720,7 +720,6 @@ cmdCheckpointList(vshControl *ctl, + virDomainCheckpointPtr checkpoint = NULL; + long long creation_longlong; + g_autoptr(GDateTime) then = NULL; +- g_autofree gchar *thenstr = NULL; + bool tree = vshCommandOptBool(cmd, "tree"); + bool name = vshCommandOptBool(cmd, "name"); + bool from = vshCommandOptBool(cmd, "from"); +@@ -803,6 +802,7 @@ cmdCheckpointList(vshControl *ctl, + } + + for (i = 0; i < checkpointlist->nchks; i++) { ++ g_autofree gchar *thenstr = NULL; + const char *chk_name; + + /* free up memory from previous iterations of the loop */ +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/cmdSnapshotList-Fix-memory-leak.patch b/generic_vdpa/libvirt/cmdSnapshotList-Fix-memory-leak.patch new file mode 100644 index 0000000..05e9f4e --- /dev/null +++ b/generic_vdpa/libvirt/cmdSnapshotList-Fix-memory-leak.patch @@ -0,0 +1,36 @@ +From 4732cb4a9306ea9b8487b66fa14316caa05428ed Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Mon, 19 Apr 2021 13:54:14 +0200 +Subject: [PATCH 062/108] cmdSnapshotList: Fix memory leak + +Fixes: 3caa28dc50df7ec215713075d669b20bef6473a2 +Signed-off-by: Tim Wiederhake +Reviewed-by: Laine Stump +(cherry picked from commit 89ce1ef86b0c8b0e039ae770221376497354f085) +--- + tools/virsh-snapshot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c +index d5e68e4b18..376290d468 100644 +--- a/tools/virsh-snapshot.c ++++ b/tools/virsh-snapshot.c +@@ -1493,7 +1493,6 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) + char *state = NULL; + long long creation_longlong; + g_autoptr(GDateTime) then = NULL; +- g_autofree gchar *thenstr = NULL; + bool tree = vshCommandOptBool(cmd, "tree"); + bool name = vshCommandOptBool(cmd, "name"); + bool from = vshCommandOptBool(cmd, "from"); +@@ -1588,6 +1587,7 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd) + } + + for (i = 0; i < snaplist->nsnaps; i++) { ++ g_autofree gchar *thenstr = NULL; + const char *snap_name; + + /* free up memory from previous iterations of the loop */ +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/conf-Use-unsigned-long-long-for-timer-frequency.patch b/generic_vdpa/libvirt/conf-Use-unsigned-long-long-for-timer-frequency.patch new file mode 100644 index 0000000..635ad7a --- /dev/null +++ b/generic_vdpa/libvirt/conf-Use-unsigned-long-long-for-timer-frequency.patch @@ -0,0 +1,81 @@ +From efd4f6469f9f5f6d3a34d250cd80faf59a8dc373 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Wed, 11 Nov 2020 16:50:16 +0100 +Subject: [PATCH 068/108] conf: Use unsigned long long for timer frequency + +Although the code in qemuProcessStartValidateTSC works as if the +timer frequency was already unsigned long long (by using an appropriate +temporary variable), the virDomainTimerDef structure actually defines +frequency as unsigned long, which is not guaranteed to be 64b. + +Fixes support for frequencies higher than 2^32 - 1 on 32b systems. + +Signed-off-by: Jiri Denemark +Reviewed-by: Martin Kletzander +(cherry picked from commit 3c7c7cd4d82c2f9a5a59bbd06673b8cd1eb23ce3) +--- + src/conf/domain_conf.c | 6 +++--- + src/conf/domain_conf.h | 2 +- + src/qemu/qemu_command.c | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index a33f9144f5..9c83f4e347 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -13951,7 +13951,7 @@ virDomainTimerDefParseXML(xmlNodePtr node, + } + } + +- ret = virXPathULong("string(./@frequency)", ctxt, &def->frequency); ++ ret = virXPathULongLong("string(./@frequency)", ctxt, &def->frequency); + if (ret == -1) { + def->frequency = 0; + } else if (ret < 0) { +@@ -22259,7 +22259,7 @@ virDomainTimerDefCheckABIStability(virDomainTimerDefPtr src, + if (src->name == VIR_DOMAIN_TIMER_NAME_TSC) { + if (src->frequency != dst->frequency) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +- _("Target TSC frequency %lu does not match source %lu"), ++ _("Target TSC frequency %llu does not match source %llu"), + dst->frequency, src->frequency); + return false; + } +@@ -27355,7 +27355,7 @@ virDomainTimerDefFormat(virBufferPtr buf, + + if (def->name == VIR_DOMAIN_TIMER_NAME_TSC) { + if (def->frequency > 0) +- virBufferAsprintf(buf, " frequency='%lu'", def->frequency); ++ virBufferAsprintf(buf, " frequency='%llu'", def->frequency); + + if (def->mode != -1) { + const char *mode +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 15b9e79d69..c0a323d465 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2078,7 +2078,7 @@ struct _virDomainTimerDef { + int track; /* host|guest */ + + /* frequency & mode are only valid for name='tsc' */ +- unsigned long frequency; /* in Hz, unspecified = 0 */ ++ unsigned long long frequency; /* in Hz, unspecified = 0 */ + int mode; /* auto|native|emulate|paravirt */ + }; + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 27b2eef8e5..42f6e10b33 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -6761,7 +6761,7 @@ qemuBuildCpuCommandLine(virCommandPtr cmd, + break; + case VIR_DOMAIN_TIMER_NAME_TSC: + if (timer->frequency > 0) +- virBufferAsprintf(&buf, ",tsc-frequency=%lu", timer->frequency); ++ virBufferAsprintf(&buf, ",tsc-frequency=%llu", timer->frequency); + break; + case VIR_DOMAIN_TIMER_NAME_ARMVTIMER: + switch (timer->tickpolicy) { +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/conf-domain_conf-pin-the-retry_interval-and-retry_ti.patch b/generic_vdpa/libvirt/conf-domain_conf-pin-the-retry_interval-and-retry_ti.patch new file mode 100644 index 0000000..14c09d7 --- /dev/null +++ b/generic_vdpa/libvirt/conf-domain_conf-pin-the-retry_interval-and-retry_ti.patch @@ -0,0 +1,31 @@ +From 5d762303253a8cf15204839e93cc3f6e562d3708 Mon Sep 17 00:00:00 2001 +From: Mao Zhongyi +Date: Sat, 18 Sep 2021 14:20:24 +0800 +Subject: [PATCH] conf/domain_conf: pin the retry_interval and retry_timeout + parameters to xml + +Signed-off-by: Mao Zhongyi +--- + src/conf/domain_conf.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index a4e9b3290c..4e3bcf479c 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -24977,6 +24977,12 @@ virDomainDiskDefFormatDriver(virBufferPtr buf, + virBufferAsprintf(&driverBuf, " rerror_policy='%s'", + virDomainDiskErrorPolicyTypeToString(disk->rerror_policy)); + ++ if (disk->retry_interval) ++ virBufferAsprintf(&driverBuf, " retry_interval='%ld'", disk->retry_interval); ++ ++ if (disk->retry_timeout) ++ virBufferAsprintf(&driverBuf, " retry_timeout='%ld'", disk->retry_timeout); ++ + if (disk->iomode) + virBufferAsprintf(&driverBuf, " io='%s'", + virDomainDiskIoTypeToString(disk->iomode)); +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/conf-implement-support-for-vhostuser-disk.patch b/generic_vdpa/libvirt/conf-implement-support-for-vhostuser-disk.patch new file mode 100644 index 0000000..a7c61fe --- /dev/null +++ b/generic_vdpa/libvirt/conf-implement-support-for-vhostuser-disk.patch @@ -0,0 +1,617 @@ +From 02565aca5158fb4d9870546ea29be85278649511 Mon Sep 17 00:00:00 2001 +From: Luo Yifan +Date: Wed, 30 Nov 2022 18:13:36 +0800 +Subject: [PATCH 15/24] conf: implement support for vhostuser disk +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +Reviewed-by: Peter Krempa +(cherry picked from commit f00fe96eb045eed2b6b40d5046449bec6d495875) +Signed-off-by: Luo Yifan +--- + src/conf/domain_conf.c | 254 ++++++++++++++++++ + src/libxl/xen_xl.c | 1 + + src/qemu/qemu_block.c | 6 + + src/qemu/qemu_command.c | 1 + + src/qemu/qemu_driver.c | 4 + + src/qemu/qemu_migration.c | 2 + + src/util/virstoragefile.c | 4 + + src/util/virstoragefile.h | 4 + + tests/qemuxml2argvdata/disk-vhostuser.xml | 30 +++ + .../disk-vhostuser.x86_64-latest.xml | 48 ++++ + tests/qemuxml2xmltest.c | 1 + + 11 files changed, 355 insertions(+) + create mode 100644 tests/qemuxml2argvdata/disk-vhostuser.xml + create mode 100644 tests/qemuxml2xmloutdata/disk-vhostuser.x86_64-latest.xml + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index b60b9d31a1..8b1ca76d39 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -1278,6 +1278,17 @@ static virClassPtr virDomainXMLOptionClass; + static void virDomainObjDispose(void *obj); + static void virDomainXMLOptionDispose(void *obj); + ++static int ++virDomainChrSourceDefFormat(virBufferPtr buf, ++ virDomainChrSourceDefPtr def, ++ unsigned int flags); ++ ++ ++static int ++virDomainChrSourceReconnectDefParseXML(virDomainChrSourceReconnectDefPtr def, ++ xmlNodePtr node, ++ xmlXPathContextPtr ctxt); ++ + static int virDomainObjOnceInit(void) + { + if (!VIR_CLASS_NEW(virDomainObj, virClassForObjectLockable())) +@@ -5200,6 +5211,12 @@ virDomainDiskDefPostParse(virDomainDiskDefPtr disk, + disk->src->nvme->managed = VIR_TRISTATE_BOOL_YES; + } + ++ /* vhost-user doesn't allow us to snapshot, disable snapshots by default */ ++ if (disk->src->type == VIR_STORAGE_TYPE_VHOST_USER && ++ disk->snapshot == VIR_DOMAIN_SNAPSHOT_LOCATION_DEFAULT) { ++ disk->snapshot = VIR_DOMAIN_SNAPSHOT_LOCATION_NONE; ++ } ++ + if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + virDomainDiskDefAssignAddress(xmlopt, disk, def) < 0) { + return -1; +@@ -5995,6 +6012,174 @@ virDomainDiskAddressDiskBusCompatibility(virDomainDiskBus bus, + return true; + } + ++static int ++virDomainDiskVhostUserValidate(const virDomainDiskDef *disk) ++{ ++ if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("vhostuser disk supports only virtio bus")); ++ return -1; ++ } ++ ++ if (disk->snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_NONE) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("only snapshot=no is supported with vhostuser disk")); ++ return -1; ++ } ++ ++ /* Unsupported driver attributes */ ++ ++ if (disk->cachemode != VIR_DOMAIN_DISK_CACHE_DEFAULT) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("cache is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->error_policy || disk->rerror_policy) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("error_policy is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->iomode) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("io is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->ioeventfd != VIR_TRISTATE_SWITCH_ABSENT) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("ioeventfd is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->copy_on_read) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("copy_on_read is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->discard) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("discard is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->iothread) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("iothread is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->detect_zeroes) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("detect_zeroes is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ /* Unsupported driver elements */ ++ ++ if (disk->virtio) { ++ if (disk->virtio->iommu != VIR_TRISTATE_SWITCH_ABSENT) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("iommu is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->virtio->ats != VIR_TRISTATE_SWITCH_ABSENT) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("ats is not supported with vhostuser disk")); ++ return -1; ++ } ++ } ++ ++ /* Unsupported disk elements */ ++ ++ if (disk->blkdeviotune.group_name || ++ virDomainBlockIoTuneInfoHasAny(&disk->blkdeviotune)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("iotune is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->src->backingStore) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("backingStore is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->src->encryption) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("encryption is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->src->readonly) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("readonly is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->src->shared) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("shareable is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->transient) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("transient is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->serial) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("serial is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->wwn) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("wwn is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->vendor) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("vendor is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->product) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("product is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->src->auth) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("auth is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->geometry.cylinders > 0 || ++ disk->geometry.heads > 0 || ++ disk->geometry.sectors > 0 || ++ disk->geometry.trans != VIR_DOMAIN_DISK_TRANS_DEFAULT) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("geometry is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ if (disk->blockio.logical_block_size > 0 || ++ disk->blockio.physical_block_size > 0) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("blockio is not supported with vhostuser disk")); ++ return -1; ++ } ++ ++ return 0; ++} + + static int + virSecurityDeviceLabelDefValidateXML(virSecurityDeviceLabelDefPtr *seclabels, +@@ -6095,6 +6280,11 @@ virDomainDiskDefValidate(const virDomainDef *def, + } + } + ++ if (disk->src->type == VIR_STORAGE_TYPE_VHOST_USER && ++ virDomainDiskVhostUserValidate(disk) < 0) { ++ return -1; ++ } ++ + for (next = disk->src; next; next = next->backingStore) { + if (virSecurityDeviceLabelDefValidateXML(next->seclabels, + next->nseclabels, +@@ -9530,6 +9720,47 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node, + return 0; + } + ++static int ++virDomainDiskSourceVHostUserParse(xmlNodePtr node, ++ virStorageSourcePtr src, ++ virDomainXMLOptionPtr xmlopt, ++ xmlXPathContextPtr ctxt) ++{ ++ g_autofree char *type = virXMLPropString(node, "type"); ++ g_autofree char *path = virXMLPropString(node, "path"); ++ ++ if (!type) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("missing 'type' attribute for vhostuser disk source")); ++ return -1; ++ } ++ ++ if (STRNEQ(type, "unix")) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("invalid 'type' attribute for vhostuser disk source")); ++ return -1; ++ } ++ ++ if (!path) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("missing 'path' attribute for vhostuser disk source")); ++ return -1; ++ } ++ ++ if (!(src->vhostuser = virDomainChrSourceDefNew(xmlopt))) ++ return -1; ++ ++ src->vhostuser->type = virDomainChrTypeFromString(type); ++ src->vhostuser->data.nix.path = g_steal_pointer(&path); ++ ++ if (virDomainChrSourceReconnectDefParseXML(&src->vhostuser->data.nix.reconnect, ++ node, ++ ctxt) < 0) { ++ return -1; ++ } ++ ++ return 0; ++} + + static int + virDomainDiskSourceNVMeParse(xmlNodePtr node, +@@ -9746,6 +9977,10 @@ virDomainStorageSourceParse(xmlNodePtr node, + if (virDomainDiskSourceNVMeParse(node, ctxt, src) < 0) + return -1; + break; ++ case VIR_STORAGE_TYPE_VHOST_USER: ++ if (virDomainDiskSourceVHostUserParse(node, src, xmlopt, ctxt) < 0) ++ return -1; ++ break; + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -24682,6 +24917,21 @@ virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf, + virPCIDeviceAddressFormat(childBuf, nvme->pciAddr, false); + } + ++static void ++virDomainChrSourceReconnectDefFormat(virBufferPtr buf, ++ virDomainChrSourceReconnectDefPtr def); ++ ++ ++static void ++virDomainDiskSourceVhostuserFormat(virBufferPtr attrBuf, ++ virBufferPtr childBuf, ++ virDomainChrSourceDefPtr vhostuser) ++{ ++ virBufferAddLit(attrBuf, " type='unix'"); ++ virBufferAsprintf(attrBuf, " path='%s'", vhostuser->data.nix.path); ++ ++ virDomainChrSourceReconnectDefFormat(childBuf, &vhostuser->data.nix.reconnect); ++} + + static int + virDomainDiskSourceFormatPrivateData(virBufferPtr buf, +@@ -24796,6 +25046,10 @@ virDomainDiskSourceFormat(virBufferPtr buf, + virDomainDiskSourceNVMeFormat(&attrBuf, &childBuf, src->nvme); + break; + ++ case VIR_STORAGE_TYPE_VHOST_USER: ++ virDomainDiskSourceVhostuserFormat(&attrBuf, &childBuf, src->vhostuser); ++ break; ++ + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, +diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c +index 91b1825399..08eea48d6c 100644 +--- a/src/libxl/xen_xl.c ++++ b/src/libxl/xen_xl.c +@@ -1641,6 +1641,7 @@ xenFormatXLDiskSrc(virStorageSourcePtr src, char **srcstr) + + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + break; +diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c +index d32277d7fd..8bd6238238 100644 +--- a/src/qemu/qemu_block.c ++++ b/src/qemu/qemu_block.c +@@ -1108,6 +1108,11 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, + return NULL; + break; + ++ case VIR_STORAGE_TYPE_VHOST_USER: ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("unable to create blockdev props for vhostuser disk type")); ++ return NULL; ++ + case VIR_STORAGE_TYPE_VOLUME: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("storage source pool '%s' volume '%s' is not translated"), +@@ -2491,6 +2496,7 @@ qemuBlockStorageSourceCreateGetStorageProps(virStorageSourcePtr src, + case VIR_STORAGE_TYPE_DIR: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + return 0; + + case VIR_STORAGE_TYPE_NONE: +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 9157008b73..bc62843783 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -1166,6 +1166,7 @@ qemuGetDriveSourceString(virStorageSourcePtr src, + + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + break; +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 854b56a563..b2ad021e4d 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -14536,6 +14536,7 @@ qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdi + case VIR_STORAGE_TYPE_DIR: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -14553,6 +14554,7 @@ qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdi + case VIR_STORAGE_TYPE_DIR: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -14621,6 +14623,7 @@ qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk + case VIR_STORAGE_TYPE_DIR: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -14749,6 +14752,7 @@ qemuDomainSnapshotPrepareDiskInternal(virDomainDiskDefPtr disk, + case VIR_STORAGE_TYPE_DIR: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 1c48138ce3..faf4e223a8 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -228,6 +228,7 @@ qemuMigrationDstPrecreateDisk(virConnectPtr conn, + case VIR_STORAGE_TYPE_BLOCK: + case VIR_STORAGE_TYPE_DIR: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -1358,6 +1359,7 @@ qemuMigrationSrcIsSafe(virDomainDefPtr def, + unsafe = true; + break; + ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_BLOCK: + case VIR_STORAGE_TYPE_DIR: +diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c +index ffc8bdb344..2515dbf5ed 100644 +--- a/src/util/virstoragefile.c ++++ b/src/util/virstoragefile.c +@@ -56,6 +56,7 @@ VIR_ENUM_IMPL(virStorage, + "network", + "volume", + "nvme", ++ "vhostuser", + ); + + VIR_ENUM_IMPL(virStorageFileFormat, +@@ -2617,6 +2618,7 @@ virStorageSourceIsLocalStorage(const virStorageSource *src) + /* While NVMe disks are local, they are not accessible via src->path. + * Therefore, we have to return false here. */ + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_LAST: + case VIR_STORAGE_TYPE_NONE: + return false; +@@ -4164,6 +4166,7 @@ virStorageSourceUpdatePhysicalSize(virStorageSourcePtr src, + /* We shouldn't get VOLUME, but the switch requires all cases */ + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + return -1; +@@ -4610,6 +4613,7 @@ virStorageSourceIsRelative(virStorageSourcePtr src) + case VIR_STORAGE_TYPE_NETWORK: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NVME: ++ case VIR_STORAGE_TYPE_VHOST_USER: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + return false; +diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h +index 7939c09cd5..f2096b8705 100644 +--- a/src/util/virstoragefile.h ++++ b/src/util/virstoragefile.h +@@ -28,6 +28,7 @@ + #include "virseclabel.h" + #include "virstorageencryption.h" + #include "virsecret.h" ++#include "../conf/virconftypes.h" + #include "virenum.h" + #include "virpci.h" + +@@ -52,6 +53,7 @@ typedef enum { + VIR_STORAGE_TYPE_NETWORK, + VIR_STORAGE_TYPE_VOLUME, + VIR_STORAGE_TYPE_NVME, ++ VIR_STORAGE_TYPE_VHOST_USER, + + VIR_STORAGE_TYPE_LAST + } virStorageType; +@@ -302,6 +304,8 @@ struct _virStorageSource { + + virStorageSourceNVMeDefPtr nvme; /* type == VIR_STORAGE_TYPE_NVME */ + ++ virDomainChrSourceDefPtr vhostuser; /* type == VIR_STORAGE_TYPE_VHOST_USER */ ++ + virStorageSourceInitiatorDef initiator; + + virObjectPtr privateData; +diff --git a/tests/qemuxml2argvdata/disk-vhostuser.xml b/tests/qemuxml2argvdata/disk-vhostuser.xml +new file mode 100644 +index 0000000000..c96ef9119c +--- /dev/null ++++ b/tests/qemuxml2argvdata/disk-vhostuser.xml +@@ -0,0 +1,30 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ ++ ++ ++ ++ 1 ++ ++ hvm ++ ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/qemuxml2xmloutdata/disk-vhostuser.x86_64-latest.xml b/tests/qemuxml2xmloutdata/disk-vhostuser.x86_64-latest.xml +new file mode 100644 +index 0000000000..9712dc0b12 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/disk-vhostuser.x86_64-latest.xml +@@ -0,0 +1,48 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ ++ ++ ++ ++ 1 ++ ++ hvm ++ ++ ++ qemu64 ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++ ++
++ ++ ++
++ ++ ++ ++ ++ ++
++ ++ ++ +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index 3a2539596b..2569c27261 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -338,6 +338,7 @@ mymain(void) + DO_TEST("disk-network-vxhs", NONE); + DO_TEST("disk-network-tlsx509", NONE); + DO_TEST("disk-nvme", QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_QCOW2_LUKS); ++ DO_TEST_CAPS_LATEST("disk-vhostuser"); + DO_TEST("disk-scsi", QEMU_CAPS_SCSI_LSI, QEMU_CAPS_SCSI_MEGASAS, + QEMU_CAPS_SCSI_MPTSAS1068, QEMU_CAPS_SCSI_DISK_WWN); + DO_TEST("disk-virtio-scsi-reservations", +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/conf-properly-clear-out-autogenerated-macvtap-names-.patch b/generic_vdpa/libvirt/conf-properly-clear-out-autogenerated-macvtap-names-.patch new file mode 100644 index 0000000..74d9499 --- /dev/null +++ b/generic_vdpa/libvirt/conf-properly-clear-out-autogenerated-macvtap-names-.patch @@ -0,0 +1,110 @@ +From a5ec03f25b225408a9e7ebbf7b9fc9e3e2f15166 Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Sat, 22 Aug 2020 23:42:52 -0400 +Subject: [PATCH 049/108] conf: properly clear out autogenerated macvtap names + when formatting/parsing + +Back when macvtap support was added in commit 315baab9443 in Feb. 2010 +(libvirt-0.7.7), it was setup to autogenerate a name for the device if +one wasn't supplied, in the pattern "macvtap%d" (or "macvlan%d"), +similar to the way an unspecified standard tap device name will lead +to an autogenerated "vnet%d". + +As a matter of fact, in commit ca1b7cc8e45 added in May 2010, the code +was changed to *always* ignore a supplied device name for macvtap +interfaces by deleting *any* name immediately during the +parsing (this was intended to prevent one domain which had failed to +completely start from deleting the macvtap device of another domain +which had subsequently been provided the same device name (this will +seem mildly ironic later). This was later fixed to only clear the +device name when inactive XML was being parsed. HOWEVER - this was +only done if the xml was - autogenerated +names were not cleared for (which could +also result in a macvtap device). + +Although the names of "vnetX" tap devices had always been +automatically cleared when parsing (see commit d1304583d +from July 2008 (!)), at the time macvtap support was added, both vnetX +and macvtapX device names were always included when formatting the +XML. + +Then in commit a8be259d0cc (July 2011, libvirt-0.9.4), +formatting was changed to also clear out "vnetX" device names during +XML formatting as well. However the same treatment wasn't given to +"macvtapX". + +Now in 2020, there has been a report that a failed migration leads to +the macvtap device of some other unrelated guest on the destination +host losing its network connectivity. It was determined that this was +due to the domain XML in the migration containing a macvtap device +name, e.g. "macvtap0", that was already in use by the other guest on +the destination. Normally this wouldn't be a problem, because libvirt +would see that the device was already in use, and then find a +different unused name. But in this case, other external problems were +causing the migration to fail prior to selecting a macvtap device and +successfully opening it, and during error recovery, qemuProcessStop() +was called, which went through all def->nets objects and (if they were +macvtap) deleted the device specified in net->ifname; since libvirt +hadn't gotten to the point of replacing the incoming "macvtap0" with +the name of a device it actually created for this guest, that meant +that "macvtap0" was deleted, *even though it was currently in use by a +different guest*! + +Whew! + +So, it turns out that when formatting "migratable" XML, "vnetX" +devices are omitted, just as when formatting "inactive" XML. By making +the code in both interface parsing and formatting consistent for +"vnetX", "macvtapX", and "macvlanX", we can thus make sure that the +autogenerated (and unneeded / completely *not* wanted) macvtap device +name will not be sent with the migration XML. This way when a +migration fails, net->ifname will be NULL, and libvirt won't have any +device to try and (erroneously) delete. + +Signed-off-by: Laine Stump +Reviewed-by: Daniel Henrique Barboza +(cherry picked from commit 282d135ddbb7203565cd5527b451469b14953994) +--- + src/conf/domain_conf.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 54228a2151..d3565ececf 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -12357,14 +12357,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + } + + def->data.direct.linkdev = g_steal_pointer(&dev); +- +- if (ifname && +- flags & VIR_DOMAIN_DEF_PARSE_INACTIVE && +- (STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || +- STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX))) { +- VIR_FREE(ifname); +- } +- + break; + + case VIR_DOMAIN_NET_TYPE_HOSTDEV: +@@ -12410,6 +12402,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + if (def->managed_tap != VIR_TRISTATE_BOOL_NO && ifname && + (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) && + (STRPREFIX(ifname, VIR_NET_GENERATED_TAP_PREFIX) || ++ STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || ++ STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) || + (prefix && STRPREFIX(ifname, prefix)))) { + /* An auto-generated target name, blank it out */ + VIR_FREE(ifname); +@@ -26263,6 +26257,8 @@ virDomainNetDefFormat(virBufferPtr buf, + (def->managed_tap == VIR_TRISTATE_BOOL_NO || + !((flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) && + (STRPREFIX(def->ifname, VIR_NET_GENERATED_TAP_PREFIX) || ++ STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || ++ STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) || + (prefix && STRPREFIX(def->ifname, prefix)))))) { + /* Skip auto-generated target names for inactive config. */ + virBufferEscapeString(&attrBuf, " dev='%s'", def->ifname); +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/conf-validate-serial-port-model-in-ABI-checks.patch b/generic_vdpa/libvirt/conf-validate-serial-port-model-in-ABI-checks.patch new file mode 100644 index 0000000..926e02f --- /dev/null +++ b/generic_vdpa/libvirt/conf-validate-serial-port-model-in-ABI-checks.patch @@ -0,0 +1,41 @@ +From 0e6fcb0eb5e3eb499a3cc7232fa1b7bf9f1813a2 Mon Sep 17 00:00:00 2001 +From: jiangdawei15 +Date: Thu, 11 Aug 2022 21:24:35 +0800 +Subject: [PATCH 06/22] conf: validate serial port model in ABI checks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The serial port model cannot be allowed to +change across migration as it affects ABI. + +Reviewed-by: Andrea Bolognani + +Signed-off-by: Daniel P. Berrangé +Signed-off-by: Dawei Jiang jiangdawei15@huawei.com +--- + src/conf/domain_conf.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 1689d92c51..2d1726af8f 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -23058,6 +23058,14 @@ virDomainSerialDefCheckABIStability(virDomainChrDefPtr src, + return false; + } + ++ if (src->targetModel != dst->targetModel) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Target serial model %s does not match source %s"), ++ virDomainChrSerialTargetModelTypeToString(dst->targetModel), ++ virDomainChrSerialTargetModelTypeToString(src->targetModel)); ++ return false; ++ } ++ + if (src->target.port != dst->target.port) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target serial port %d does not match source %d"), +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/cpu_map-Add-Cooperlake-x86-CPU-model.patch b/generic_vdpa/libvirt/cpu_map-Add-Cooperlake-x86-CPU-model.patch new file mode 100644 index 0000000..96d36bb --- /dev/null +++ b/generic_vdpa/libvirt/cpu_map-Add-Cooperlake-x86-CPU-model.patch @@ -0,0 +1,167 @@ +From 41717af8988db9c2d9d8b753f306f6deaa1cec8d Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Tue, 19 May 2020 15:08:11 +0200 +Subject: [PATCH 2/3] cpu_map: Add Cooperlake x86 CPU model + +The stepping range (10-11) is likely incomplete. QEMU uses 10 and the +CPUID data for Cooperlake show 11. We will update the range if needed +once more details about he CPU are available. + +Signed-off-by: Jiri Denemark +Reviewed-by: Pavel Hrdina +Signed-off-by: Jingyi Wang +--- + src/cpu_map/index.xml | 1 + + src/cpu_map/x86_Cooperlake.xml | 89 +++++++++++++++++++ + .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + + .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 1 + + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + + 5 files changed, 93 insertions(+) + create mode 100644 src/cpu_map/x86_Cooperlake.xml + +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 672d0a3c92..3ccc76b9ed 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -54,6 +54,7 @@ + + + ++ + + + +diff --git a/src/cpu_map/x86_Cooperlake.xml b/src/cpu_map/x86_Cooperlake.xml +new file mode 100644 +index 0000000000..77e695aea4 +--- /dev/null ++++ b/src/cpu_map/x86_Cooperlake.xml +@@ -0,0 +1,89 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +index ff721530cd..fa945fc002 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +@@ -93,6 +93,7 @@ + EPYC-IBPB + EPYC + Dhyana ++ Cooperlake + Conroe + Cascadelake-Server-noTSX + Cascadelake-Server +diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +index d567863f49..a0eeed7c2d 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +@@ -101,6 +101,7 @@ + EPYC-IBPB + EPYC + Dhyana ++ Cooperlake + Conroe + Cascadelake-Server-noTSX + Cascadelake-Server +diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +index 2c6066003d..fbde7a6ba2 100644 +--- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +@@ -92,6 +92,7 @@ + EPYC-IBPB + EPYC + Dhyana ++ Cooperlake + Conroe + Cascadelake-Server-noTSX + Cascadelake-Server +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/cpu_map-Add-pschange-mc-no-bit-in-IA32_ARCH_CAPABILI.patch b/generic_vdpa/libvirt/cpu_map-Add-pschange-mc-no-bit-in-IA32_ARCH_CAPABILI.patch new file mode 100644 index 0000000..79420a7 --- /dev/null +++ b/generic_vdpa/libvirt/cpu_map-Add-pschange-mc-no-bit-in-IA32_ARCH_CAPABILI.patch @@ -0,0 +1,131 @@ +From 9696e88e150fce9ea82eadb16726c8c3a7a197ae Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Mon, 18 May 2020 20:55:42 +0200 +Subject: [PATCH 1/3] cpu_map: Add pschange-mc-no bit in IA32_ARCH_CAPABILITIES + MSR + +Signed-off-by: Jiri Denemark +Reviewed-by: Pavel Hrdina +Signed-off-by: Jingyi Wang +--- + src/cpu_map/x86_features.xml | 3 +++ + tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml | 2 +- + tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml | 1 + + tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml | 1 + + tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml | 1 + + tests/domaincapsdata/qemu_4.2.0.x86_64.xml | 1 + + tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + + 9 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 2c4c29dc99..8525ae0fa5 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -509,6 +509,9 @@ + + + ++ ++ ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml +index 6c480eeacf..57f8ebabba 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-enabled.xml +@@ -5,5 +5,5 @@ + + + +- ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml +index 92404e4d03..ed06515e99 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-guest.xml +@@ -26,6 +26,7 @@ + + + ++ + + + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml +index 7f6fe2eac3..7681c94649 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-host.xml +@@ -27,4 +27,5 @@ + + + ++ + +diff --git a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml +index 645c0934c2..4774d39c7e 100644 +--- a/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Core-i7-8550U-json.xml +@@ -14,6 +14,7 @@ + + + ++ + + + +diff --git a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml +index 1b8b8be2f5..fcb0505da0 100644 +--- a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml +@@ -47,6 +47,7 @@ + + + ++ + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml +index 213dcc5a08..e22ef8e032 100644 +--- a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml +@@ -46,6 +46,7 @@ + + + ++ + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +index 45c3e00b1e..ff721530cd 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +@@ -47,6 +47,7 @@ + + + ++ + + + qemu64 +diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +index d2a884eed1..2c6066003d 100644 +--- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +@@ -46,6 +46,7 @@ + + + ++ + + + qemu64 +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/cpu_map-Distribute-x86_Cooperlake.xml.patch b/generic_vdpa/libvirt/cpu_map-Distribute-x86_Cooperlake.xml.patch new file mode 100644 index 0000000..bcef2fb --- /dev/null +++ b/generic_vdpa/libvirt/cpu_map-Distribute-x86_Cooperlake.xml.patch @@ -0,0 +1,30 @@ +From fc20e12b3be7a4c96ff0a71112d69181408506d1 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Tue, 26 May 2020 12:52:00 +0200 +Subject: [PATCH 3/3] cpu_map: Distribute x86_Cooperlake.xml +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Jingyi Wang +--- + src/cpu_map/Makefile.inc.am | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am +index ab5268d94f..8eb818706a 100644 +--- a/src/cpu_map/Makefile.inc.am ++++ b/src/cpu_map/Makefile.inc.am +@@ -22,6 +22,7 @@ cpumap_DATA = \ + cpu_map/x86_Cascadelake-Server.xml \ + cpu_map/x86_Cascadelake-Server-noTSX.xml \ + cpu_map/x86_Conroe.xml \ ++ cpu_map/x86_Cooperlake.xml \ + cpu_map/x86_core2duo.xml \ + cpu_map/x86_coreduo.xml \ + cpu_map/x86_cpu64-rhel5.xml \ +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/cpu_map-Fix-Icelake-Server-model-number.patch b/generic_vdpa/libvirt/cpu_map-Fix-Icelake-Server-model-number.patch new file mode 100644 index 0000000..0261661 --- /dev/null +++ b/generic_vdpa/libvirt/cpu_map-Fix-Icelake-Server-model-number.patch @@ -0,0 +1,45 @@ +From a70f3b2d8b707063c63fb3b43751651e5fedebb9 Mon Sep 17 00:00:00 2001 +From: Tim Wiederhake +Date: Wed, 2 Dec 2020 11:38:22 +0100 +Subject: [PATCH 012/108] cpu_map: Fix Icelake Server model number + +See arch/x86/include/asm/intel-family.h in the Kernel: + #define INTEL_FAM6_ICELAKE_X 0x6A + +Signed-off-by: Tim Wiederhake +Reviewed-by: Jiri Denemark +(cherry picked from commit 1278ac6265589cd83cc2e661056c860e98105507) +--- + src/cpu_map/x86_Icelake-Server-noTSX.xml | 2 +- + src/cpu_map/x86_Icelake-Server.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cpu_map/x86_Icelake-Server-noTSX.xml b/src/cpu_map/x86_Icelake-Server-noTSX.xml +index 2fd6906406..34a0f7c18c 100644 +--- a/src/cpu_map/x86_Icelake-Server-noTSX.xml ++++ b/src/cpu_map/x86_Icelake-Server-noTSX.xml +@@ -1,7 +1,7 @@ + + + +- ++ + + + +diff --git a/src/cpu_map/x86_Icelake-Server.xml b/src/cpu_map/x86_Icelake-Server.xml +index 367ade7240..1ee4ea9cd4 100644 +--- a/src/cpu_map/x86_Icelake-Server.xml ++++ b/src/cpu_map/x86_Icelake-Server.xml +@@ -1,7 +1,7 @@ + + + +- ++ + + + +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/cpu_ppc64-compare-CPU-function-is-ignoring-return-va.patch b/generic_vdpa/libvirt/cpu_ppc64-compare-CPU-function-is-ignoring-return-va.patch new file mode 100644 index 0000000..369d662 --- /dev/null +++ b/generic_vdpa/libvirt/cpu_ppc64-compare-CPU-function-is-ignoring-return-va.patch @@ -0,0 +1,44 @@ +From 9549d796fd310e41ec58f1c438328d1bedc0cb93 Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Tue, 29 Nov 2022 12:12:58 +0000 +Subject: [PATCH 09/24] cpu_ppc64: compare CPU function is ignoring return + value Function to compare CPU on 64-bits PowerPC is ignoring the flag to + avoid failure in case of CPUs (host and guest) are incompatible. Basically, + the function is returning -1 even if it is set to continue. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Julio Faracco jcfaracco@gmail.com +Reviewed-by: Ján Tomko jtomko@redhat.com +Signed-off-by: Ján Tomko jtomko@redhat.com + +Signed-off-by: tangbin tangbin_yewu@cmss.chinamobile.com +(cherry-pick from b356d81b8960c3a43212f8c0e9eab66465c8c10a) +--- + src/cpu/cpu_ppc64.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c +index 6b3590ab6a..9cbb28cbc5 100644 +--- a/src/cpu/cpu_ppc64.c ++++ b/src/cpu/cpu_ppc64.c +@@ -561,11 +561,11 @@ virCPUppc64Compare(virCPUDefPtr host, + if (failIncompatible) { + virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", + _("unknown host CPU")); +- } else { +- VIR_WARN("unknown host CPU"); +- ret = VIR_CPU_COMPARE_INCOMPATIBLE; ++ return VIR_CPU_COMPARE_ERROR; + } +- return -1; ++ ++ VIR_WARN("unknown host CPU"); ++ return VIR_CPU_COMPARE_INCOMPATIBLE; + } + + ret = ppc64Compute(host, cpu, NULL, &message); +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/cpu_topo-fix-detection-of-vCPU-pids-when-multiple-cl.patch b/generic_vdpa/libvirt/cpu_topo-fix-detection-of-vCPU-pids-when-multiple-cl.patch new file mode 100644 index 0000000..123b781 --- /dev/null +++ b/generic_vdpa/libvirt/cpu_topo-fix-detection-of-vCPU-pids-when-multiple-cl.patch @@ -0,0 +1,108 @@ +From a450496281dbbc2b240bf5dc0829a17d113aed22 Mon Sep 17 00:00:00 2001 +From: zhangxinhao +Date: Wed, 17 May 2023 09:41:19 +0800 +Subject: cpu_topo: fix detection of vCPU pids when multiple + clusters are present + +The logic for querying hotpluggable CPUs needs to sort the list +of CPUs returned by QEMU. Add the logic of cluster when sorting +the hotpluggable CPUs. + +Signed-off-by: zhangxinhao +--- + src/qemu/qemu_domain.c | 3 ++- + src/qemu/qemu_monitor.c | 2 ++ + src/qemu/qemu_monitor.h | 2 ++ + src/qemu/qemu_monitor_json.c | 5 +++++ + 4 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 152c8615d5..fbc665aff3 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -13877,11 +13877,12 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver, + + if (validTIDs) + VIR_DEBUG("vCPU[%zu] PID %llu is valid " +- "(node=%d socket=%d die=%d core=%d thread=%d)", ++ "(node=%d socket=%d die=%d cluster=%d core=%d thread=%d)", + i, (unsigned long long)info[i].tid, + info[i].node_id, + info[i].socket_id, + info[i].die_id, ++ info[i].cluster_id, + info[i].core_id, + info[i].thread_id); + } +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index ffd1d348e5..3bdfdbe078 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -1676,6 +1676,7 @@ qemuMonitorCPUInfoClear(qemuMonitorCPUInfoPtr cpus, + cpus[i].qemu_id = -1; + cpus[i].socket_id = -1; + cpus[i].die_id = -1; ++ cpus[i].cluster_id = -1; + cpus[i].core_id = -1; + cpus[i].thread_id = -1; + cpus[i].node_id = -1; +@@ -1832,6 +1833,7 @@ qemuMonitorGetCPUInfoHotplug(struct qemuMonitorQueryHotpluggableCpusEntry *hotpl + !vcpus[mastervcpu].online; + vcpus[mastervcpu].socket_id = hotplugvcpus[i].socket_id; + vcpus[mastervcpu].die_id = hotplugvcpus[i].die_id; ++ vcpus[mastervcpu].cluster_id = hotplugvcpus[i].cluster_id; + vcpus[mastervcpu].core_id = hotplugvcpus[i].core_id; + vcpus[mastervcpu].thread_id = hotplugvcpus[i].thread_id; + vcpus[mastervcpu].node_id = hotplugvcpus[i].node_id; +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index 76d0bbb753..1c6b001872 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -579,6 +579,7 @@ struct qemuMonitorQueryHotpluggableCpusEntry { + int node_id; + int socket_id; + int die_id; ++ int cluster_id; + int core_id; + int thread_id; + +@@ -602,6 +603,7 @@ struct _qemuMonitorCPUInfo { + * all entries are -1 */ + int socket_id; + int die_id; ++ int cluster_id; + int core_id; + int thread_id; + int node_id; +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index a02d0e2780..afd826bc2f 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -8598,12 +8598,14 @@ qemuMonitorJSONProcessHotpluggableCpusReply(virJSONValuePtr vcpu, + entry->node_id = -1; + entry->socket_id = -1; + entry->die_id = -1; ++ entry->cluster_id = -1; + entry->core_id = -1; + entry->thread_id = -1; + + ignore_value(virJSONValueObjectGetNumberInt(props, "node-id", &entry->node_id)); + ignore_value(virJSONValueObjectGetNumberInt(props, "socket-id", &entry->socket_id)); + ignore_value(virJSONValueObjectGetNumberInt(props, "die-id", &entry->die_id)); ++ ignore_value(virJSONValueObjectGetNumberInt(props, "cluster-id", &entry->cluster_id)); + ignore_value(virJSONValueObjectGetNumberInt(props, "core-id", &entry->core_id)); + ignore_value(virJSONValueObjectGetNumberInt(props, "thread-id", &entry->thread_id)); + +@@ -8641,6 +8643,9 @@ qemuMonitorQueryHotpluggableCpusEntrySort(const void *p1, + if (a->die_id != b->die_id) + return a->die_id - b->die_id; + ++ if (a->cluster_id != b->cluster_id) ++ return a->cluster_id - b->cluster_id; ++ + if (a->core_id != b->core_id) + return a->core_id - b->core_id; + +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/cpu_topo-support-for-cpu_topo-clusters-in-conf.patch b/generic_vdpa/libvirt/cpu_topo-support-for-cpu_topo-clusters-in-conf.patch new file mode 100644 index 0000000..c8a96f7 --- /dev/null +++ b/generic_vdpa/libvirt/cpu_topo-support-for-cpu_topo-clusters-in-conf.patch @@ -0,0 +1,1152 @@ +From 576236efe092a457cd3c33fef139fb21985713c6 Mon Sep 17 00:00:00 2001 +From: zhangxinhao +Date: Tue, 9 May 2023 15:23:48 +0800 +Subject: cpu_topo: support for cpu_topo "clusters” in conf + +Kunpeng920 support a new structure "cluster" in cpu topology. Support +"clusters" in XML parser. + +Signed-off-by: zhangxinhao +--- + docs/formatcaps.html.in | 2 +- + docs/formatdomain.html.in | 23 +++++++++-------- + docs/schemas/cputypes.rng | 5 ++++ + src/conf/cpu_conf.c | 25 +++++++++++++++++-- + src/conf/cpu_conf.h | 1 + + src/conf/domain_conf.c | 1 + + src/cpu/cpu.c | 1 + + src/qemu/qemu_command.c | 5 ++++ + src/vmx/vmx.c | 7 ++++++ + .../x86_64-host+guest,model486-result.xml | 2 +- + .../x86_64-host+guest,models-result.xml | 2 +- + .../cputestdata/x86_64-host+guest-result.xml | 2 +- + tests/cputestdata/x86_64-host+guest.xml | 2 +- + .../x86_64-host+host-model-nofallback.xml | 2 +- + ...t-Haswell-noTSX+Haswell,haswell-result.xml | 2 +- + ...ell-noTSX+Haswell-noTSX,haswell-result.xml | 2 +- + ...ost-Haswell-noTSX+Haswell-noTSX-result.xml | 2 +- + .../x86_64-host-worse+guest-result.xml | 2 +- + .../ppc64-modern-bulk-result-conf.xml | 2 +- + .../ppc64-modern-bulk-result-live.xml | 2 +- + .../ppc64-modern-individual-result-conf.xml | 2 +- + .../ppc64-modern-individual-result-live.xml | 2 +- + .../x86-modern-bulk-result-conf.xml | 2 +- + .../x86-modern-bulk-result-live.xml | 2 +- + .../x86-modern-individual-add-result-conf.xml | 2 +- + .../x86-modern-individual-add-result-live.xml | 2 +- + .../x86-old-bulk-result-conf.xml | 2 +- + .../x86-old-bulk-result-live.xml | 2 +- + .../fd-memory-no-numa-topology.xml | 2 +- + .../fd-memory-numa-topology.xml | 2 +- + .../fd-memory-numa-topology2.xml | 2 +- + .../fd-memory-numa-topology3.xml | 2 +- + tests/qemuxml2argvdata/hugepages-nvdimm.xml | 2 +- + .../memfd-memory-default-hugepage.xml | 2 +- + tests/qemuxml2argvdata/memfd-memory-numa.xml | 2 +- + .../memory-hotplug-nvdimm-access.xml | 2 +- + .../memory-hotplug-nvdimm-align.xml | 2 +- + .../memory-hotplug-nvdimm-label.xml | 2 +- + .../memory-hotplug-nvdimm-pmem.xml | 2 +- + .../memory-hotplug-nvdimm-readonly.xml | 2 +- + .../memory-hotplug-nvdimm.xml | 2 +- + .../qemuxml2xmloutdata/cpu-numa-disjoint.xml | 2 +- + .../cpu-numa-disordered.xml | 2 +- + .../qemuxml2xmloutdata/cpu-numa-memshared.xml | 2 +- + .../cpu-numa-no-memory-element.xml | 2 +- + tests/qemuxml2xmloutdata/cpu-numa1.xml | 2 +- + tests/qemuxml2xmloutdata/cpu-numa2.xml | 2 +- + .../fd-memory-no-numa-topology.xml | 2 +- + .../fd-memory-numa-topology.xml | 2 +- + .../fd-memory-numa-topology2.xml | 2 +- + .../fd-memory-numa-topology3.xml | 2 +- + .../graphics-spice-timeout.xml | 2 +- + tests/qemuxml2xmloutdata/hugepages-nvdimm.xml | 2 +- + .../memfd-memory-default-hugepage.xml | 2 +- + .../qemuxml2xmloutdata/memfd-memory-numa.xml | 2 +- + .../memory-hotplug-dimm.xml | 2 +- + .../memory-hotplug-nvdimm-access.xml | 2 +- + .../memory-hotplug-nvdimm-align.xml | 2 +- + .../memory-hotplug-nvdimm-label.xml | 2 +- + .../memory-hotplug-nvdimm-pmem.xml | 2 +- + .../memory-hotplug-nvdimm-ppc64.xml | 2 +- + .../memory-hotplug-nvdimm-readonly.xml | 2 +- + .../memory-hotplug-nvdimm.xml | 2 +- + tests/qemuxml2xmloutdata/memory-hotplug.xml | 2 +- + .../numad-auto-memory-vcpu-cpuset.xml | 2 +- + ...to-memory-vcpu-no-cpuset-and-placement.xml | 2 +- + .../numad-auto-vcpu-no-numatune.xml | 2 +- + .../numad-static-vcpu-no-numatune.xml | 2 +- + tests/qemuxml2xmloutdata/pci-expander-bus.xml | 2 +- + .../qemuxml2xmloutdata/pcie-expander-bus.xml | 2 +- + .../pseries-phb-numa-node.xml | 2 +- + tests/qemuxml2xmloutdata/smp.xml | 2 +- + .../vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml | 2 +- + .../vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml | 2 +- + 74 files changed, 121 insertions(+), 79 deletions(-) + +diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in +index 59d21a7..ff40f06 100644 +--- a/docs/formatcaps.html.in ++++ b/docs/formatcaps.html.in +@@ -173,7 +173,7 @@ + </features> + <model>core2duo</model> + <vendor>Intel</vendor> +- <topology sockets="1" dies="1" cores="2" threads="1"/> ++ <topology sockets="1" dies="1" clusters="1" cores="2" threads="1"/> + <feature name="lahf_lm"/> + <feature name='xtpr'/> + ... +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 5860ec9..6e51c3b 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -1470,7 +1470,7 @@ + <cpu match='exact'> + <model fallback='allow'>core2duo</model> + <vendor>Intel</vendor> +- <topology sockets='1' dies='1' cores='2' threads='1'/> ++ <topology sockets='1' dies='1' clusters="1" cores='2' threads='1'/> + <cache level='3' mode='emulate'/> + <feature policy='disable' name='lahf_lm'/> + </cpu> +@@ -1479,7 +1479,7 @@ +
+ <cpu mode='host-model'>
+   <model fallback='forbid'/>
+-  <topology sockets='1' dies='1' cores='2' threads='1'/>
++  <topology sockets='1' dies='1' clusters='1' cores='2' threads='1'/>
+ </cpu>
+ ...
+ +@@ -1498,7 +1498,7 @@ +
+ ...
+ <cpu>
+-  <topology sockets='1' dies='1' cores='2' threads='1'/>
++  <topology sockets='1' dies='1' clusters='1' cores='2' threads='1'/>
+ </cpu>
+ ...
+ +@@ -1674,14 +1674,15 @@ +
topology
+
The topology element specifies requested topology of + virtual CPU provided to the guest. Four attributes, sockets, +- dies, cores, and threads, +- accept non-zero positive integer values. They refer to the total number +- of CPU sockets, number of dies per socket, number of cores per die, and +- number of threads per core, respectively. The dies +- attribute is optional and will default to 1 if omitted, while the other +- attributes are all mandatory. Hypervisors may require that the maximum +- number of vCPUs specified by the cpus element equals to +- the number of vcpus resulting from the topology.
++ dies, dies, cores, ++ and threads, accept non-zero positive integer values. They ++ refer to the total number of CPU sockets, number of dies per socket, ++ number of clusters per die, number of cores per cluster, and number of ++ threads per core, respectively. The attribute dies and ++ clusters are optional and will default to 1 if omitted, ++ while the other attributes are all mandatory. Hypervisors may require ++ that the maximum number of vCPUs specified by the cpus ++ element equals to the number of vcpus resulting from the topology. + +
feature
+
The cpu element can contain zero or more +diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng +index e2744ac..699fd05 100644 +--- a/docs/schemas/cputypes.rng ++++ b/docs/schemas/cputypes.rng +@@ -91,6 +91,11 @@ + + + ++ ++ ++ ++ ++ + + + +diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c +index 989306b..3c2ee73 100644 +--- a/src/conf/cpu_conf.c ++++ b/src/conf/cpu_conf.c +@@ -240,6 +240,7 @@ virCPUDefCopyWithoutModel(const virCPUDef *cpu) + copy->fallback = cpu->fallback; + copy->sockets = cpu->sockets; + copy->dies = cpu->dies; ++ copy->clusters = cpu->clusters; + copy->cores = cpu->cores; + copy->threads = cpu->threads; + copy->arch = cpu->arch; +@@ -547,6 +548,17 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, + def->dies = 1; + } + ++ if (virXPathNode("./topology[1]/@clusters", ctxt)) { ++ if (virXPathULong("string(./topology[1]/@clusters)", ctxt, &ul) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Malformed 'clusters' attribute in CPU topology")); ++ goto cleanup; ++ } ++ def->clusters = (unsigned int) ul; ++ } else { ++ def->clusters = 1; ++ } ++ + if (virXPathULong("string(./topology[1]/@cores)", ctxt, &ul) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing 'cores' attribute in CPU topology")); +@@ -561,7 +573,8 @@ virCPUDefParseXML(xmlXPathContextPtr ctxt, + } + def->threads = (unsigned int) ul; + +- if (!def->sockets || !def->cores || !def->threads || !def->dies) { ++ if (!def->sockets || !def->cores || !def->threads || !def->dies || ++ !def -> clusters) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Invalid CPU topology")); + goto cleanup; +@@ -833,10 +846,12 @@ virCPUDefFormatBuf(virBufferPtr buf, + virBufferAddLit(buf, "/>\n"); + } + +- if (def->sockets && def->dies && def->cores && def->threads) { ++ if (def->sockets && def->dies && def->clusters && def->cores && ++ def->threads) { + virBufferAddLit(buf, "sockets); + virBufferAsprintf(buf, " dies='%u'", def->dies); ++ virBufferAsprintf(buf, " clusters='%u'", def->clusters); + virBufferAsprintf(buf, " cores='%u'", def->cores); + virBufferAsprintf(buf, " threads='%u'", def->threads); + virBufferAddLit(buf, "/>\n"); +@@ -1081,6 +1096,12 @@ virCPUDefIsEqual(virCPUDefPtr src, + return false; + } + ++ if (src->clusters != dst->clusters) { ++ MISMATCH(_("Target CPU clusters %d does not match source %d"), ++ dst->clusters, src->clusters); ++ return false; ++ } ++ + if (src->cores != dst->cores) { + MISMATCH(_("Target CPU cores %d does not match source %d"), + dst->cores, src->cores); +diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h +index 1b297ed..10a2252 100644 +--- a/src/conf/cpu_conf.h ++++ b/src/conf/cpu_conf.h +@@ -134,6 +134,7 @@ struct _virCPUDef { + unsigned int microcodeVersion; + unsigned int sockets; + unsigned int dies; ++ unsigned int clusters; + unsigned int cores; + unsigned int threads; + size_t nfeatures; +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index b8cf1ad..7ae4034 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -2088,6 +2088,7 @@ virDomainDefGetVcpusTopology(const virDomainDef *def, + + /* multiplication of 32bit numbers fits into a 64bit variable */ + if ((tmp *= def->cpu->dies) > UINT_MAX || ++ (tmp *= def->cpu->clusters) > UINT_MAX || + (tmp *= def->cpu->cores) > UINT_MAX || + (tmp *= def->cpu->threads) > UINT_MAX) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c +index df78a0d..27d26fc 100644 +--- a/src/cpu/cpu.c ++++ b/src/cpu/cpu.c +@@ -426,6 +426,7 @@ virCPUGetHost(virArch arch, + if (nodeInfo) { + cpu->sockets = nodeInfo->sockets; + cpu->dies = 1; ++ cpu->clusters = 1; + cpu->cores = nodeInfo->cores; + cpu->threads = nodeInfo->threads; + } +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 5f7e847..85f95b4 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -7335,6 +7335,11 @@ qemuBuildSmpCommandLine(virCommandPtr cmd, + _("Only 1 die per socket is supported")); + return -1; + } ++ if (def->cpu->clusters != 1) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("Only 1 cluster per dies is supported")); ++ return -1; ++ } + virBufferAsprintf(&buf, ",sockets=%u", def->cpu->sockets); + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMP_DIES)) + virBufferAsprintf(&buf, ",dies=%u", def->cpu->dies); +diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c +index 5f2ada6..76e5e66 100644 +--- a/src/vmx/vmx.c ++++ b/src/vmx/vmx.c +@@ -1494,6 +1494,7 @@ virVMXParseConfig(virVMXContext *ctx, + goto cleanup; + } + cpu->dies = 1; ++ cpu->clusters = 1; + cpu->cores = coresPerSocket; + cpu->threads = 1; + +@@ -3222,6 +3223,12 @@ virVMXFormatConfig(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virDomainDe + goto cleanup; + } + ++ if (def->cpu->clusters != 1) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("Only 1 cluster per die is supported")); ++ goto cleanup; ++ } ++ + calculated_vcpus = def->cpu->sockets * def->cpu->cores; + if (calculated_vcpus != maxvcpus) { + virReportError(VIR_ERR_INTERNAL_ERROR, +diff --git a/tests/cputestdata/x86_64-host+guest,model486-result.xml b/tests/cputestdata/x86_64-host+guest,model486-result.xml +index ea8e2d3..b533f22 100644 +--- a/tests/cputestdata/x86_64-host+guest,model486-result.xml ++++ b/tests/cputestdata/x86_64-host+guest,model486-result.xml +@@ -1,6 +1,6 @@ + + 486 +- ++ + + + +diff --git a/tests/cputestdata/x86_64-host+guest,models-result.xml b/tests/cputestdata/x86_64-host+guest,models-result.xml +index 0dd6955..f476022 100644 +--- a/tests/cputestdata/x86_64-host+guest,models-result.xml ++++ b/tests/cputestdata/x86_64-host+guest,models-result.xml +@@ -1,6 +1,6 @@ + + Nehalem +- ++ + + + +diff --git a/tests/cputestdata/x86_64-host+guest-result.xml b/tests/cputestdata/x86_64-host+guest-result.xml +index 28e3152..cf41b3f 100644 +--- a/tests/cputestdata/x86_64-host+guest-result.xml ++++ b/tests/cputestdata/x86_64-host+guest-result.xml +@@ -1,6 +1,6 @@ + + Penryn +- ++ + + + +diff --git a/tests/cputestdata/x86_64-host+guest.xml b/tests/cputestdata/x86_64-host+guest.xml +index 28e3152..cf41b3f 100644 +--- a/tests/cputestdata/x86_64-host+guest.xml ++++ b/tests/cputestdata/x86_64-host+guest.xml +@@ -1,6 +1,6 @@ + + Penryn +- ++ + + + +diff --git a/tests/cputestdata/x86_64-host+host-model-nofallback.xml b/tests/cputestdata/x86_64-host+host-model-nofallback.xml +index 16d6e1d..881eea7 100644 +--- a/tests/cputestdata/x86_64-host+host-model-nofallback.xml ++++ b/tests/cputestdata/x86_64-host+host-model-nofallback.xml +@@ -1,7 +1,7 @@ + + Penryn + Intel +- ++ + + + +diff --git a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell,haswell-result.xml b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell,haswell-result.xml +index 8eda668..67994c6 100644 +--- a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell,haswell-result.xml ++++ b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell,haswell-result.xml +@@ -1,6 +1,6 @@ + + Haswell +- ++ + + + +diff --git a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml +index cb02449..4804c0b 100644 +--- a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml ++++ b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX,haswell-result.xml +@@ -1,6 +1,6 @@ + + Haswell +- ++ + + + +diff --git a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX-result.xml b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX-result.xml +index 7ee926a..c21b331 100644 +--- a/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX-result.xml ++++ b/tests/cputestdata/x86_64-host-Haswell-noTSX+Haswell-noTSX-result.xml +@@ -1,4 +1,4 @@ + + Haswell-noTSX +- ++ + +diff --git a/tests/cputestdata/x86_64-host-worse+guest-result.xml b/tests/cputestdata/x86_64-host-worse+guest-result.xml +index 9d54c66..712c3ad 100644 +--- a/tests/cputestdata/x86_64-host-worse+guest-result.xml ++++ b/tests/cputestdata/x86_64-host-worse+guest-result.xml +@@ -1,6 +1,6 @@ + + Penryn +- ++ + + + +diff --git a/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-conf.xml b/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-conf.xml +index f80c436..e976c00 100644 +--- a/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-conf.xml ++++ b/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-conf.xml +@@ -43,7 +43,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-live.xml b/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-live.xml +index 7998b97..21666a0 100644 +--- a/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-live.xml ++++ b/tests/qemuhotplugtestcpus/ppc64-modern-bulk-result-live.xml +@@ -43,7 +43,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-conf.xml b/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-conf.xml +index 2a48a97..2740737 100644 +--- a/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-conf.xml ++++ b/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-conf.xml +@@ -43,7 +43,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-live.xml b/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-live.xml +index 90518d1..b9e325d 100644 +--- a/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-live.xml ++++ b/tests/qemuhotplugtestcpus/ppc64-modern-individual-result-live.xml +@@ -43,7 +43,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuhotplugtestcpus/x86-modern-bulk-result-conf.xml b/tests/qemuhotplugtestcpus/x86-modern-bulk-result-conf.xml +index 0d622fc..0b86f3a 100644 +--- a/tests/qemuhotplugtestcpus/x86-modern-bulk-result-conf.xml ++++ b/tests/qemuhotplugtestcpus/x86-modern-bulk-result-conf.xml +@@ -19,7 +19,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuhotplugtestcpus/x86-modern-bulk-result-live.xml b/tests/qemuhotplugtestcpus/x86-modern-bulk-result-live.xml +index ed9deae..c21b000 100644 +--- a/tests/qemuhotplugtestcpus/x86-modern-bulk-result-live.xml ++++ b/tests/qemuhotplugtestcpus/x86-modern-bulk-result-live.xml +@@ -19,7 +19,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-conf.xml b/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-conf.xml +index 342f172..bef1189 100644 +--- a/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-conf.xml ++++ b/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-conf.xml +@@ -19,7 +19,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-live.xml b/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-live.xml +index b8341c7..aa63e72 100644 +--- a/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-live.xml ++++ b/tests/qemuhotplugtestcpus/x86-modern-individual-add-result-live.xml +@@ -19,7 +19,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuhotplugtestcpus/x86-old-bulk-result-conf.xml b/tests/qemuhotplugtestcpus/x86-old-bulk-result-conf.xml +index 29da89f..2952fba 100644 +--- a/tests/qemuhotplugtestcpus/x86-old-bulk-result-conf.xml ++++ b/tests/qemuhotplugtestcpus/x86-old-bulk-result-conf.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuhotplugtestcpus/x86-old-bulk-result-live.xml b/tests/qemuhotplugtestcpus/x86-old-bulk-result-live.xml +index f81194d..a5087a7 100644 +--- a/tests/qemuhotplugtestcpus/x86-old-bulk-result-live.xml ++++ b/tests/qemuhotplugtestcpus/x86-old-bulk-result-live.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuxml2argvdata/fd-memory-no-numa-topology.xml b/tests/qemuxml2argvdata/fd-memory-no-numa-topology.xml +index 0749952..d9e20d4 100644 +--- a/tests/qemuxml2argvdata/fd-memory-no-numa-topology.xml ++++ b/tests/qemuxml2argvdata/fd-memory-no-numa-topology.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuxml2argvdata/fd-memory-numa-topology.xml b/tests/qemuxml2argvdata/fd-memory-numa-topology.xml +index 05ea164..7e082eb 100644 +--- a/tests/qemuxml2argvdata/fd-memory-numa-topology.xml ++++ b/tests/qemuxml2argvdata/fd-memory-numa-topology.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/fd-memory-numa-topology2.xml b/tests/qemuxml2argvdata/fd-memory-numa-topology2.xml +index 904e64f..919b30a 100644 +--- a/tests/qemuxml2argvdata/fd-memory-numa-topology2.xml ++++ b/tests/qemuxml2argvdata/fd-memory-numa-topology2.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/fd-memory-numa-topology3.xml b/tests/qemuxml2argvdata/fd-memory-numa-topology3.xml +index 9785609..a429a27 100644 +--- a/tests/qemuxml2argvdata/fd-memory-numa-topology3.xml ++++ b/tests/qemuxml2argvdata/fd-memory-numa-topology3.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/hugepages-nvdimm.xml b/tests/qemuxml2argvdata/hugepages-nvdimm.xml +index 144d02b..f8a5a2f 100644 +--- a/tests/qemuxml2argvdata/hugepages-nvdimm.xml ++++ b/tests/qemuxml2argvdata/hugepages-nvdimm.xml +@@ -16,7 +16,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/memfd-memory-default-hugepage.xml b/tests/qemuxml2argvdata/memfd-memory-default-hugepage.xml +index 69d27ef..f3e155a 100644 +--- a/tests/qemuxml2argvdata/memfd-memory-default-hugepage.xml ++++ b/tests/qemuxml2argvdata/memfd-memory-default-hugepage.xml +@@ -18,7 +18,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/memfd-memory-numa.xml b/tests/qemuxml2argvdata/memfd-memory-numa.xml +index e3d5d92..ed814a0 100644 +--- a/tests/qemuxml2argvdata/memfd-memory-numa.xml ++++ b/tests/qemuxml2argvdata/memfd-memory-numa.xml +@@ -20,7 +20,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.xml +index a1cc126..5e74f58 100644 +--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.xml ++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-access.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.xml +index 018a693..c1de357 100644 +--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.xml ++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-align.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.xml +index c9d54a6..db0d67e 100644 +--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.xml ++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-label.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.xml +index 391d70f..bfa1589 100644 +--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.xml ++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-pmem.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.xml +index 09b2c5c..bff89db 100644 +--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.xml ++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm-readonly.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2argvdata/memory-hotplug-nvdimm.xml b/tests/qemuxml2argvdata/memory-hotplug-nvdimm.xml +index a32474d..827a7ca 100644 +--- a/tests/qemuxml2argvdata/memory-hotplug-nvdimm.xml ++++ b/tests/qemuxml2argvdata/memory-hotplug-nvdimm.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/cpu-numa-disjoint.xml b/tests/qemuxml2xmloutdata/cpu-numa-disjoint.xml +index d7f5372..2e4c53c 100644 +--- a/tests/qemuxml2xmloutdata/cpu-numa-disjoint.xml ++++ b/tests/qemuxml2xmloutdata/cpu-numa-disjoint.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/cpu-numa-disordered.xml b/tests/qemuxml2xmloutdata/cpu-numa-disordered.xml +index 487ced1..e5979c3 100644 +--- a/tests/qemuxml2xmloutdata/cpu-numa-disordered.xml ++++ b/tests/qemuxml2xmloutdata/cpu-numa-disordered.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/cpu-numa-memshared.xml b/tests/qemuxml2xmloutdata/cpu-numa-memshared.xml +index f472bff..f4af5be 100644 +--- a/tests/qemuxml2xmloutdata/cpu-numa-memshared.xml ++++ b/tests/qemuxml2xmloutdata/cpu-numa-memshared.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/cpu-numa-no-memory-element.xml b/tests/qemuxml2xmloutdata/cpu-numa-no-memory-element.xml +index 2ef7f84..d583f86 100644 +--- a/tests/qemuxml2xmloutdata/cpu-numa-no-memory-element.xml ++++ b/tests/qemuxml2xmloutdata/cpu-numa-no-memory-element.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/cpu-numa1.xml b/tests/qemuxml2xmloutdata/cpu-numa1.xml +index 2ef7f84..d583f86 100644 +--- a/tests/qemuxml2xmloutdata/cpu-numa1.xml ++++ b/tests/qemuxml2xmloutdata/cpu-numa1.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/cpu-numa2.xml b/tests/qemuxml2xmloutdata/cpu-numa2.xml +index 2ef7f84..d583f86 100644 +--- a/tests/qemuxml2xmloutdata/cpu-numa2.xml ++++ b/tests/qemuxml2xmloutdata/cpu-numa2.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/fd-memory-no-numa-topology.xml b/tests/qemuxml2xmloutdata/fd-memory-no-numa-topology.xml +index 0749952..d9e20d4 100644 +--- a/tests/qemuxml2xmloutdata/fd-memory-no-numa-topology.xml ++++ b/tests/qemuxml2xmloutdata/fd-memory-no-numa-topology.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuxml2xmloutdata/fd-memory-numa-topology.xml b/tests/qemuxml2xmloutdata/fd-memory-numa-topology.xml +index 05ea164..7e082eb 100644 +--- a/tests/qemuxml2xmloutdata/fd-memory-numa-topology.xml ++++ b/tests/qemuxml2xmloutdata/fd-memory-numa-topology.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/fd-memory-numa-topology2.xml b/tests/qemuxml2xmloutdata/fd-memory-numa-topology2.xml +index 904e64f..919b30a 100644 +--- a/tests/qemuxml2xmloutdata/fd-memory-numa-topology2.xml ++++ b/tests/qemuxml2xmloutdata/fd-memory-numa-topology2.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/fd-memory-numa-topology3.xml b/tests/qemuxml2xmloutdata/fd-memory-numa-topology3.xml +index 9785609..a429a27 100644 +--- a/tests/qemuxml2xmloutdata/fd-memory-numa-topology3.xml ++++ b/tests/qemuxml2xmloutdata/fd-memory-numa-topology3.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/graphics-spice-timeout.xml b/tests/qemuxml2xmloutdata/graphics-spice-timeout.xml +index 6e23652..f7a7c87 100644 +--- a/tests/qemuxml2xmloutdata/graphics-spice-timeout.xml ++++ b/tests/qemuxml2xmloutdata/graphics-spice-timeout.xml +@@ -18,7 +18,7 @@ + + core2duo + Intel +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/hugepages-nvdimm.xml b/tests/qemuxml2xmloutdata/hugepages-nvdimm.xml +index 144d02b..f8a5a2f 100644 +--- a/tests/qemuxml2xmloutdata/hugepages-nvdimm.xml ++++ b/tests/qemuxml2xmloutdata/hugepages-nvdimm.xml +@@ -16,7 +16,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memfd-memory-default-hugepage.xml b/tests/qemuxml2xmloutdata/memfd-memory-default-hugepage.xml +index 69d27ef..f3e155a 100644 +--- a/tests/qemuxml2xmloutdata/memfd-memory-default-hugepage.xml ++++ b/tests/qemuxml2xmloutdata/memfd-memory-default-hugepage.xml +@@ -18,7 +18,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memfd-memory-numa.xml b/tests/qemuxml2xmloutdata/memfd-memory-numa.xml +index e3d5d92..ed814a0 100644 +--- a/tests/qemuxml2xmloutdata/memfd-memory-numa.xml ++++ b/tests/qemuxml2xmloutdata/memfd-memory-numa.xml +@@ -20,7 +20,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-dimm.xml b/tests/qemuxml2xmloutdata/memory-hotplug-dimm.xml +index 326b5c9..378b262 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug-dimm.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug-dimm.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-access.xml b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-access.xml +index a1cc126..5e74f58 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-access.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-access.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-align.xml b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-align.xml +index 018a693..c1de357 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-align.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-align.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-label.xml b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-label.xml +index c9d54a6..db0d67e 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-label.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-label.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-pmem.xml b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-pmem.xml +index 391d70f..bfa1589 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-pmem.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-pmem.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-ppc64.xml b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-ppc64.xml +index ae5a17d..e90b462 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-ppc64.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-ppc64.xml +@@ -10,7 +10,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-readonly.xml b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-readonly.xml +index 09b2c5c..bff89db 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-readonly.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm-readonly.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm.xml b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm.xml +index a32474d..827a7ca 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug-nvdimm.xml +@@ -14,7 +14,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug.xml b/tests/qemuxml2xmloutdata/memory-hotplug.xml +index 0e5295d..547f613 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug.xml +@@ -10,7 +10,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-cpuset.xml b/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-cpuset.xml +index 841ea69..f438a7c 100644 +--- a/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-cpuset.xml ++++ b/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-cpuset.xml +@@ -12,7 +12,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml b/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml +index 2e3998e..4d37383 100644 +--- a/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml ++++ b/tests/qemuxml2xmloutdata/numad-auto-memory-vcpu-no-cpuset-and-placement.xml +@@ -12,7 +12,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuxml2xmloutdata/numad-auto-vcpu-no-numatune.xml b/tests/qemuxml2xmloutdata/numad-auto-vcpu-no-numatune.xml +index 7c1f18c..051606f 100644 +--- a/tests/qemuxml2xmloutdata/numad-auto-vcpu-no-numatune.xml ++++ b/tests/qemuxml2xmloutdata/numad-auto-vcpu-no-numatune.xml +@@ -12,7 +12,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuxml2xmloutdata/numad-static-vcpu-no-numatune.xml b/tests/qemuxml2xmloutdata/numad-static-vcpu-no-numatune.xml +index 3d05790..2479852 100644 +--- a/tests/qemuxml2xmloutdata/numad-static-vcpu-no-numatune.xml ++++ b/tests/qemuxml2xmloutdata/numad-static-vcpu-no-numatune.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/qemuxml2xmloutdata/pci-expander-bus.xml b/tests/qemuxml2xmloutdata/pci-expander-bus.xml +index 60e4e4a..6f8103b 100644 +--- a/tests/qemuxml2xmloutdata/pci-expander-bus.xml ++++ b/tests/qemuxml2xmloutdata/pci-expander-bus.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/pcie-expander-bus.xml b/tests/qemuxml2xmloutdata/pcie-expander-bus.xml +index 452d476..80d5ece 100644 +--- a/tests/qemuxml2xmloutdata/pcie-expander-bus.xml ++++ b/tests/qemuxml2xmloutdata/pcie-expander-bus.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/pseries-phb-numa-node.xml b/tests/qemuxml2xmloutdata/pseries-phb-numa-node.xml +index b05ac33..35c0e18 100644 +--- a/tests/qemuxml2xmloutdata/pseries-phb-numa-node.xml ++++ b/tests/qemuxml2xmloutdata/pseries-phb-numa-node.xml +@@ -13,7 +13,7 @@ + + + +- ++ + + + +diff --git a/tests/qemuxml2xmloutdata/smp.xml b/tests/qemuxml2xmloutdata/smp.xml +index 3e00f57..0816d5f 100644 +--- a/tests/qemuxml2xmloutdata/smp.xml ++++ b/tests/qemuxml2xmloutdata/smp.xml +@@ -9,7 +9,7 @@ + + + +- ++ + + + destroy +diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml +index 2011bfb..4b1a9d1 100644 +--- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml ++++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml +@@ -11,7 +11,7 @@ + hvm + + +- ++ + + + destroy +diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml +index fa428c1..f7b6eb6 100644 +--- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml ++++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-9.xml +@@ -12,7 +12,7 @@ + hvm + + +- ++ + + + destroy +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/cpu_topo-support-for-reporting-cluster_id-in-NUMA-to.patch b/generic_vdpa/libvirt/cpu_topo-support-for-reporting-cluster_id-in-NUMA-to.patch new file mode 100644 index 0000000..9a214ba --- /dev/null +++ b/generic_vdpa/libvirt/cpu_topo-support-for-reporting-cluster_id-in-NUMA-to.patch @@ -0,0 +1,522 @@ +From baa40f939ab38d80597651aec82779af25599bb0 Mon Sep 17 00:00:00 2001 +From: zhangxinhao +Date: Tue, 9 May 2023 23:28:59 +0800 +Subject: cpu_topo: support for reporting cluster_id in NUMA + topology + +Support report the die_id in the NUMA topology capabilities. + +Signed-off-by: zhangxinhao +--- + docs/schemas/capability.rng | 3 ++ + src/conf/capabilities.c | 4 ++- + src/conf/capabilities.h | 1 + + src/libvirt_linux.syms | 1 + + src/util/virhostcpu.c | 22 +++++++++++++ + src/util/virhostcpu.h | 1 + + .../vircaps2xmldata/vircaps-aarch64-basic.xml | 32 +++++++++---------- + .../vircaps-x86_64-basic-dies.xml | 24 +++++++------- + .../vircaps2xmldata/vircaps-x86_64-basic.xml | 32 +++++++++---------- + .../vircaps2xmldata/vircaps-x86_64-caches.xml | 16 +++++----- + .../vircaps-x86_64-resctrl-cdp.xml | 24 +++++++------- + .../vircaps-x86_64-resctrl-cmt.xml | 24 +++++++------- + .../vircaps-x86_64-resctrl-fake-feature.xml | 24 +++++++------- + .../vircaps-x86_64-resctrl-skx-twocaches.xml | 2 +- + .../vircaps-x86_64-resctrl-skx.xml | 2 +- + .../vircaps-x86_64-resctrl.xml | 24 +++++++------- + 16 files changed, 133 insertions(+), 103 deletions(-) + +diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng +index 031c55bf20..f5b37d8c18 100644 +--- a/docs/schemas/capability.rng ++++ b/docs/schemas/capability.rng +@@ -268,6 +268,9 @@ + + + ++ ++ ++ + + + +diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c +index 12c8c3a324..3c3a66a78a 100644 +--- a/src/conf/capabilities.c ++++ b/src/conf/capabilities.c +@@ -874,9 +874,10 @@ virCapabilitiesHostNUMAFormat(virCapsHostNUMAPtr caps, + return -1; + + virBufferAsprintf(buf, +- " socket_id='%d' die_id='%d' core_id='%d' siblings='%s'", ++ " socket_id='%d' die_id='%d' cluster_id='%d' core_id='%d' siblings='%s'", + cell->cpus[j].socket_id, + cell->cpus[j].die_id, ++ cell->cpus[j].cluster_id, + cell->cpus[j].core_id, + siblings); + VIR_FREE(siblings); +@@ -1465,6 +1466,7 @@ virCapabilitiesFillCPUInfo(int cpu_id G_GNUC_UNUSED, + + if (virHostCPUGetSocket(cpu_id, &cpu->socket_id) < 0 || + virHostCPUGetDie(cpu_id, &cpu->die_id) < 0 || ++ virHostCPUGetCluster(cpu_id, &cpu->cluster_id) < 0 || + virHostCPUGetCore(cpu_id, &cpu->core_id) < 0) + return -1; + +diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h +index e2581fac8b..f88bb412b5 100644 +--- a/src/conf/capabilities.h ++++ b/src/conf/capabilities.h +@@ -89,6 +89,7 @@ struct _virCapsHostNUMACellCPU { + unsigned int id; + unsigned int socket_id; + unsigned int die_id; ++ unsigned int cluster_id; + unsigned int core_id; + virBitmapPtr siblings; + }; +diff --git a/src/libvirt_linux.syms b/src/libvirt_linux.syms +index 55649ae39c..004cbfee97 100644 +--- a/src/libvirt_linux.syms ++++ b/src/libvirt_linux.syms +@@ -3,6 +3,7 @@ + # + + # util/virhostcpu.h ++virHostCPUGetCluster; + virHostCPUGetCore; + virHostCPUGetDie; + virHostCPUGetInfoPopulateLinux; +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index 8c8fc3a476..d2ac31e784 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -240,6 +240,28 @@ virHostCPUGetDie(unsigned int cpu, unsigned int *die) + return 0; + } + ++int ++virHostCPUGetCluster(unsigned int cpu, unsigned int *cluster) ++{ ++ int cluster_id; ++ int ret = virFileReadValueInt(&cluster_id, ++ "%s/cpu/cpu%u/topology/cluster_id", ++ SYSFS_SYSTEM_PATH, cpu); ++ if (ret == -1) ++ return -1; ++ ++ /* If the file is not there, it's 0. ++ * Another alternative is cluster_id set to -1, meaning that ++ * the arch does not have cluster_id support. Set @cluster to ++ * 0 in this case too. */ ++ if (ret == -2 || cluster_id < 0) ++ cluster_id = 0; ++ ++ *cluster = cluster_id; ++ ++ return 0; ++} ++ + int + virHostCPUGetCore(unsigned int cpu, unsigned int *core) + { +diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h +index 9be2e51a38..e3a04c2eeb 100644 +--- a/src/util/virhostcpu.h ++++ b/src/util/virhostcpu.h +@@ -66,6 +66,7 @@ int virHostCPUStatsAssign(virNodeCPUStatsPtr param, + #ifdef __linux__ + int virHostCPUGetSocket(unsigned int cpu, unsigned int *socket); + int virHostCPUGetDie(unsigned int cpu, unsigned int *die); ++int virHostCPUGetCluster(unsigned int cpu, unsigned int *cluster); + int virHostCPUGetCore(unsigned int cpu, unsigned int *core); + + virBitmapPtr virHostCPUGetSiblingsList(unsigned int cpu); +diff --git a/tests/vircaps2xmldata/vircaps-aarch64-basic.xml b/tests/vircaps2xmldata/vircaps-aarch64-basic.xml +index 0a04052c40..5533ae0586 100644 +--- a/tests/vircaps2xmldata/vircaps-aarch64-basic.xml ++++ b/tests/vircaps2xmldata/vircaps-aarch64-basic.xml +@@ -16,10 +16,10 @@ + 4096 + 6144 + +- +- +- +- ++ ++ ++ ++ + + + +@@ -28,10 +28,10 @@ + 6144 + 8192 + +- +- +- +- ++ ++ ++ ++ + + + +@@ -40,10 +40,10 @@ + 8192 + 10240 + +- +- +- +- ++ ++ ++ ++ + + + +@@ -52,10 +52,10 @@ + 10240 + 12288 + +- +- +- +- ++ ++ ++ ++ + + + +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-basic-dies.xml b/tests/vircaps2xmldata/vircaps-x86_64-basic-dies.xml +index 8a3ca2d13c..c86dc4defc 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-basic-dies.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-basic-dies.xml +@@ -14,18 +14,18 @@ + 4096 + 6144 + +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-basic.xml b/tests/vircaps2xmldata/vircaps-x86_64-basic.xml +index 4da09f889c..9ae155d571 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-basic.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-basic.xml +@@ -14,10 +14,10 @@ + 4096 + 6144 + +- +- +- +- ++ ++ ++ ++ + + + +@@ -26,10 +26,10 @@ + 6144 + 8192 + +- +- +- +- ++ ++ ++ ++ + + + +@@ -38,10 +38,10 @@ + 8192 + 10240 + +- +- +- +- ++ ++ ++ ++ + + + +@@ -50,10 +50,10 @@ + 10240 + 12288 + +- +- +- +- ++ ++ ++ ++ + + + +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-caches.xml b/tests/vircaps2xmldata/vircaps-x86_64-caches.xml +index 28f00c0a90..05b33147b7 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-caches.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-caches.xml +@@ -17,14 +17,14 @@ + 4096 + 6144 + +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cdp.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cdp.xml +index ee26fe9464..167b217d8e 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cdp.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cdp.xml +@@ -17,12 +17,12 @@ + 4096 + 6144 + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +@@ -31,12 +31,12 @@ + 6144 + 8192 + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cmt.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cmt.xml +index acdd97ec58..311bb58e6a 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cmt.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-cmt.xml +@@ -17,12 +17,12 @@ + 4096 + 6144 + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +@@ -31,12 +31,12 @@ + 6144 + 8192 + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-fake-feature.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-fake-feature.xml +index 5f3678e072..8f64bcad63 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-fake-feature.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-fake-feature.xml +@@ -17,12 +17,12 @@ + 4096 + 6144 + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +@@ -31,12 +31,12 @@ + 6144 + 8192 + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx-twocaches.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx-twocaches.xml +index 6769bd0591..eb53eb2142 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx-twocaches.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx-twocaches.xml +@@ -17,7 +17,7 @@ + 4096 + 6144 + +- ++ + + + +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx.xml +index bc52480905..38ea0bdc27 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl-skx.xml +@@ -17,7 +17,7 @@ + 4096 + 6144 + +- ++ + + + +diff --git a/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml b/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml +index c386edd4b0..ea9e2613d7 100644 +--- a/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml ++++ b/tests/vircaps2xmldata/vircaps-x86_64-resctrl.xml +@@ -17,12 +17,12 @@ + 4096 + 6144 + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +@@ -31,12 +31,12 @@ + 6144 + 8192 + +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ + + + +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/cpu_topo-support-for-specifying-clusters-in-qemu-com.patch b/generic_vdpa/libvirt/cpu_topo-support-for-specifying-clusters-in-qemu-com.patch new file mode 100644 index 0000000..08c5cc8 --- /dev/null +++ b/generic_vdpa/libvirt/cpu_topo-support-for-specifying-clusters-in-qemu-com.patch @@ -0,0 +1,163 @@ +From 2e275763162623b59b1872a16c0c9f0f3837f530 Mon Sep 17 00:00:00 2001 +From: zhangxinhao +Date: Tue, 9 May 2023 23:01:36 +0800 +Subject: cpu_topo: support for specifying "clusters" in qemu + comand + +Support for cpu topology "clusters" for qemu command parameter "-smp". + +Signed-off-by: zhangxinhao +--- + src/qemu/qemu_capabilities.c | 2 ++ + src/qemu/qemu_capabilities.h | 1 + + src/qemu/qemu_command.c | 7 ++--- + tests/qemuxml2argvdata/smp-clusters.args | 30 +++++++++++++++++++++ + tests/qemuxml2argvdata/smp-clusters.xml | 33 ++++++++++++++++++++++++ + tests/qemuxml2argvtest.c | 1 + + 6 files changed, 69 insertions(+), 5 deletions(-) + create mode 100644 tests/qemuxml2argvdata/smp-clusters.args + create mode 100644 tests/qemuxml2argvdata/smp-clusters.xml + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 21b477cd4d..19030b2040 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -579,6 +579,7 @@ VIR_ENUM_IMPL(virQEMUCaps, + /* 365 */ + "calc-dirty-rate", + "dirtyrate-param.mode", ++ "smp-clusters", + ); + + +@@ -3218,6 +3219,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = { + { "chardev", "fd", QEMU_CAPS_CHARDEV_FD_PASS }, + { "overcommit", NULL, QEMU_CAPS_OVERCOMMIT }, + { "smp-opts", "dies", QEMU_CAPS_SMP_DIES }, ++ { "smp-opts", "clusters", QEMU_CAPS_SMP_CLUSTERS }, + }; + + static int +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 00682eb52c..43507760c8 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -560,6 +560,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + /* 365 */ + QEMU_CAPS_CALC_DIRTY_RATE, /* accepts calc-dirty-rate */ + QEMU_CAPS_DIRTYRATE_MODE , /* calc-dirty-rate accepts mode parameter */ ++ QEMU_CAPS_SMP_CLUSTERS, /* -smp clusters= */ + + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 85f95b41c3..dc7fb871e7 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -7335,14 +7335,11 @@ qemuBuildSmpCommandLine(virCommandPtr cmd, + _("Only 1 die per socket is supported")); + return -1; + } +- if (def->cpu->clusters != 1) { +- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +- _("Only 1 cluster per dies is supported")); +- return -1; +- } + virBufferAsprintf(&buf, ",sockets=%u", def->cpu->sockets); + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMP_DIES)) + virBufferAsprintf(&buf, ",dies=%u", def->cpu->dies); ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMP_CLUSTERS)) ++ virBufferAsprintf(&buf, ",clusters=%u", def->cpu->clusters); + virBufferAsprintf(&buf, ",cores=%u", def->cpu->cores); + virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads); + } else { +diff --git a/tests/qemuxml2argvdata/smp-clusters.args b/tests/qemuxml2argvdata/smp-clusters.args +new file mode 100644 +index 0000000000..ab91ad7218 +--- /dev/null ++++ b/tests/qemuxml2argvdata/smp-clusters.args +@@ -0,0 +1,30 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/tmp/lib/domain--1-QEMUGuest1 \ ++USER=test \ ++LOGNAME=test \ ++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ ++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ ++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-i386 \ ++-name QEMUGuest1 \ ++-S \ ++-machine pc,usb=off,dump-guest-core=off \ ++-accel tcg \ ++-m 214 \ ++-realtime mlock=off \ ++-smp 1,maxcpus=4,sockets=2,clusters=2,cores=1,threads=1 \ ++-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ ++server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-no-acpi \ ++-usb \ ++-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ ++-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 +diff --git a/tests/qemuxml2argvdata/smp-clusters.xml b/tests/qemuxml2argvdata/smp-clusters.xml +new file mode 100644 +index 0000000000..c1845b8213 +--- /dev/null ++++ b/tests/qemuxml2argvdata/smp-clusters.xml +@@ -0,0 +1,33 @@ ++ ++ QEMUGuest1 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 4 ++ ++ hvm ++ ++ ++ ++ ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index ec90532b5f..df62dfacb6 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1828,6 +1828,7 @@ mymain(void) + + DO_TEST("smp", NONE); + DO_TEST("smp-dies", QEMU_CAPS_SMP_DIES); ++ DO_TEST("smp-clusters", QEMU_CAPS_SMP_CLUSTERS); + + DO_TEST("iothreads", QEMU_CAPS_OBJECT_IOTHREAD); + DO_TEST("iothreads-ids", QEMU_CAPS_OBJECT_IOTHREAD); +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/disk-storage-fix-allocation-size-for-pool-format-dos.patch b/generic_vdpa/libvirt/disk-storage-fix-allocation-size-for-pool-format-dos.patch new file mode 100644 index 0000000..061ba4f --- /dev/null +++ b/generic_vdpa/libvirt/disk-storage-fix-allocation-size-for-pool-format-dos.patch @@ -0,0 +1,42 @@ +From 9e4751b3a9c0435c4cb199c353144acb55458473 Mon Sep 17 00:00:00 2001 +From: Sebastian Mitterle +Date: Sat, 29 Aug 2020 00:49:07 +0000 +Subject: [PATCH 027/108] disk storage: fix allocation size for pool format dos + +The changed condition was always false because the function was always +called with boundary values 0. + +Use the free extent's start value to get its start offset from the +cylinder boundary and determine if the needed size for allocation +needs to be expanded too in case the offset doesn't fit within extra +bytes for alignment. + +This fixes an issue where vol-create-from will call qemu-img convert +to create a destination volume of same capacity as the source volume +and qemu-img will error 'Cannot grow device files' due to the partition +being too small for the source although both destination partition and +source volume have the same capacity. + +Signed-off-by: Sebastian Mitterle +Reviewed-by: Michal Privoznik +(cherry picked from commit 653fdf48e352814efdbff72aa5421f65385088ac) +--- + src/storage/storage_backend_disk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c +index eae23ec24a..da06357b90 100644 +--- a/src/storage/storage_backend_disk.c ++++ b/src/storage/storage_backend_disk.c +@@ -691,7 +691,7 @@ virStorageBackendDiskPartBoundaries(virStoragePoolObjPtr pool, + if (def->source.format == VIR_STORAGE_POOL_DISK_DOS) { + /* align to cylinder boundary */ + neededSize += extraBytes; +- if ((*start % cylinderSize) > extraBytes) { ++ if ((dev->freeExtents[i].start % cylinderSize) > extraBytes) { + /* add an extra cylinder if the offset can't fit within + the extra bytes we have */ + neededSize += cylinderSize; +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/docs-Fix-template-matching-in-page.xsl.patch b/generic_vdpa/libvirt/docs-Fix-template-matching-in-page.xsl.patch new file mode 100644 index 0000000..29478d6 --- /dev/null +++ b/generic_vdpa/libvirt/docs-Fix-template-matching-in-page.xsl.patch @@ -0,0 +1,60 @@ +From 2fc51790318ec17fbca46185991fac8cc3302ec0 Mon Sep 17 00:00:00 2001 +From: Martin Kletzander +Date: Mon, 21 Feb 2022 09:26:13 +0100 +Subject: [PATCH] docs: Fix template matching in page.xsl + +Our last default template had a match of "node()" which incidentally matched +everything, including text nodes. Since this has the same priority according to +the XSLT spec, section 5.5: + + https://www.w3.org/TR/1999/REC-xslt-19991116#conflict + +this is an error. Also according to the same spec section, the XSLT processor +may signal the error or pick the last rule. + +This was uncovered with libxslt 1.1.35 which contains the following commit: + + https://gitlab.gnome.org/GNOME/libxslt/-/commit/b0074eeca3c6b21b4da14fdf712b853900c51635 + +which makes the build fail with: + + runtime error: file ../docs/page.xsl line 223 element element + xsl:element: The effective name '' is not a valid QName. + +because our last rule also matches text nodes and we are trying to extract the +node name out of them. + +To fix this we change the match to "*" which only matches elements and not all +the nodes, and to avoid any possible errors with different XSLT processors we +also bump the priority of the match="text()" rule a little higher, just in case +someone needs to use an XSLT processor that chooses signalling the error instead +of the optional recovery. + +https://bugs.gentoo.org/833586 + +Signed-off-by: Martin Kletzander +--- + docs/page.xsl | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/docs/page.xsl b/docs/page.xsl +index ddae5ab508..5dc46329fd 100644 +--- a/docs/page.xsl ++++ b/docs/page.xsl +@@ -194,11 +194,11 @@ + + + +- ++ + + + +- ++ + + + +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/docs-build-Don-t-include-stylesheet-in-intermediate-.patch b/generic_vdpa/libvirt/docs-build-Don-t-include-stylesheet-in-intermediate-.patch new file mode 100644 index 0000000..b13d5e0 --- /dev/null +++ b/generic_vdpa/libvirt/docs-build-Don-t-include-stylesheet-in-intermediate-.patch @@ -0,0 +1,62 @@ +From c99e7e8abe1e22f504173a976a82e1a72551bdc1 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 3 Aug 2020 07:32:29 +0200 +Subject: [PATCH] docs: build: Don't include stylesheet in intermediate html + files generated from RST +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +'docutils' add a stylesheet to the output html file for direct +consumption. Since we use the html files just as an intermediate step +which is post-processed to add our own stylesheet and drop the docutils +one in the process we can ask 'rst2html' to not add any for an +intermediate file with less garbage. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +Signed-off-by: rpm-build +--- + docs/Makefile.am | 4 ++-- + docs/Makefile.in | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/docs/Makefile.am b/docs/Makefile.am +index 61862c4..4c44504 100644 +--- a/docs/Makefile.am ++++ b/docs/Makefile.am +@@ -420,11 +420,11 @@ manpages/%.html.in: manpages/%.rst + grep -v '^:Manual ' < $< | \ + sed -e 's|SYSCONFDIR|$(sysconfdir)|g' \ + -e 's|RUNSTATEDIR|$(runstatedir)|g' | \ +- $(RST2HTML) --strict > $@ || { rm $@ && exit 1; } ++ $(RST2HTML) --stylesheet= --strict > $@ || { rm $@ && exit 1; } + + %.html.in: %.rst + $(AM_V_GEN)$(MKDIR_P) `dirname $@` && \ +- $(RST2HTML) --strict $< > $@ || { rm $@ && exit 1; } ++ $(RST2HTML) --stylesheet= --strict $< > $@ || { rm $@ && exit 1; } + + %.html.tmp: %.html.in site.xsl subsite.xsl page.xsl \ + $(acl_generated) +diff --git a/docs/Makefile.in b/docs/Makefile.in +index 61eac52..1836655 100644 +--- a/docs/Makefile.in ++++ b/docs/Makefile.in +@@ -1469,11 +1469,11 @@ manpages/%.html.in: manpages/%.rst + grep -v '^:Manual ' < $< | \ + sed -e 's|SYSCONFDIR|$(sysconfdir)|g' \ + -e 's|RUNSTATEDIR|$(runstatedir)|g' | \ +- $(RST2HTML) --strict > $@ || { rm $@ && exit 1; } ++ $(RST2HTML) --stylesheet= --strict > $@ || { rm $@ && exit 1; } + + %.html.in: %.rst + $(AM_V_GEN)$(MKDIR_P) `dirname $@` && \ +- $(RST2HTML) --strict $< > $@ || { rm $@ && exit 1; } ++ $(RST2HTML) --stylesheet= --strict $< > $@ || { rm $@ && exit 1; } + + %.html.tmp: %.html.in site.xsl subsite.xsl page.xsl \ + $(acl_generated) +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/docs-introduces-new-vhostuser-disk-type.patch b/generic_vdpa/libvirt/docs-introduces-new-vhostuser-disk-type.patch new file mode 100644 index 0000000..f083253 --- /dev/null +++ b/generic_vdpa/libvirt/docs-introduces-new-vhostuser-disk-type.patch @@ -0,0 +1,149 @@ +From 0b8ff5672665c3792c27c02d9d05e0951c03d440 Mon Sep 17 00:00:00 2001 +From: Luo Yifan +Date: Wed, 30 Nov 2022 18:13:36 +0800 +Subject: [PATCH 14/24] docs: introduces new vhostuser disk type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + + + + + + + + +Signed-off-by: Pavel Hrdina +Reviewed-by: Ján Tomko +Reviewed-by: Peter Krempa +(cherry picked from commit e88bdaf789b6f1cc5347b217240f15afd86a94c1) +Signed-off-by: Luo Yifan +--- + docs/formatdomain.html.in | 51 ++++++++++++++++++++++++++++++++++- + docs/schemas/domaincommon.rng | 19 +++++++++++++ + 2 files changed, 69 insertions(+), 1 deletion(-) + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index aaeb05961f..5860ec9f20 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -2977,6 +2977,13 @@ + </source> + <target dev='vde' bus='virtio'/> + </disk> ++ <disk type='vhostuser' device='disk'> ++ <driver name='qemu' type='raw'/> ++ <source type='unix' path='/tmp/vhost-blk.sock'> ++ <reconnect enabled='yes' timeout='10'/> ++ </source> ++ <target dev='vdf' bus='virtio'/> ++ </disk> + </devices> + ... + +@@ -2991,7 +2998,8 @@ + "dir" (since 0.7.5), + "network" (since 0.8.7), or + "volume" (since 1.0.5), or +- "nvme" (since 6.0.0) ++ "nvme" (since 6.0.0), or ++ "vhostuser" (since 6.2.0) + and refer to the underlying source for the disk. + Since 0.0.3 +
+@@ -3217,6 +3225,31 @@ + <disk type='block'> and therefore lower + latencies can be achieved. + ++
vhostuser
++
++ Enables the hypervisor to connect to another process using vhost-user ++ protocol. Requires shared memory configured for the VM, for more details ++ see access mode for ++ memoryBacking <#elementsMemoryBacking> element. ++ ++ The source element has following mandatory attributes: ++
++
type
++
The type of char device. Currently only unix type ++ is supported. ++
++ ++
path
++
Path to the unix socket to be used as disk source. ++
++
++ ++ Note that the vhost server replaces both the disk frontend and backend ++ thus almost all of the disk properties can't be configured via the ++ <disk> XML for this disk type. Additionally features ++ such as blockjobs, incremental backups and snapshots are not supported ++ for this disk type. ++
+ + With "file", "block", and "volume", one or more optional + sub-elements seclabel, described +@@ -3424,6 +3457,22 @@ + Note that '0' is considered as if the value is not provided. + Since 6.2.0 + ++
reconnect
++
++ For disk type vhostuser configures reconnect timeout ++ if the connection is lost. It has two mandatory attributes: ++
++
enabled
++
If the reconnect feature is enabled, acceptsyes ++ and no ++
++ ++
timeout
++
The amount of seconds after which hypervisor tries to reconnect. ++
++
++ Since 6.2.0 ++
+ + +

+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index 1807df521c..764f826df4 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -1631,6 +1631,7 @@ + + + ++ + + + +@@ -2103,6 +2104,24 @@ + + + ++ ++ ++ vhostuser ++ ++ ++ ++ unix ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + (ioemu:)?(fd|hd|sd|vd|xvd|ubd)[a-zA-Z0-9_]+ +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/domain-add-logs-for-virDomainHotpatchManage.patch b/generic_vdpa/libvirt/domain-add-logs-for-virDomainHotpatchManage.patch new file mode 100644 index 0000000..ef63bf4 --- /dev/null +++ b/generic_vdpa/libvirt/domain-add-logs-for-virDomainHotpatchManage.patch @@ -0,0 +1,45 @@ +From e59b2064ffefbc94c729d38ec0180197e2b1f8ed Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Mon, 12 Jul 2021 21:28:41 +0800 +Subject: [PATCH] domain: add logs for virDomainHotpatchManage + +Add logs for virDomainHotpatchManage to facilitate the location of +issues related to subsequent hotpatch. + +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + src/libvirt-domain.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index 068ab52f54..3cf6bcb3b4 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -12777,12 +12777,21 @@ virDomainHotpatchManage(virDomainPtr domain, + if (action == VIR_DOMAIN_HOTPATCH_UNAPPLY) + virCheckNonNullArgGoto(id, error); + ++ VIR_INFO("enter virDomainHotpatchManage domainname=%s, action=%d, " ++ "patch=%s, id=%s, flags=%d", ++ NULLSTR(domain->name), action, ++ NULLSTR(patch), NULLSTR(id), flags); ++ + if (conn->driver->domainHotpatchManage) { + char *ret; + ret = conn->driver->domainHotpatchManage(domain, action, patch, id, flags); +- if (!ret) ++ if (!ret) { ++ VIR_ERROR("domain %s managed hotpatch failed", ++ NULLSTR(domain->name)); + goto error; +- ++ } ++ VIR_INFO("domain %s managed hotpatch successfully", ++ NULLSTR(domain->name)); + return ret; + } + +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/domain_capabilities-Assert-enums-fit-into-unsigned-i.patch b/generic_vdpa/libvirt/domain_capabilities-Assert-enums-fit-into-unsigned-i.patch new file mode 100644 index 0000000..db0eadb --- /dev/null +++ b/generic_vdpa/libvirt/domain_capabilities-Assert-enums-fit-into-unsigned-i.patch @@ -0,0 +1,121 @@ +From 11073a79e7c7275436a43a43dd6b6e772b05588f Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Wed, 18 Nov 2020 11:58:01 +0100 +Subject: [PATCH 066/108] domain_capabilities: Assert enums fit into unsigned + int bitmask + +The way our domain capabilities work currently, is that we have +virDomainCapsEnum struct which contains 'unsigned int values' +member which serves as a bitmask. More complicated structs are +composed from this struct, giving us whole virDomainCaps +eventually. + +Whenever we want to report that a certain value is supported, the +'1 << value' bit is set in the corresponding unsigned int member. +This works as long as the resulting value after bitshift does not +overflow unsigned int. There is a check inside +virDomainCapsEnumSet() which ensures exactly this, but no caller +really checks whether virDomainCapsEnumSet() succeeded. Also, +checking at runtime is a bit too late. + +Fortunately, we know the largest value we want to store in each +member, because each enum of ours ends with _LAST member. +Therefore, we can check at build time whether an overflow can +occur. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit 912421e7b63a358d552b79fac62a5518ec58f4e5) +--- + src/conf/domain_capabilities.h | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h +index 9f4a23d015..0345c84855 100644 +--- a/src/conf/domain_capabilities.h ++++ b/src/conf/domain_capabilities.h +@@ -36,6 +36,9 @@ struct _virDomainCapsEnum { + unsigned int values; /* Bitmask of values supported in the corresponding enum */ + }; + ++#define STATIC_ASSERT_ENUM(last) \ ++ G_STATIC_ASSERT(last <= sizeof(unsigned int) * CHAR_BIT) ++ + typedef struct _virDomainCapsStringValues virDomainCapsStringValues; + typedef virDomainCapsStringValues *virDomainCapsStringValuesPtr; + struct _virDomainCapsStringValues { +@@ -43,6 +46,8 @@ struct _virDomainCapsStringValues { + size_t nvalues; /* number of strings */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_LOADER_TYPE_LAST); ++STATIC_ASSERT_ENUM(VIR_TRISTATE_BOOL_LAST); + typedef struct _virDomainCapsLoader virDomainCapsLoader; + typedef virDomainCapsLoader *virDomainCapsLoaderPtr; + struct _virDomainCapsLoader { +@@ -53,6 +58,7 @@ struct _virDomainCapsLoader { + virDomainCapsEnum secure; /* Info about secure:virTristateBool */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_OS_DEF_FIRMWARE_LAST); + typedef struct _virDomainCapsOS virDomainCapsOS; + typedef virDomainCapsOS *virDomainCapsOSPtr; + struct _virDomainCapsOS { +@@ -61,6 +67,9 @@ struct _virDomainCapsOS { + virDomainCapsLoader loader; /* Info about virDomainLoaderDef */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_DISK_DEVICE_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_DISK_BUS_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_DISK_MODEL_LAST); + typedef struct _virDomainCapsDeviceDisk virDomainCapsDeviceDisk; + typedef virDomainCapsDeviceDisk *virDomainCapsDeviceDiskPtr; + struct _virDomainCapsDeviceDisk { +@@ -71,6 +80,7 @@ struct _virDomainCapsDeviceDisk { + /* add new fields here */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_GRAPHICS_TYPE_LAST); + typedef struct _virDomainCapsDeviceGraphics virDomainCapsDeviceGraphics; + typedef virDomainCapsDeviceGraphics *virDomainCapsDeviceGraphicsPtr; + struct _virDomainCapsDeviceGraphics { +@@ -78,6 +88,7 @@ struct _virDomainCapsDeviceGraphics { + virDomainCapsEnum type; /* virDomainGraphicsType */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_VIDEO_TYPE_LAST); + typedef struct _virDomainCapsDeviceVideo virDomainCapsDeviceVideo; + typedef virDomainCapsDeviceVideo *virDomainCapsDeviceVideoPtr; + struct _virDomainCapsDeviceVideo { +@@ -85,6 +96,11 @@ struct _virDomainCapsDeviceVideo { + virDomainCapsEnum modelType; /* virDomainVideoType */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_MODE_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_STARTUP_POLICY_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_CAPS_TYPE_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST); + typedef struct _virDomainCapsDeviceHostdev virDomainCapsDeviceHostdev; + typedef virDomainCapsDeviceHostdev *virDomainCapsDeviceHostdevPtr; + struct _virDomainCapsDeviceHostdev { +@@ -97,6 +113,8 @@ struct _virDomainCapsDeviceHostdev { + /* add new fields here */ + }; + ++STATIC_ASSERT_ENUM(VIR_DOMAIN_RNG_MODEL_LAST); ++STATIC_ASSERT_ENUM(VIR_DOMAIN_RNG_BACKEND_LAST); + typedef struct _virDomainCapsDeviceRNG virDomainCapsDeviceRNG; + typedef virDomainCapsDeviceRNG *virDomainCapsDeviceRNGPtr; + struct _virDomainCapsDeviceRNG { +@@ -105,6 +123,7 @@ struct _virDomainCapsDeviceRNG { + virDomainCapsEnum backendModel; /* virDomainRNGBackend */ + }; + ++STATIC_ASSERT_ENUM(VIR_GIC_VERSION_LAST); + typedef struct _virDomainCapsFeatureGIC virDomainCapsFeatureGIC; + typedef virDomainCapsFeatureGIC *virDomainCapsFeatureGICPtr; + struct _virDomainCapsFeatureGIC { +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/domain_cgroup.c-update-domain-after-setting-blkio.we.patch b/generic_vdpa/libvirt/domain_cgroup.c-update-domain-after-setting-blkio.we.patch new file mode 100644 index 0000000..c7e8c4d --- /dev/null +++ b/generic_vdpa/libvirt/domain_cgroup.c-update-domain-after-setting-blkio.we.patch @@ -0,0 +1,48 @@ +From da99b4e69fab6a14f55873a0b27f962ed6ed5f11 Mon Sep 17 00:00:00 2001 +From: Daniel Henrique Barboza +Date: Mon, 22 Mar 2021 16:28:59 -0300 +Subject: [PATCH 091/108] domain_cgroup.c: update domain after setting + blkio.weight +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit ac87d3520ad5 consolidated common cgroup code between the QEMU and +lxc drivers in domain_cgroup.c. In this process, in +virDomainCgroupSetupDomainBlkioParameters(), a call to +virCgroupGetBlkioWeight() went missing. + +The result is that 'virsh blkiotune' is setting the blkio.weight for the +guest in the host cgroup, but not on the domain XML, because +virCgroupGetBlkioWeight() is also used to write the blkio.weight value +in the domain object. + +Fix it by adding the virCgroupGetBlkioWeight() call in the +virDomainCgroupSetupDomainBlkioParameters() helper. + +Fixes: ac87d3520ad542d558854a72b0ae0a81fddc6747 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1941407 +Reviewed-by: Ján Tomko +Signed-off-by: Daniel Henrique Barboza +(cherry picked from commit e2602f2bb186da100116a5668d95ca829b7f2767) +--- + src/hypervisor/domain_cgroup.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/hypervisor/domain_cgroup.c b/src/hypervisor/domain_cgroup.c +index eb4fa20a9e..05e3aa7e6a 100644 +--- a/src/hypervisor/domain_cgroup.c ++++ b/src/hypervisor/domain_cgroup.c +@@ -104,7 +104,8 @@ virDomainCgroupSetupDomainBlkioParameters(virCgroupPtr cgroup, + virTypedParameterPtr param = ¶ms[i]; + + if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) { +- if (virCgroupSetBlkioWeight(cgroup, params[i].value.ui) < 0) ++ if (virCgroupSetBlkioWeight(cgroup, params[i].value.ui) < 0 || ++ virCgroupGetBlkioWeight(cgroup, &def->blkio.weight) < 0) + ret = -1; + } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT) || + STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS) || +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/domain_conf-fix-NULL-dereference-on-error-in-virDoma.patch b/generic_vdpa/libvirt/domain_conf-fix-NULL-dereference-on-error-in-virDoma.patch new file mode 100644 index 0000000..8806010 --- /dev/null +++ b/generic_vdpa/libvirt/domain_conf-fix-NULL-dereference-on-error-in-virDoma.patch @@ -0,0 +1,40 @@ +From 5862d4429c3c3b813b46c32830800df34c6dafe0 Mon Sep 17 00:00:00 2001 +From: Pavel Hrdina +Date: Wed, 11 Mar 2020 13:25:59 +0100 +Subject: [PATCH 074/108] domain_conf: fix NULL dereference on error in + virDomainObjCopyPersistentDef + +The issue was introduced together with the function itself by commit +. Calling +`virDomainObjGetPersistentDef` may return NULL which is later passed +to `virDomainDefFormat` where the `def` attribute is marked as NONNULL +and later in `virDomainDefFormatInternalSetRootName` it is actually +defererenced without any other check. + +Signed-off-by: Pavel Hrdina +Reviewed-by: Peter Krempa +(cherry picked from commit b96174d9f2dcf0197bb6e58eea3fbbda17043478) +--- + src/conf/domain_conf.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 9c83f4e347..b60b9d31a1 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -30074,6 +30074,12 @@ virDomainObjCopyPersistentDef(virDomainObjPtr dom, + virDomainDefPtr cur; + + cur = virDomainObjGetPersistentDef(xmlopt, dom, parseOpaque); ++ if (!cur) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("failed to get persistent definition object")); ++ return NULL; ++ } ++ + return virDomainDefCopy(cur, xmlopt, parseOpaque, false); + } + +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/domain_conf.c-do-not-leak-video-in-virDomainDefParse.patch b/generic_vdpa/libvirt/domain_conf.c-do-not-leak-video-in-virDomainDefParse.patch new file mode 100644 index 0000000..084a3f7 --- /dev/null +++ b/generic_vdpa/libvirt/domain_conf.c-do-not-leak-video-in-virDomainDefParse.patch @@ -0,0 +1,65 @@ +From fbb537ad89c6820e8763a57722cebc5a3db363e0 Mon Sep 17 00:00:00 2001 +From: Daniel Henrique Barboza +Date: Thu, 19 Nov 2020 13:57:43 -0300 +Subject: [PATCH 067/108] domain_conf.c: do not leak 'video' in + virDomainDefParseXML() + +The 'video' pointer is only being freed on error path, meaning +that we're leaking it after each loop restart. + +There are more opportunities for auto cleanups of virDomainVideoDef +pointers, so let's register AUTOPTR_CLEANUP_FUNC for it to use +g_autoptr() later on. + +Reviewed-by: Michal Privoznik +Signed-off-by: Daniel Henrique Barboza +(cherry picked from commit 18d29844c616fb633f7042dbe4cf80819cdd2f1d) +--- + src/conf/domain_conf.c | 4 +--- + src/conf/domain_conf.h | 1 + + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index d3565ececf..a33f9144f5 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -21631,7 +21631,7 @@ virDomainDefParseXML(xmlDocPtr xml, + if (n && VIR_ALLOC_N(def->videos, n) < 0) + goto error; + for (i = 0; i < n; i++) { +- virDomainVideoDefPtr video; ++ g_autoptr(virDomainVideoDef) video = NULL; + ssize_t insertAt = -1; + + if (!(video = virDomainVideoDefParseXML(xmlopt, nodes[i], +@@ -21640,7 +21640,6 @@ virDomainDefParseXML(xmlDocPtr xml, + + if (video->primary) { + if (def->nvideos != 0 && def->videos[0]->primary) { +- virDomainVideoDefFree(video); + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only one primary video device is supported")); + goto error; +@@ -21652,7 +21651,6 @@ virDomainDefParseXML(xmlDocPtr xml, + insertAt, + def->nvideos, + video) < 0) { +- virDomainVideoDefFree(video); + goto error; + } + } +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index e057c384c6..15b9e79d69 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2938,6 +2938,7 @@ void virDomainNVRAMDefFree(virDomainNVRAMDefPtr def); + void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def); + virDomainVideoDefPtr virDomainVideoDefNew(virDomainXMLOptionPtr xmlopt); + void virDomainVideoDefFree(virDomainVideoDefPtr def); ++G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVideoDef, virDomainVideoDefFree); + void virDomainVideoDefClear(virDomainVideoDefPtr def); + virDomainHostdevDefPtr virDomainHostdevDefNew(void); + void virDomainHostdevDefClear(virDomainHostdevDefPtr def); +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/enum-Add-helpers-for-converting-virTristate-to-a-pla.patch b/generic_vdpa/libvirt/enum-Add-helpers-for-converting-virTristate-to-a-pla.patch new file mode 100644 index 0000000..78c611b --- /dev/null +++ b/generic_vdpa/libvirt/enum-Add-helpers-for-converting-virTristate-to-a-pla.patch @@ -0,0 +1,125 @@ +From 04c5fee85547da11323b66b2fb79fb590e8307a1 Mon Sep 17 00:00:00 2001 +From: jiangdawei15 +Date: Thu, 18 Aug 2022 20:15:54 +0800 +Subject: [PATCH 22/22] enum: Add helpers for converting virTristate* to a + plain bool +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The helpers will update the passed boolean if the tristate's value is +not _ABSENT. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +--- + src/libvirt_private.syms | 2 ++ + src/util/virenum.c | 54 ++++++++++++++++++++++++++++++++++++++++ + src/util/virenum.h | 2 ++ + 3 files changed, 58 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index f30eb7ffb5..a00e354859 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1965,9 +1965,11 @@ ebtablesRemoveForwardAllowIn; + virEnumFromString; + virEnumToString; + virTristateBoolFromBool; ++virTristateBoolToBool; + virTristateBoolTypeFromString; + virTristateBoolTypeToString; + virTristateSwitchFromBool; ++virTristateSwitchToBool; + virTristateSwitchTypeFromString; + virTristateSwitchTypeToString; + +diff --git a/src/util/virenum.c b/src/util/virenum.c +index 26093bd795..dfedc28ba7 100644 +--- a/src/util/virenum.c ++++ b/src/util/virenum.c +@@ -47,6 +47,33 @@ virTristateBoolFromBool(bool val) + } + + ++/** ++ * virTristateBoolToBool: The value pointed to by @b is ++ * updated if the tristate value @t is not absent. ++ * ++ * @t: a virTristateBool value ++ * @b: pointer to a boolean to be updated according to the value of @t ++ */ ++void ++virTristateBoolToBool(virTristateBool t, ++ bool *b) ++{ ++ switch (t) { ++ case VIR_TRISTATE_BOOL_YES: ++ *b = true; ++ break; ++ ++ case VIR_TRISTATE_BOOL_NO: ++ *b = false; ++ break; ++ ++ case VIR_TRISTATE_BOOL_ABSENT: ++ case VIR_TRISTATE_BOOL_LAST: ++ break; ++ } ++} ++ ++ + virTristateSwitch + virTristateSwitchFromBool(bool val) + { +@@ -57,6 +84,33 @@ virTristateSwitchFromBool(bool val) + } + + ++/** ++ * virTristateSwitchToBool: The value pointed to by @b ++ * is updated if the tristate value @t is not absent. ++ * ++ * @t: a virTristateSwitch value ++ * @b: pointer to a boolean to be updated according to the value of @t ++ */ ++void ++virTristateSwitchToBool(virTristateSwitch t, ++ bool *b) ++{ ++ switch (t) { ++ case VIR_TRISTATE_SWITCH_ON: ++ *b = true; ++ break; ++ ++ case VIR_TRISTATE_SWITCH_OFF: ++ *b = false; ++ break; ++ ++ case VIR_TRISTATE_SWITCH_ABSENT: ++ case VIR_TRISTATE_SWITCH_LAST: ++ break; ++ } ++} ++ ++ + int + virEnumFromString(const char * const *types, + unsigned int ntypes, +diff --git a/src/util/virenum.h b/src/util/virenum.h +index d74af35530..98f01d574d 100644 +--- a/src/util/virenum.h ++++ b/src/util/virenum.h +@@ -68,7 +68,9 @@ VIR_ENUM_DECL(virTristateBool); + VIR_ENUM_DECL(virTristateSwitch); + + virTristateBool virTristateBoolFromBool(bool val); ++void virTristateBoolToBool(virTristateBool t, bool *b); + virTristateSwitch virTristateSwitchFromBool(bool val); ++void virTristateSwitchToBool(virTristateSwitch t, bool *b); + + /* the two enums must be in sync to be able to use helpers interchangeably in + * some special cases */ +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/esx-call-freeaddrinfo-earlier-in-esxUtil_ResolveHost.patch b/generic_vdpa/libvirt/esx-call-freeaddrinfo-earlier-in-esxUtil_ResolveHost.patch new file mode 100644 index 0000000..ec36310 --- /dev/null +++ b/generic_vdpa/libvirt/esx-call-freeaddrinfo-earlier-in-esxUtil_ResolveHost.patch @@ -0,0 +1,42 @@ +From 9b80543fb6ebccf64d0bcbe91a2e97873886164c Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Thu, 16 Mar 2023 07:03:51 +0000 +Subject: [PATCH] esx: call freeaddrinfo earlier in esxUtil_ResolveHostname + Call freeaddrinfo() as soon as @result is not needed anymore, i.e. right + after getnameinfo(); this avoids calling freeaddrinfo() in two branches. + +Signed-off-by: Pino Toscano +Reviewed-by: Laine Stump + +Signed-off-by: tangbin +(cherry-pick from 3aaf23ff69cea9abb7b7a43d9ff3eb687a916a2e) +--- + src/esx/esx_util.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c +index 89d136248f..98ce462ff0 100644 +--- a/src/esx/esx_util.c ++++ b/src/esx/esx_util.c +@@ -311,17 +311,15 @@ esxUtil_ResolveHostname(const char *hostname, + + errcode = getnameinfo(result->ai_addr, result->ai_addrlen, ipAddress, + ipAddress_length, NULL, 0, NI_NUMERICHOST); ++ freeaddrinfo(result); + + if (errcode != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Formatting IP address for host '%s' failed: %s"), hostname, + gai_strerror(errcode)); +- freeaddrinfo(result); + return -1; + } + +- freeaddrinfo(result); +- + return 0; + } + +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/examples-hellolibvirt-fix-argc-check.patch b/generic_vdpa/libvirt/examples-hellolibvirt-fix-argc-check.patch new file mode 100644 index 0000000..7b56c05 --- /dev/null +++ b/generic_vdpa/libvirt/examples-hellolibvirt-fix-argc-check.patch @@ -0,0 +1,41 @@ +From 7a13a72308b5ad5887497e13995522ab151e6293 Mon Sep 17 00:00:00 2001 +From: wangmeiyang +Date: Wed, 30 Nov 2022 19:47:10 +0800 +Subject: [PATCH 20/24] examples: hellolibvirt: fix argc check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +https://gitlab.com/libvirt/libvirt/-/issues/255 + +cherry-pick from dacf616b788a989ecaa1679845a07ff8010372cf + +Reported-by: Jeremy Alcim +Signed-off-by: Ján Tomko +Signed-off-by: Meiyang Wang +--- + examples/c/misc/hellolibvirt.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/examples/c/misc/hellolibvirt.c b/examples/c/misc/hellolibvirt.c +index a598e01be2..39cefe934c 100644 +--- a/examples/c/misc/hellolibvirt.c ++++ b/examples/c/misc/hellolibvirt.c +@@ -107,11 +107,12 @@ main(int argc, char *argv[]) + { + int ret = 0; + virConnectPtr conn; +- char *uri; ++ char *uri = NULL; + + printf("Attempting to connect to hypervisor\n"); + +- uri = (argc > 0 ? argv[1] : NULL); ++ if (argc > 1) ++ uri = argv[1]; + + /* virConnectOpenAuth is called here with all default parameters, + * except, possibly, the URI of the hypervisor. */ +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/fix-error-in-printf-format-string.patch b/generic_vdpa/libvirt/fix-error-in-printf-format-string.patch new file mode 100644 index 0000000..78edba3 --- /dev/null +++ b/generic_vdpa/libvirt/fix-error-in-printf-format-string.patch @@ -0,0 +1,32 @@ +From 56dc1a61719f5133b30676afe71c4d1482c84476 Mon Sep 17 00:00:00 2001 +From: Zhenyu Ye +Date: Thu, 19 Aug 2021 20:14:11 +0800 +Subject: [PATCH] fix error in printf format string + +Use %s to print NULLSTR(duri). + +Reported-by: Peng Liang +Signed-off-by: Zhenyu Ye +Reviewed-by: Michal Privoznik +Signed-off-by: zhujun2 +(cherry-pick from 94ac9d55fd9067326c483372c858bb4233826880) +--- + src/libvirt-domain.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index 6ce4a6715c..8f6ff2fe22 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -4086,7 +4086,7 @@ virDomainMigrateToURI(virDomainPtr domain, + const char *dconnuri = NULL; + const char *miguri = NULL; + +- VIR_DOMAIN_DEBUG(domain, "duri=%p, flags=0x%lx, dname=%s, bandwidth=%lu", ++ VIR_DOMAIN_DEBUG(domain, "duri=%s, flags=0x%lx, dname=%s, bandwidth=%lu", + NULLSTR(duri), flags, NULLSTR(dname), bandwidth); + + virResetLastError(); +-- +2.41.0.windows.1 + diff --git a/generic_vdpa/libvirt/fix-the-issue-of-errors-when-saving-after-virsh-edit.patch b/generic_vdpa/libvirt/fix-the-issue-of-errors-when-saving-after-virsh-edit.patch new file mode 100644 index 0000000..7a0e38a --- /dev/null +++ b/generic_vdpa/libvirt/fix-the-issue-of-errors-when-saving-after-virsh-edit.patch @@ -0,0 +1,24 @@ +From d5c1bd627d522b16eb87e2684a912c16ce79c12b Mon Sep 17 00:00:00 2001 +From: lifeng 71117973 +Date: Mon, 15 May 2023 15:39:32 +0800 +Subject: [PATCH] fix the issue of errors when saving after 'virsh edit' + +--- + docs/schemas/basictypes.rng | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng +index 34d285db48..8b430e71a6 100644 +--- a/docs/schemas/basictypes.rng ++++ b/docs/schemas/basictypes.rng +@@ -440,6 +440,7 @@ + sh4eb + sparc + sparc64 ++ sw_64 + unicore32 + x86_64 + xtensa +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/glibcompat-Provide-implementation-for-G_GNUC_NO_INLI.patch b/generic_vdpa/libvirt/glibcompat-Provide-implementation-for-G_GNUC_NO_INLI.patch new file mode 100644 index 0000000..2c6042f --- /dev/null +++ b/generic_vdpa/libvirt/glibcompat-Provide-implementation-for-G_GNUC_NO_INLI.patch @@ -0,0 +1,70 @@ +From 1ac928729853d29d030944ece5e10db69d54267d Mon Sep 17 00:00:00 2001 +From: mayunlong +Date: Tue, 14 Feb 2023 19:09:08 +0800 +Subject: [PATCH] glibcompat: Provide implementation for G_GNUC_NO_INLINE + +Currently, we require glib-2.56.0 at minimum (because of RHEL-8) +but we use G_GNUC_NO_INLINE which was introduced in 2.58.0. While +we provide an implementation for older versions, where the macro +does not exists, it's a bit more tricky than that. Since we +define GLIB_VERSION_MAX_ALLOWED we would get a compile time error +when trying to use something too new, except for G_GNUC_NO_INLINE +which was intentionally not marked as +GLIB_AVAILABLE_MACRO_IN_2_58. But this is about to change with +glib-2.73.2 (which contains commit [1]). + +At the same time, we can't just bump glib and thus we have to +provide an alternative implementation without the version +annotation. + +1: https://gitlab.gnome.org/GNOME/glib/-/commit/a6f8fe071e44b0145619c21f3bfbc90c56ab805e +Signed-off-by: Michal Privoznik +Reviewed-by: Pavel Hrdina +--- + src/internal.h | 12 ------------ + src/util/glibcompat.h | 9 +++++++++ + 2 files changed, 9 insertions(+), 12 deletions(-) + +diff --git a/src/internal.h b/src/internal.h +index 302fddba34..440f01d370 100644 +--- a/src/internal.h ++++ b/src/internal.h +@@ -94,18 +94,6 @@ + # endif + #endif + +-/** +- * G_GNUC_NO_INLINE: +- * +- * Force compiler not to inline a method. Should be used if +- * the method need to be overridable by test mocks. +- * +- * TODO: Remove after upgrading to GLib >= 2.58 +- */ +-#ifndef G_GNUC_NO_INLINE +-# define G_GNUC_NO_INLINE __attribute__((__noinline__)) +-#endif +- + /** + * ATTRIBUTE_PACKED + * +diff --git a/src/util/glibcompat.h b/src/util/glibcompat.h +index 6f50a76f3c..15d3266686 100644 +--- a/src/util/glibcompat.h ++++ b/src/util/glibcompat.h +@@ -37,3 +37,12 @@ char *vir_g_strdup_vprintf(const char *msg, va_list args) + #define g_canonicalize_filename vir_g_canonicalize_filename + #undef g_fsync + #define g_fsync vir_g_fsync ++ ++/* Intentionally redefine macro so that it's not marked as available in 2.58 ++ * and newer. Drop when bumping to 2.58 or newer. */ ++#undef G_GNUC_NO_INLINE ++#if g_macro__has_attribute(__noinline__) ++# define G_GNUC_NO_INLINE __attribute__ ((__noinline__)) ++#else ++# define G_GNUC_NO_INLINE ++#endif +-- +2.25.1 + diff --git a/generic_vdpa/libvirt/hostdev-Update-mdev-pointer-reference-after-checking.patch b/generic_vdpa/libvirt/hostdev-Update-mdev-pointer-reference-after-checking.patch new file mode 100644 index 0000000..b49c96d --- /dev/null +++ b/generic_vdpa/libvirt/hostdev-Update-mdev-pointer-reference-after-checking.patch @@ -0,0 +1,45 @@ +From 24ae6a276d538a31f42feb5e988d15b08b444b4a Mon Sep 17 00:00:00 2001 +From: Erik Skultety +Date: Thu, 7 Jan 2021 16:48:40 +0100 +Subject: [PATCH 078/108] hostdev: Update mdev pointer reference after checking + device type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We set the pointer to some garbage packed structure data without +knowing whether we were actually handling the type of device we +expected to be handling. On its own, this was harmless, because we'd +never use the pointer as we'd skip the device if it were not the +expected type. However, it's better to make the logic even more +explicit - we first check the device and only when we're sure we have +the expected type we then update the pointer shortcut. + +Signed-off-by: Erik Skultety +Reviewed-by: Ján Tomko +(cherry picked from commit 964738cff3d949d90fc5c3317a2618fcd8d217b4) +--- + src/hypervisor/virhostdev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c +index 9017cc3be8..c88c8bee0e 100644 +--- a/src/hypervisor/virhostdev.c ++++ b/src/hypervisor/virhostdev.c +@@ -1986,11 +1986,11 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr, + virDomainHostdevSubsysMediatedDevPtr mdevsrc; + virDomainHostdevDefPtr hostdev = hostdevs[i]; + +- mdevsrc = &hostdev->source.subsys.u.mdev; +- + if (!virHostdevIsMdevDevice(hostdev)) + continue; + ++ mdevsrc = &hostdev->source.subsys.u.mdev; ++ + if (!(mdev = virMediatedDeviceNew(mdevsrc->uuidstr, + mdevsrc->model))) + continue; +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-.patch b/generic_vdpa/libvirt/hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-.patch new file mode 100644 index 0000000..44953b3 --- /dev/null +++ b/generic_vdpa/libvirt/hostdev-mdev-Lookup-mdevs-by-sysfs-path-rather-than-.patch @@ -0,0 +1,161 @@ +From 7b752336bd26048514d55bb222531c0b0183fa9c Mon Sep 17 00:00:00 2001 +From: Erik Skultety +Date: Thu, 7 Jan 2021 16:53:21 +0100 +Subject: [PATCH 079/108] hostdev: mdev: Lookup mdevs by sysfs path rather than + mdev struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The lookup didn't do anything apart from comparing the sysfs paths +anyway since that's what makes each mdev unique. +The most ridiculous usage of the old logic was in +virHostdevReAttachMediatedDevices where in order to drop an mdev +hostdev from the list of active devices we first had to create a new +mdev and use it in the lookup call. Why couldn't we have used the +hostdev directly? Because the hostdev and mdev structures are +incompatible. + +The way mdevs are currently removed is via a write to a specific sysfs +attribute. If you do it while the machine which has the mdev assigned +is running, the write call may block (with a new enough kernel, with +older kernels it would return a write error!) until the device +is no longer in use which is when the QEMU process exits. + +The interesting part here comes afterwards when we're cleaning up and +call virHostdevReAttachMediatedDevices. The domain doesn't exist +anymore, so the list of active hostdevs needs to be updated and the +respective hostdevs removed from the list, but remember we had to +create an mdev object in the memory in order to find it in the list +first which will fail because the write to sysfs had already removed +the mdev instance from the host system. +And so the next time you try to start the same domain you'll get: + +"Requested operation is not valid: mediated device is in use by +driver QEMU, domain " + +Fixes: https://gitlab.com/libvirt/libvirt/-/issues/119 + +Signed-off-by: Erik Skultety +Reviewed-by: Ján Tomko +(cherry picked from commit 49cb59778a4e6c2d04bb9383a9d97fbbc83f9fce) +--- + src/hypervisor/virhostdev.c | 10 ++++------ + src/util/virmdev.c | 16 ++++++++-------- + src/util/virmdev.h | 4 ++-- + 3 files changed, 14 insertions(+), 16 deletions(-) + +diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c +index c88c8bee0e..4057f7b25f 100644 +--- a/src/hypervisor/virhostdev.c ++++ b/src/hypervisor/virhostdev.c +@@ -1981,7 +1981,7 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr, + + virObjectLock(mgr->activeMediatedHostdevs); + for (i = 0; i < nhostdevs; i++) { +- g_autoptr(virMediatedDevice) mdev = NULL; ++ g_autofree char *sysfspath = NULL; + virMediatedDevicePtr tmp; + virDomainHostdevSubsysMediatedDevPtr mdevsrc; + virDomainHostdevDefPtr hostdev = hostdevs[i]; +@@ -1990,14 +1990,12 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr, + continue; + + mdevsrc = &hostdev->source.subsys.u.mdev; +- +- if (!(mdev = virMediatedDeviceNew(mdevsrc->uuidstr, +- mdevsrc->model))) +- continue; ++ sysfspath = virMediatedDeviceGetSysfsPath(mdevsrc->uuidstr); + + /* Remove from the list only mdevs assigned to @drv_name/@dom_name */ + +- tmp = virMediatedDeviceListFind(mgr->activeMediatedHostdevs, mdev); ++ tmp = virMediatedDeviceListFind(mgr->activeMediatedHostdevs, ++ sysfspath); + + /* skip inactive devices */ + if (!tmp) +diff --git a/src/util/virmdev.c b/src/util/virmdev.c +index c2499c0a20..bae4a7d2c1 100644 +--- a/src/util/virmdev.c ++++ b/src/util/virmdev.c +@@ -312,7 +312,7 @@ int + virMediatedDeviceListAdd(virMediatedDeviceListPtr list, + virMediatedDevicePtr *dev) + { +- if (virMediatedDeviceListFind(list, *dev)) { ++ if (virMediatedDeviceListFind(list, (*dev)->path)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("device %s is already in use"), (*dev)->path); + return -1; +@@ -358,7 +358,7 @@ virMediatedDevicePtr + virMediatedDeviceListSteal(virMediatedDeviceListPtr list, + virMediatedDevicePtr dev) + { +- int idx = virMediatedDeviceListFindIndex(list, dev); ++ int idx = virMediatedDeviceListFindIndex(list, dev->path); + + return virMediatedDeviceListStealIndex(list, idx); + } +@@ -374,13 +374,13 @@ virMediatedDeviceListDel(virMediatedDeviceListPtr list, + + int + virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev) ++ const char *sysfspath) + { + size_t i; + + for (i = 0; i < list->count; i++) { +- virMediatedDevicePtr other = list->devs[i]; +- if (STREQ(other->path, dev->path)) ++ virMediatedDevicePtr dev = list->devs[i]; ++ if (STREQ(sysfspath, dev->path)) + return i; + } + return -1; +@@ -389,11 +389,11 @@ virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list, + + virMediatedDevicePtr + virMediatedDeviceListFind(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev) ++ const char *sysfspath) + { + int idx; + +- if ((idx = virMediatedDeviceListFindIndex(list, dev)) >= 0) ++ if ((idx = virMediatedDeviceListFindIndex(list, sysfspath)) >= 0) + return list->devs[idx]; + else + return NULL; +@@ -407,7 +407,7 @@ virMediatedDeviceIsUsed(virMediatedDevicePtr dev, + const char *drvname, *domname; + virMediatedDevicePtr tmp = NULL; + +- if ((tmp = virMediatedDeviceListFind(list, dev))) { ++ if ((tmp = virMediatedDeviceListFind(list, dev->path))) { + virMediatedDeviceGetUsedBy(tmp, &drvname, &domname); + virReportError(VIR_ERR_OPERATION_INVALID, + _("mediated device %s is in use by " +diff --git a/src/util/virmdev.h b/src/util/virmdev.h +index 51f7f608a2..1d97f7d44f 100644 +--- a/src/util/virmdev.h ++++ b/src/util/virmdev.h +@@ -119,11 +119,11 @@ virMediatedDeviceListDel(virMediatedDeviceListPtr list, + + virMediatedDevicePtr + virMediatedDeviceListFind(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev); ++ const char *sysfspath); + + int + virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list, +- virMediatedDevicePtr dev); ++ const char *sysfspath); + + int + virMediatedDeviceListMarkDevices(virMediatedDeviceListPtr dst, +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/hotpatch-Implement-qemuDomainHotpatchManage.patch b/generic_vdpa/libvirt/hotpatch-Implement-qemuDomainHotpatchManage.patch new file mode 100644 index 0000000..79bcd38 --- /dev/null +++ b/generic_vdpa/libvirt/hotpatch-Implement-qemuDomainHotpatchManage.patch @@ -0,0 +1,336 @@ +From b255a024007eb236745b703586a2fed8bdedae6c Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Tue, 19 Oct 2021 22:11:45 +0800 +Subject: [PATCH] hotpatch: Implement qemuDomainHotpatchManage + +Signed-off-by: Hao Wang +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + src/qemu/Makefile.inc.am | 2 + + src/qemu/qemu_driver.c | 48 +++++++++++ + src/qemu/qemu_hotpatch.c | 182 +++++++++++++++++++++++++++++++++++++++ + src/qemu/qemu_hotpatch.h | 36 ++++++++ + 4 files changed, 268 insertions(+) + create mode 100644 src/qemu/qemu_hotpatch.c + create mode 100644 src/qemu/qemu_hotpatch.h + +diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am +index 51cd79879d..a1a8bfa17c 100644 +--- a/src/qemu/Makefile.inc.am ++++ b/src/qemu/Makefile.inc.am +@@ -73,6 +73,8 @@ QEMU_DRIVER_SOURCES = \ + qemu/qemu_checkpoint.h \ + qemu/qemu_backup.c \ + qemu/qemu_backup.h \ ++ qemu/qemu_hotpatch.c \ ++ qemu/qemu_hotpatch.h \ + $(NULL) + + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 5901f922bf..f6d99957a5 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -50,6 +50,7 @@ + #include "qemu_security.h" + #include "qemu_checkpoint.h" + #include "qemu_backup.h" ++#include "qemu_hotpatch.h" + + #include "virerror.h" + #include "virlog.h" +@@ -23171,6 +23172,52 @@ qemuDomainAgentSetResponseTimeout(virDomainPtr dom, + return ret; + } + ++static char * ++qemuDomainHotpatchManage(virDomainPtr domain, ++ int action, ++ const char *patch, ++ const char *id, ++ unsigned int flags) ++{ ++ virDomainObjPtr vm; ++ char *ret = NULL; ++ size_t len; ++ ++ virCheckFlags(0, NULL); ++ ++ if (!(vm = qemuDomainObjFromDomain(domain))) ++ goto cleanup; ++ ++ switch (action) { ++ case VIR_DOMAIN_HOTPATCH_APPLY: ++ ret = qemuDomainHotpatchApply(vm, patch); ++ break; ++ ++ case VIR_DOMAIN_HOTPATCH_UNAPPLY: ++ ret = qemuDomainHotpatchUnapply(vm, id); ++ break; ++ ++ case VIR_DOMAIN_HOTPATCH_QUERY: ++ ret = qemuDomainHotpatchQuery(vm); ++ break; ++ ++ default: ++ virReportError(VIR_ERR_OPERATION_INVALID, "%s", ++ _("Unknow hotpatch action")); ++ } ++ ++ if (!ret) ++ goto endjob; ++ ++ /* Wipeout redundant empty line */ ++ len = strlen(ret); ++ if (len > 0) ++ ret[len - 1] = '\0'; ++ ++ cleanup: ++ virDomainObjEndAPI(&vm); ++ return ret; ++} + + static virHypervisorDriver qemuHypervisorDriver = { + .name = QEMU_DRIVER_NAME, +@@ -23411,6 +23458,7 @@ static virHypervisorDriver qemuHypervisorDriver = { + .domainAgentSetResponseTimeout = qemuDomainAgentSetResponseTimeout, /* 5.10.0 */ + .domainBackupBegin = qemuDomainBackupBegin, /* 6.0.0 */ + .domainBackupGetXMLDesc = qemuDomainBackupGetXMLDesc, /* 6.0.0 */ ++ .domainHotpatchManage = qemuDomainHotpatchManage, /* 6.2.0 */ + }; + + +diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c +new file mode 100644 +index 0000000000..45796b3f24 +--- /dev/null ++++ b/src/qemu/qemu_hotpatch.c +@@ -0,0 +1,182 @@ ++/* ++ * huawei_qemu_hotpatch.h: huawei qemu hotpatch functions ++ * ++ * Copyright (C) 2021-2021 HUAWEI, Inc. ++ * ++ * 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 "viralloc.h" ++#include "virerror.h" ++#include "virfile.h" ++#include "virlog.h" ++#include "vircommand.h" ++#include "qemu/qemu_domain.h" ++#include "qemu_hotpatch.h" ++ ++#define LIBCARE_CTL "libcare-ctl" ++#define LIBCARE_ERROR_NUMBER 255 ++#define MAX_PATCHID_LEN 8 ++ ++#define VIR_FROM_THIS VIR_FROM_QEMU ++ ++VIR_LOG_INIT("qemu_hotpatch"); ++ ++char * ++qemuDomainHotpatchQuery(virDomainObjPtr vm) ++{ ++ g_autoptr(virCommand) cmd = NULL; ++ g_autofree char *binary = NULL; ++ char *output = NULL; ++ int ret = -1; ++ ++ if (!(binary = virFindFileInPath(LIBCARE_CTL))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, "%s", ++ _("Failed to find libcare-ctl command.")); ++ return NULL; ++ } ++ ++ cmd = virCommandNewArgList(binary, "info", "-p", NULL); ++ virCommandAddArgFormat(cmd, "%d", vm->pid); ++ virCommandSetOutputBuffer(cmd, &output); ++ ++ VIR_DEBUG("Querying hotpatch for domain %s. (%s info -p %d)", ++ vm->def->name, binary, vm->pid); ++ ++ if (virCommandRun(cmd, &ret) < 0) ++ goto error; ++ ++ if (ret == LIBCARE_ERROR_NUMBER) { ++ virReportError(VIR_ERR_OPERATION_FAILED, "%s", ++ _("Failed to execute libcare-ctl command.")); ++ goto error; ++ } ++ return output; ++ ++ error: ++ VIR_FREE(output); ++ return NULL; ++} ++ ++char * ++qemuDomainHotpatchApply(virDomainObjPtr vm, ++ const char *patch) ++{ ++ g_autoptr(virCommand) cmd = NULL; ++ g_autofree char *binary = NULL; ++ char *output = NULL; ++ int ret = -1; ++ ++ if (!patch || !virFileExists(patch)) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ "%s", _("Invalid hotpatch file.")); ++ return NULL; ++ } ++ ++ if (!(binary = virFindFileInPath(LIBCARE_CTL))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ "%s", _("Failed to find libcare-ctl command.")); ++ return NULL; ++ } ++ ++ cmd = virCommandNewArgList(binary, "patch", "-p", NULL); ++ virCommandAddArgFormat(cmd, "%d", vm->pid); ++ virCommandAddArgList(cmd, patch, NULL); ++ virCommandSetOutputBuffer(cmd, &output); ++ ++ VIR_DEBUG("Applying hotpatch for domain %s. (%s patch -p %d %s)", ++ vm->def->name, binary, vm->pid, patch); ++ ++ if (virCommandRun(cmd, &ret) < 0) ++ goto error; ++ ++ if (ret == LIBCARE_ERROR_NUMBER) { ++ virReportError(VIR_ERR_OPERATION_FAILED, "%s", ++ _("Failed to execute libcare-ctl command.")); ++ goto error; ++ } ++ return output; ++ ++ error: ++ VIR_FREE(output); ++ return NULL; ++} ++ ++static bool ++qemuDomainHotpatchIsPatchidValid(const char *id) ++{ ++ size_t len, i; ++ ++ if (!id) ++ return false; ++ ++ len = strlen(id); ++ if (len > MAX_PATCHID_LEN - 1) ++ return false; ++ ++ for (i = 0; i < len; i++) { ++ if (!g_ascii_isalnum(*(id + i))) ++ return false; ++ } ++ ++ return true; ++} ++ ++char * ++qemuDomainHotpatchUnapply(virDomainObjPtr vm, ++ const char *id) ++{ ++ g_autoptr(virCommand) cmd = NULL; ++ g_autofree char *binary = NULL; ++ char *output = NULL; ++ int ret = -1; ++ ++ if (!id || !qemuDomainHotpatchIsPatchidValid(id)) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ "%s", _("Invalid hotpatch id.")); ++ return NULL; ++ } ++ ++ if (!(binary = virFindFileInPath(LIBCARE_CTL))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ "%s", _("Failed to find libcare-ctl command.")); ++ return NULL; ++ } ++ ++ cmd = virCommandNewArgList(binary, "unpatch", "-p", NULL); ++ virCommandAddArgFormat(cmd, "%d", vm->pid); ++ virCommandAddArgList(cmd, "-i", id, NULL); ++ virCommandSetOutputBuffer(cmd, &output); ++ ++ VIR_DEBUG("Unapplying hotpatch for domain %s. (%s unpatch -p %d -i %s)", ++ vm->def->name, binary, vm->pid, id); ++ ++ if (virCommandRun(cmd, &ret) < 0) ++ goto error; ++ ++ if (ret == LIBCARE_ERROR_NUMBER) { ++ virReportError(VIR_ERR_OPERATION_FAILED, "%s", ++ _("Failed to execute libcare-ctl command.")); ++ goto error; ++ } ++ return output; ++ ++ error: ++ VIR_FREE(output); ++ return NULL; ++} +diff --git a/src/qemu/qemu_hotpatch.h b/src/qemu/qemu_hotpatch.h +new file mode 100644 +index 0000000000..4c84a57950 +--- /dev/null ++++ b/src/qemu/qemu_hotpatch.h +@@ -0,0 +1,36 @@ ++/* ++ * huawei_qemu_hotpatch.h: huawei qemu hotpatch functions ++ * ++ * Copyright (C) 2021-2021 HUAWEI, Inc. ++ * ++ * 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 ++ * . ++ * ++ */ ++ ++#pragma once ++ ++#include ++#include "qemu/qemu_conf.h" ++ ++char * ++qemuDomainHotpatchQuery(virDomainObjPtr vm); ++ ++char * ++qemuDomainHotpatchApply(virDomainObjPtr vm, ++ const char *patch); ++ ++char * ++qemuDomainHotpatchUnapply(virDomainObjPtr vm, ++ const char *id); +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch b/generic_vdpa/libvirt/hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch new file mode 100644 index 0000000..13d997c --- /dev/null +++ b/generic_vdpa/libvirt/hotpatch-check-vm-id-and-pid-before-using-hotpatch-a.patch @@ -0,0 +1,135 @@ +From 58121fbc3085296364e6b90bc16cb56eeaf36f77 Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Fri, 9 Jul 2021 10:50:07 +0800 +Subject: [PATCH] hotpatch: check vm id and pid before using hotpatch api + +Check if the vm is alive before using hotpatch api by calling +virDomainObjCheckActive() to check vm id and calling +qemuDomainHotpatchCheckPid() to check vm pid. + +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + src/qemu/qemu_driver.c | 3 +++ + src/qemu/qemu_hotpatch.c | 36 ++++++++++++++++++++++++++++++------ + 2 files changed, 33 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index d4c5f073bb..2b24881f75 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -23196,6 +23196,9 @@ qemuDomainHotpatchManage(virDomainPtr domain, + VIR_DOMAIN_JOB_OPERATION_HOTPATCH, 0) < 0) + goto cleanup; + ++ if (virDomainObjCheckActive(vm) < 0) ++ goto endjob; ++ + qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_DEFAULT_MASK); + + switch (action) { +diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c +index 45796b3f24..03e63c1341 100644 +--- a/src/qemu/qemu_hotpatch.c ++++ b/src/qemu/qemu_hotpatch.c +@@ -37,12 +37,25 @@ + + VIR_LOG_INIT("qemu_hotpatch"); + ++static int ++qemuDomainHotpatchCheckPid(pid_t pid) ++{ ++ if (pid <= 0) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ "%s", _("Invalid pid")); ++ return -1; ++ } ++ ++ return 0; ++} ++ + char * + qemuDomainHotpatchQuery(virDomainObjPtr vm) + { + g_autoptr(virCommand) cmd = NULL; + g_autofree char *binary = NULL; + char *output = NULL; ++ pid_t pid = vm->pid; + int ret = -1; + + if (!(binary = virFindFileInPath(LIBCARE_CTL))) { +@@ -51,12 +64,15 @@ qemuDomainHotpatchQuery(virDomainObjPtr vm) + return NULL; + } + ++ if (qemuDomainHotpatchCheckPid(pid) < 0) ++ return NULL; ++ + cmd = virCommandNewArgList(binary, "info", "-p", NULL); +- virCommandAddArgFormat(cmd, "%d", vm->pid); ++ virCommandAddArgFormat(cmd, "%d", pid); + virCommandSetOutputBuffer(cmd, &output); + + VIR_DEBUG("Querying hotpatch for domain %s. (%s info -p %d)", +- vm->def->name, binary, vm->pid); ++ vm->def->name, binary, pid); + + if (virCommandRun(cmd, &ret) < 0) + goto error; +@@ -80,6 +96,7 @@ qemuDomainHotpatchApply(virDomainObjPtr vm, + g_autoptr(virCommand) cmd = NULL; + g_autofree char *binary = NULL; + char *output = NULL; ++ pid_t pid = vm->pid; + int ret = -1; + + if (!patch || !virFileExists(patch)) { +@@ -94,13 +111,16 @@ qemuDomainHotpatchApply(virDomainObjPtr vm, + return NULL; + } + ++ if (qemuDomainHotpatchCheckPid(pid) < 0) ++ return NULL; ++ + cmd = virCommandNewArgList(binary, "patch", "-p", NULL); +- virCommandAddArgFormat(cmd, "%d", vm->pid); ++ virCommandAddArgFormat(cmd, "%d", pid); + virCommandAddArgList(cmd, patch, NULL); + virCommandSetOutputBuffer(cmd, &output); + + VIR_DEBUG("Applying hotpatch for domain %s. (%s patch -p %d %s)", +- vm->def->name, binary, vm->pid, patch); ++ vm->def->name, binary, pid, patch); + + if (virCommandRun(cmd, &ret) < 0) + goto error; +@@ -144,6 +164,7 @@ qemuDomainHotpatchUnapply(virDomainObjPtr vm, + g_autoptr(virCommand) cmd = NULL; + g_autofree char *binary = NULL; + char *output = NULL; ++ pid_t pid = vm->pid; + int ret = -1; + + if (!id || !qemuDomainHotpatchIsPatchidValid(id)) { +@@ -158,13 +179,16 @@ qemuDomainHotpatchUnapply(virDomainObjPtr vm, + return NULL; + } + ++ if (qemuDomainHotpatchCheckPid(pid) < 0) ++ return NULL; ++ + cmd = virCommandNewArgList(binary, "unpatch", "-p", NULL); +- virCommandAddArgFormat(cmd, "%d", vm->pid); ++ virCommandAddArgFormat(cmd, "%d", pid); + virCommandAddArgList(cmd, "-i", id, NULL); + virCommandSetOutputBuffer(cmd, &output); + + VIR_DEBUG("Unapplying hotpatch for domain %s. (%s unpatch -p %d -i %s)", +- vm->def->name, binary, vm->pid, id); ++ vm->def->name, binary, pid, id); + + if (virCommandRun(cmd, &ret) < 0) + goto error; +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/hotpatch-implement-hotpatch-virsh-api.patch b/generic_vdpa/libvirt/hotpatch-implement-hotpatch-virsh-api.patch new file mode 100644 index 0000000..552ae2d --- /dev/null +++ b/generic_vdpa/libvirt/hotpatch-implement-hotpatch-virsh-api.patch @@ -0,0 +1,110 @@ +From cf380e22898f70f5782bcea8b0d22027ff7d86af Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Wed, 20 Oct 2021 11:07:34 +0800 +Subject: [PATCH] hotpatch: implement hotpatch virsh api + +Signed-off-by: Hao Wang +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + tools/virsh-domain.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 78 insertions(+) + +diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c +index f643bd403e..813be4a0db 100644 +--- a/tools/virsh-domain.c ++++ b/tools/virsh-domain.c +@@ -14326,6 +14326,78 @@ cmdGuestInfo(vshControl *ctl, const vshCmd *cmd) + return ret; + } + ++/* ++ * "hotpatch" command ++ */ ++static const vshCmdInfo info_hotpatch[] = { ++ {.name = "help", ++ .data = N_("Manage hotpatch of a live domain") ++ }, ++ {.name = "desc", ++ .data = N_("Manage hotpatch of a live domain") ++ }, ++ {.name = NULL} ++}; ++ ++static const vshCmdOptDef opts_hotpatch[] = { ++ VIRSH_COMMON_OPT_DOMAIN_FULL(0), ++ {.name = "action", ++ .type = VSH_OT_DATA, ++ .flags = VSH_OFLAG_REQ, ++ .help = N_("hotpatch action, choose from , and ") ++ }, ++ {.name = "patch", ++ .type = VSH_OT_STRING, ++ .help = N_("the absolute path of the hotpatch file, mandatory when action=apply") ++ }, ++ {.name = "id", ++ .type = VSH_OT_STRING, ++ .help = N_("the unique id of the target patch, mandatory when action=unapply") ++ }, ++ {.name = NULL} ++}; ++ ++VIR_ENUM_DECL(virDomainHotpatchAction); ++VIR_ENUM_IMPL(virDomainHotpatchAction, ++ VIR_DOMAIN_HOTPATCH_LAST, ++ "none", ++ "apply", ++ "unapply", ++ "query"); ++ ++static bool ++cmdHotpatch(vshControl *ctl, ++ const vshCmd *cmd) ++{ ++ g_autoptr(virshDomain) dom = NULL; ++ const char *patch = NULL; ++ const char *id = NULL; ++ const char *actionstr = NULL; ++ int action = -1; ++ g_autofree char *ret = NULL; ++ ++ if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) ++ return false; ++ ++ if (vshCommandOptStringReq(ctl, cmd, "action", &actionstr) < 0) ++ return false; ++ ++ if (actionstr) ++ action = virDomainHotpatchActionTypeFromString(actionstr); ++ ++ if (vshCommandOptStringReq(ctl, cmd, "patch", &patch) < 0) ++ return false; ++ ++ if (vshCommandOptStringReq(ctl, cmd, "id", &id) < 0) ++ return false; ++ ++ if (!(ret = virDomainHotpatchManage(dom, action, patch, id, 0))) ++ return false; ++ ++ vshPrint(ctl, _("%s"), ret); ++ return true; ++} ++ + const vshCmdDef domManagementCmds[] = { + {.name = "attach-device", + .handler = cmdAttachDevice, +@@ -14953,5 +15025,11 @@ const vshCmdDef domManagementCmds[] = { + .info = info_guestinfo, + .flags = 0 + }, ++ {.name = "hotpatch", ++ .handler = cmdHotpatch, ++ .opts = opts_hotpatch, ++ .info = info_hotpatch, ++ .flags = 0 ++ }, + {.name = NULL} + }; +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/hotpatch-introduce-hotpatch-async-job-flag.patch b/generic_vdpa/libvirt/hotpatch-introduce-hotpatch-async-job-flag.patch new file mode 100644 index 0000000..24f1611 --- /dev/null +++ b/generic_vdpa/libvirt/hotpatch-introduce-hotpatch-async-job-flag.patch @@ -0,0 +1,155 @@ +From a83bb0dc19d7c92c200b9a234e120d16878eac19 Mon Sep 17 00:00:00 2001 +From: AlexChen +Date: Tue, 19 Oct 2021 22:41:24 +0800 +Subject: [PATCH] hotpatch: introduce hotpatch async job flag + +Signed-off-by: Hao Wang +Signed-off-by: Bihong Yu +Signed-off-by: AlexChen +--- + include/libvirt/libvirt-domain.h | 1 + + src/qemu/qemu_domain.c | 3 +++ + src/qemu/qemu_domain.h | 1 + + src/qemu/qemu_driver.c | 13 +++++++++++++ + src/qemu/qemu_migration.c | 2 ++ + src/qemu/qemu_process.c | 1 + + tools/virsh-domain.c | 1 + + 7 files changed, 22 insertions(+) + +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index f91061724b..2d6432cab2 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -3295,6 +3295,7 @@ typedef enum { + VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT = 7, + VIR_DOMAIN_JOB_OPERATION_DUMP = 8, + VIR_DOMAIN_JOB_OPERATION_BACKUP = 9, ++ VIR_DOMAIN_JOB_OPERATION_HOTPATCH = 10, + + # ifdef VIR_ENUM_SENTINELS + VIR_DOMAIN_JOB_OPERATION_LAST +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 5d35d49638..2351cac120 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -111,6 +111,7 @@ VIR_ENUM_IMPL(qemuDomainAsyncJob, + "snapshot", + "start", + "backup", ++ "hotpatch", + ); + + VIR_ENUM_IMPL(qemuDomainNamespace, +@@ -217,6 +218,7 @@ qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job, + case QEMU_ASYNC_JOB_START: + case QEMU_ASYNC_JOB_NONE: + case QEMU_ASYNC_JOB_BACKUP: ++ case QEMU_ASYNC_JOB_HOTPATCH: + G_GNUC_FALLTHROUGH; + case QEMU_ASYNC_JOB_LAST: + break; +@@ -243,6 +245,7 @@ qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job, + case QEMU_ASYNC_JOB_START: + case QEMU_ASYNC_JOB_NONE: + case QEMU_ASYNC_JOB_BACKUP: ++ case QEMU_ASYNC_JOB_HOTPATCH: + G_GNUC_FALLTHROUGH; + case QEMU_ASYNC_JOB_LAST: + break; +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index cf19f4d101..678ddab624 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -107,6 +107,7 @@ typedef enum { + QEMU_ASYNC_JOB_SNAPSHOT, + QEMU_ASYNC_JOB_START, + QEMU_ASYNC_JOB_BACKUP, ++ QEMU_ASYNC_JOB_HOTPATCH, + + QEMU_ASYNC_JOB_LAST + } qemuDomainAsyncJob; +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index f6d99957a5..d4c5f073bb 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -13866,6 +13866,9 @@ static int qemuDomainAbortJob(virDomainPtr dom) + ret = 0; + break; + ++ case QEMU_ASYNC_JOB_HOTPATCH: ++ break; ++ + case QEMU_ASYNC_JOB_LAST: + default: + virReportEnumRangeError(qemuDomainAsyncJob, priv->job.asyncJob); +@@ -23180,6 +23183,7 @@ qemuDomainHotpatchManage(virDomainPtr domain, + unsigned int flags) + { + virDomainObjPtr vm; ++ virQEMUDriverPtr driver = domain->conn->privateData; + char *ret = NULL; + size_t len; + +@@ -23188,6 +23192,12 @@ qemuDomainHotpatchManage(virDomainPtr domain, + if (!(vm = qemuDomainObjFromDomain(domain))) + goto cleanup; + ++ if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_HOTPATCH, ++ VIR_DOMAIN_JOB_OPERATION_HOTPATCH, 0) < 0) ++ goto cleanup; ++ ++ qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_DEFAULT_MASK); ++ + switch (action) { + case VIR_DOMAIN_HOTPATCH_APPLY: + ret = qemuDomainHotpatchApply(vm, patch); +@@ -23214,6 +23224,9 @@ qemuDomainHotpatchManage(virDomainPtr domain, + if (len > 0) + ret[len - 1] = '\0'; + ++ endjob: ++ qemuDomainObjEndAsyncJob(driver, vm); ++ + cleanup: + virDomainObjEndAPI(&vm); + return ret; +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 3f4627bd39..1665071eb3 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -1532,6 +1532,8 @@ qemuMigrationJobName(virDomainObjPtr vm) + return _("start job"); + case QEMU_ASYNC_JOB_BACKUP: + return _("backup job"); ++ case QEMU_ASYNC_JOB_HOTPATCH: ++ return _("hotpatch job"); + case QEMU_ASYNC_JOB_LAST: + default: + return _("job"); +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 9cf7242f31..818a72d8f9 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -3646,6 +3646,7 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver, + priv->job.current->started = now; + break; + ++ case QEMU_ASYNC_JOB_HOTPATCH: + case QEMU_ASYNC_JOB_NONE: + case QEMU_ASYNC_JOB_LAST: + break; +diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c +index 65d5c831ec..f643bd403e 100644 +--- a/tools/virsh-domain.c ++++ b/tools/virsh-domain.c +@@ -6167,6 +6167,7 @@ VIR_ENUM_IMPL(virshDomainJobOperation, + N_("Snapshot revert"), + N_("Dump"), + N_("Backup"), ++ N_("Hotpatch"), + ); + + static const char * +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/hotpatch-virsh-support-autoload-mode.patch b/generic_vdpa/libvirt/hotpatch-virsh-support-autoload-mode.patch new file mode 100644 index 0000000..2c95db6 --- /dev/null +++ b/generic_vdpa/libvirt/hotpatch-virsh-support-autoload-mode.patch @@ -0,0 +1,302 @@ +From 3be8bb571d13795c2824dd6d2089035a1be6cf57 Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Wed, 26 Jan 2022 15:18:10 +0800 +Subject: [PATCH] hotpatch: virsh support autoload mode + +--- + include/libvirt/libvirt-domain.h | 1 + + src/qemu/qemu_conf.c | 9 +++ + src/qemu/qemu_conf.h | 1 + + src/qemu/qemu_driver.c | 5 ++ + src/qemu/qemu_hotpatch.c | 122 +++++++++++++++++++++++++++++++ + src/qemu/qemu_hotpatch.h | 3 + + src/qemu/qemu_process.c | 6 ++ + tools/virsh-domain.c | 5 +- + 8 files changed, 150 insertions(+), 2 deletions(-) + +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index 2d6432cab2..4ab0c9c0b2 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -4997,6 +4997,7 @@ typedef enum { + VIR_DOMAIN_HOTPATCH_APPLY, /* Apply hotpatch */ + VIR_DOMAIN_HOTPATCH_UNAPPLY, /* Unapply hotpatch */ + VIR_DOMAIN_HOTPATCH_QUERY, /* Query hotpatch */ ++ VIR_DOMAIN_HOTPATCH_AUTOLOAD, /* Autoload hotpatch */ + + # ifdef VIR_ENUM_SENTINELS + VIR_DOMAIN_HOTPATCH_LAST +diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c +index 809e8fe526..bd96ccb78e 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -1006,6 +1006,12 @@ virQEMUDriverConfigLoadCapsFiltersEntry(virQEMUDriverConfigPtr cfg, + return 0; + } + ++static int ++virQEMUDriverConfigLoadHotpatchPathEntry(virQEMUDriverConfigPtr cfg, ++ virConfPtr conf) ++{ ++ return virConfGetValueString(conf, "hotpatch_path", &cfg->hotpatchPath); ++} + + int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, + const char *filename, +@@ -1078,6 +1084,9 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, + if (virQEMUDriverConfigLoadCapsFiltersEntry(cfg, conf) < 0) + return -1; + ++ if (virQEMUDriverConfigLoadHotpatchPathEntry(cfg, conf) < 0) ++ return -1; ++ + return 0; + } + +diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h +index 14f9b9e81e..f0124a0fe2 100644 +--- a/src/qemu/qemu_conf.h ++++ b/src/qemu/qemu_conf.h +@@ -220,6 +220,7 @@ struct _virQEMUDriverConfig { + gid_t swtpm_group; + + char **capabilityfilters; ++ char *hotpatchPath; + }; + + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virQEMUDriverConfig, virObjectUnref); +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 2b24881f75..37b2c4a2da 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -23186,6 +23186,7 @@ qemuDomainHotpatchManage(virDomainPtr domain, + virQEMUDriverPtr driver = domain->conn->privateData; + char *ret = NULL; + size_t len; ++ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + + virCheckFlags(0, NULL); + +@@ -23214,6 +23215,10 @@ qemuDomainHotpatchManage(virDomainPtr domain, + ret = qemuDomainHotpatchQuery(vm); + break; + ++ case VIR_DOMAIN_HOTPATCH_AUTOLOAD: ++ ret = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath); ++ break; ++ + default: + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("Unknow hotpatch action")); +diff --git a/src/qemu/qemu_hotpatch.c b/src/qemu/qemu_hotpatch.c +index 03e63c1341..02f511cc38 100644 +--- a/src/qemu/qemu_hotpatch.c ++++ b/src/qemu/qemu_hotpatch.c +@@ -25,6 +25,8 @@ + #include "virerror.h" + #include "virfile.h" + #include "virlog.h" ++#include "virbuffer.h" ++#include "virstring.h" + #include "vircommand.h" + #include "qemu/qemu_domain.h" + #include "qemu_hotpatch.h" +@@ -32,6 +34,7 @@ + #define LIBCARE_CTL "libcare-ctl" + #define LIBCARE_ERROR_NUMBER 255 + #define MAX_PATCHID_LEN 8 ++#define MAX_FILE_SIZE (1024*1024) + + #define VIR_FROM_THIS VIR_FROM_QEMU + +@@ -204,3 +207,122 @@ qemuDomainHotpatchUnapply(virDomainObjPtr vm, + VIR_FREE(output); + return NULL; + } ++ ++char * ++qemuDomainHotpatchAutoload(virDomainObjPtr vm, char *hotpatch_path) ++{ ++ VIR_AUTOSTRINGLIST applied_patches = NULL; ++ VIR_AUTOSTRINGLIST lines = NULL; ++ g_autofree char *applied_patch = NULL; ++ g_autofree char *libvirtd_conf = NULL; ++ g_autofree char *patch_conf = NULL; ++ g_autofree char *buf = NULL; ++ char *ret = NULL; ++ int i, j, len; ++ ++ if (hotpatch_path == NULL) { ++ virReportError(VIR_ERR_INVALID_ARG, "%s", ++ _("Invalid hotpatch path.")); ++ return NULL; ++ } ++ ++ /* get hotpatch info from Patch.conf */ ++ patch_conf = g_strdup_printf("%s/Patch.conf", hotpatch_path); ++ if ((len = virFileReadAll(patch_conf, MAX_FILE_SIZE, &buf)) < 0) { ++ virReportError(VIR_ERR_INVALID_ARG, "%s", ++ _("Failed to read Patch.conf file.")); ++ return NULL; ++ } ++ if (len > 0) ++ buf[len-1] = '\0'; ++ ++ lines = virStringSplit(buf, "\n", 0); ++ if (!lines) ++ return NULL; ++ ++ /* get domain hotpatch infomation */ ++ applied_patch = qemuDomainHotpatchQuery(vm); ++ if (!applied_patch) ++ return NULL; ++ ++ applied_patches = virStringSplit(applied_patch, "\n", 0); ++ if (!applied_patches) ++ return NULL; ++ ++ /* load all hotpatch which are listed in Patch.conf one by one */ ++ for (i = 0; lines[i] != NULL; i++) { ++ VIR_AUTOSTRINGLIST patch_info = NULL; ++ g_autofree char *kpatch_dir = NULL; ++ g_autofree char *file_path = NULL; ++ struct dirent *de; ++ DIR *dh; ++ int direrr; ++ ++ if (!strstr(lines[i], "QEMU-")) ++ continue; ++ ++ patch_info = virStringSplit(lines[i], " ", 0); ++ if (!patch_info) ++ continue; ++ ++ /* skip already applied patch */ ++ if (strstr(applied_patch, patch_info[2])) ++ continue; ++ ++ /* get the kpatch file name */ ++ kpatch_dir = g_strdup_printf("%s/%s", hotpatch_path, patch_info[1]); ++ if (!kpatch_dir || !virFileExists(kpatch_dir)) ++ return NULL; ++ ++ if (virDirOpen(&dh, kpatch_dir) < 0) ++ return NULL; ++ if ((direrr = virDirRead(dh, &de, kpatch_dir)) > 0) { ++ GStatBuf sb; ++ ++ file_path = g_strdup_printf("%s/%s", kpatch_dir, de->d_name); ++ if (g_lstat(file_path, &sb) < 0) { ++ virReportSystemError(errno, _("Cannot access '%s'"), ++ file_path); ++ VIR_DIR_CLOSE(dh); ++ return NULL; ++ } ++ } ++ VIR_DIR_CLOSE(dh); ++ ++ if (qemuDomainHotpatchApply(vm, file_path) == NULL) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("failed to apply the hotpatch.")); ++ return NULL; ++ } ++ } ++ ++ /* unload the hotpatch which are not listed in Patch.conf */ ++ for (i = 0; applied_patches[i] != NULL; i++) { ++ const char *patch_id = NULL; ++ bool is_need_unload = true; ++ ++ if (!strstr(applied_patches[i], "Patch id")) ++ continue; ++ ++ patch_id = strstr(applied_patches[i], ":") + 1; ++ virSkipSpaces(&patch_id); ++ ++ for (j = 0; lines[j] != NULL; j++) { ++ if (!strstr(lines[j], "QEMU-")) ++ continue; ++ if (strstr(lines[j], patch_id)) { ++ is_need_unload = false; ++ break; ++ } ++ } ++ if (is_need_unload == true) ++ if (qemuDomainHotpatchUnapply(vm, patch_id) == NULL) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("failed to unapply the hotpatch.")); ++ return NULL; ++ } ++ } ++ ++ ret = g_strdup_printf("Hotpatch autoload successfully.\n"); ++ return ret; ++} +diff --git a/src/qemu/qemu_hotpatch.h b/src/qemu/qemu_hotpatch.h +index 4c84a57950..8e0bfe348a 100644 +--- a/src/qemu/qemu_hotpatch.h ++++ b/src/qemu/qemu_hotpatch.h +@@ -34,3 +34,6 @@ qemuDomainHotpatchApply(virDomainObjPtr vm, + char * + qemuDomainHotpatchUnapply(virDomainObjPtr vm, + const char *id); ++ ++char * ++qemuDomainHotpatchAutoload(virDomainObjPtr vm, char *path_config); +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 818a72d8f9..24dd9f052c 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -59,6 +59,7 @@ + #include "qemu_firmware.h" + #include "qemu_backup.h" + #include "qemu_dbus.h" ++#include "qemu_hotpatch.h" + + #include "cpu/cpu.h" + #include "cpu/cpu_x86.h" +@@ -6684,6 +6685,7 @@ qemuProcessLaunch(virConnectPtr conn, + g_autoptr(virQEMUDriverConfig) cfg = NULL; + size_t nnicindexes = 0; + g_autofree int *nicindexes = NULL; ++ g_autofree char *autoLoadStatus = NULL; + size_t i; + + VIR_DEBUG("conn=%p driver=%p vm=%p name=%s if=%d asyncJob=%d " +@@ -6993,6 +6995,10 @@ qemuProcessLaunch(virConnectPtr conn, + qemuProcessAutoDestroyAdd(driver, vm, conn) < 0) + goto cleanup; + ++ /* Autoload hotpatch */ ++ if ((autoLoadStatus = qemuDomainHotpatchAutoload(vm, cfg->hotpatchPath)) == NULL) { ++ VIR_WARN("Failed to autoload the hotpatch for %s.", vm->def->name); ++ } + ret = 0; + + cleanup: +diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c +index 813be4a0db..b5375ebd3e 100644 +--- a/tools/virsh-domain.c ++++ b/tools/virsh-domain.c +@@ -14344,7 +14344,7 @@ static const vshCmdOptDef opts_hotpatch[] = { + {.name = "action", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, +- .help = N_("hotpatch action, choose from , and ") ++ .help = N_("hotpatch action, choose from , , and ") + }, + {.name = "patch", + .type = VSH_OT_STRING, +@@ -14363,7 +14363,8 @@ VIR_ENUM_IMPL(virDomainHotpatchAction, + "none", + "apply", + "unapply", +- "query"); ++ "query", ++ "autoload"); + + static bool + cmdHotpatch(vshControl *ctl, +-- +2.30.0 + diff --git a/generic_vdpa/libvirt/hyperv-fix-the-number-of-threads-per-core.patch b/generic_vdpa/libvirt/hyperv-fix-the-number-of-threads-per-core.patch new file mode 100644 index 0000000..3f717fe --- /dev/null +++ b/generic_vdpa/libvirt/hyperv-fix-the-number-of-threads-per-core.patch @@ -0,0 +1,32 @@ +From ee9069defba076d94b432662af93a784ea002f5a Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Tue, 29 Nov 2022 08:57:42 +0000 +Subject: [PATCH 04/24] hyperv: fix the number of threads per core The operands + were reversed, producing an incorrect result. + +Co-authored-by: Sri Ramanujam +Signed-off-by: Matt Coleman +Reviewed-by: Michal Privoznik + +Signed-off-by: tangbin +(cherry-pick from 1e18d3b833b9daa7bb18b9550a2cf4d140303d86) +--- + src/hyperv/hyperv_driver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c +index 4677a25ff8..213dd8837b 100644 +--- a/src/hyperv/hyperv_driver.c ++++ b/src/hyperv/hyperv_driver.c +@@ -310,7 +310,7 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) + } + + info->cores = processorList->data.common->NumberOfCores; +- info->threads = info->cores / processorList->data.common->NumberOfLogicalProcessors; ++ info->threads = processorList->data.common->NumberOfLogicalProcessors / info->cores; + info->cpus = info->sockets * info->cores; + + result = 0; +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/include-Introduce-virDomainDirtyRateCalcFlags.patch b/generic_vdpa/libvirt/include-Introduce-virDomainDirtyRateCalcFlags.patch new file mode 100644 index 0000000..cc700c6 --- /dev/null +++ b/generic_vdpa/libvirt/include-Introduce-virDomainDirtyRateCalcFlags.patch @@ -0,0 +1,77 @@ +From c4c665b4654280560eafe5782359b71e8ef2b1b5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= + +Date: Sun, 20 Feb 2022 21:28:11 +0800 +Subject: [PATCH 6/7] include: Introduce virDomainDirtyRateCalcFlags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce virDomainDirtyRateCalcFlags to get ready for +adding mode parameter to qemuDomainStartDirtyRateCalc. + +Signed-off-by: Hyman Huang(黄勇) +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +--- + include/libvirt/libvirt-domain.h | 13 +++++++++++++ + src/libvirt-domain.c | 12 +++++++++++- + 2 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h +index e1954ae663..c7956c81d6 100644 +--- a/include/libvirt/libvirt-domain.h ++++ b/include/libvirt/libvirt-domain.h +@@ -5030,6 +5030,19 @@ typedef enum { + # endif + } virDomainDirtyRateStatus; + ++/** ++ * virDomainDirtyRateCalcFlags: ++ * ++ * Flags OR'ed together to provide specific behaviour when calculating dirty page ++ * rate for a Domain ++ * ++ */ ++typedef enum { ++ VIR_DOMAIN_DIRTYRATE_MODE_PAGE_SAMPLING = 0, /* default mode - page-sampling */ ++ VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_BITMAP = 1 << 0, /* dirty-bitmap mode */ ++ VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_RING = 1 << 1, /* dirty-ring mode */ ++} virDomainDirtyRateCalcFlags; ++ + int virDomainStartDirtyRateCalc(virDomainPtr domain, + int seconds, + unsigned int flags); +diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c +index 6a37ea85b7..0ff99c94b6 100644 +--- a/src/libvirt-domain.c ++++ b/src/libvirt-domain.c +@@ -12821,7 +12821,7 @@ virDomainHotpatchManage(virDomainPtr domain, + * virDomainStartDirtyRateCalc: + * @domain: a domain object + * @seconds: specified calculating time in seconds +- * @flags: extra flags; not used yet, so callers should always pass 0 ++ * @flags: bitwise-OR of supported virDomainDirtyRateCalcFlags + * + * Calculate the current domain's memory dirty rate in next @seconds. + * The calculated dirty rate information is available by calling +@@ -12845,6 +12845,16 @@ virDomainStartDirtyRateCalc(virDomainPtr domain, + + virCheckReadOnlyGoto(conn->flags, error); + ++ VIR_EXCLUSIVE_FLAGS_GOTO(VIR_DOMAIN_DIRTYRATE_MODE_PAGE_SAMPLING, ++ VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_BITMAP, ++ error); ++ VIR_EXCLUSIVE_FLAGS_GOTO(VIR_DOMAIN_DIRTYRATE_MODE_PAGE_SAMPLING, ++ VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_RING, ++ error); ++ VIR_EXCLUSIVE_FLAGS_GOTO(VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_BITMAP, ++ VIR_DOMAIN_DIRTYRATE_MODE_DIRTY_RING, ++ error); ++ + if (conn->driver->domainStartDirtyRateCalc) { + int ret; + ret = conn->driver->domainStartDirtyRateCalc(domain, seconds, flags); +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/leaseshelper-Report-errors-on-failure.patch b/generic_vdpa/libvirt/leaseshelper-Report-errors-on-failure.patch new file mode 100644 index 0000000..cb4ea48 --- /dev/null +++ b/generic_vdpa/libvirt/leaseshelper-Report-errors-on-failure.patch @@ -0,0 +1,51 @@ +From 75d4ed800f297532a7b3ac2b8f8a94c049959e3b Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Fri, 18 Dec 2020 16:09:08 +0100 +Subject: [PATCH 024/108] leaseshelper: Report errors on failure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If leasehelper fails all that we are left with is a simple error +message produced by dnsmasq: + + lease-init script returned exit code 1 + +This is because the leasehelper did not write any message to +stderr. According to dnsmasq's manpage, whenever it's invoking +leasehelper the stderr is kept open: + + All file descriptors are closed except stdin, which is open to + /dev/null, and stdout and stderr which capture output for + logging by dnsmasq. + +As debugging leasehelper is not trivial (because dnsmasq invokes +it with plenty of env vars set - that's how data is passed onto +helper), let's print an error into stderr if exiting with an +error. And since we are not calling public APIs, we have to call +virDispatchError() explicitly and since we don't have any +connection open, we have to pass NULL. + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +(cherry picked from commit c14bd64f3eba9838af8ab1cac369d51abfeb21b9) +--- + src/network/leaseshelper.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c +index 2b5fc0f442..fdd7fd3e80 100644 +--- a/src/network/leaseshelper.c ++++ b/src/network/leaseshelper.c +@@ -253,6 +253,8 @@ main(int argc, char **argv) + rv = EXIT_SUCCESS; + + cleanup: ++ if (rv != EXIT_SUCCESS) ++ virDispatchError(NULL); + if (pid_file_fd != -1) + virPidFileReleasePath(pid_file, pid_file_fd); + +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/libvirt-6.2.0.tar.xz b/generic_vdpa/libvirt/libvirt-6.2.0.tar.xz new file mode 100644 index 0000000..4d27d2f Binary files /dev/null and b/generic_vdpa/libvirt/libvirt-6.2.0.tar.xz differ diff --git a/generic_vdpa/libvirt/libvirt-Add-retry-support-for-error-policy.patch b/generic_vdpa/libvirt/libvirt-Add-retry-support-for-error-policy.patch new file mode 100644 index 0000000..3b5d3e3 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-Add-retry-support-for-error-policy.patch @@ -0,0 +1,119 @@ +From 9ba3e54d2b33e1105f5879fff3656c093337e60a Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 25 Feb 2021 18:55:30 +0800 +Subject: [PATCH] libvirt: Add 'retry' support for error policy + +Introduce error_policy=/rerror_policy='retry' to support +werror=/rerror=retry mechanism in qemu. + +Add retry_interval parameter to control the interval between retries. +Add retry_timeout parameter to control the total retry times. + +Signed-off-by: Jiahui Cen +Signed-off-by: Ying Fang +--- + src/conf/domain_conf.c | 25 +++++++++++++++++++++++++ + src/conf/domain_conf.h | 3 +++ + src/qemu/qemu_command.c | 8 ++++++++ + src/qemu/qemu_domain.c | 2 ++ + 4 files changed, 38 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index dbc3e103ff..5c469cedd0 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -355,6 +355,7 @@ VIR_ENUM_IMPL(virDomainDiskErrorPolicy, + "report", + "ignore", + "enospace", ++ "retry", + ); + + VIR_ENUM_IMPL(virDomainDiskIo, +@@ -10213,6 +10214,30 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, + } + VIR_FREE(tmp); + ++ def->retry_interval = -1; ++ if ((tmp = virXMLPropString(cur, "retry_interval")) && ++ ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && ++ def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (virStrToLong_l(tmp, NULL, 10, &def->retry_interval) < 0) || ++ (def->retry_interval < 0))) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unknown disk retry interval '%s'"), tmp); ++ return -1; ++ } ++ VIR_FREE(tmp); ++ ++ def->retry_timeout = -1; ++ if ((tmp = virXMLPropString(cur, "retry_timeout")) && ++ ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && ++ def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (virStrToLong_l(tmp, NULL, 10, &def->retry_timeout) < 0) || ++ (def->retry_timeout < 0))) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("unknown disk retry interval '%s'"), tmp); ++ return -1; ++ } ++ VIR_FREE(tmp); ++ + if ((tmp = virXMLPropString(cur, "io")) && + (def->iomode = virDomainDiskIoTypeFromString(tmp)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 16e625331c..86a86d3090 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -396,6 +396,7 @@ typedef enum { + VIR_DOMAIN_DISK_ERROR_POLICY_REPORT, + VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE, + VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE, ++ VIR_DOMAIN_DISK_ERROR_POLICY_RETRY, + + VIR_DOMAIN_DISK_ERROR_POLICY_LAST + } virDomainDiskErrorPolicy; +@@ -561,6 +562,8 @@ struct _virDomainDiskDef { + int cachemode; /* enum virDomainDiskCache */ + int error_policy; /* enum virDomainDiskErrorPolicy */ + int rerror_policy; /* enum virDomainDiskErrorPolicy */ ++ long retry_interval; ++ long retry_timeout; + int iomode; /* enum virDomainDiskIo */ + int ioeventfd; /* enum virTristateSwitch */ + int event_idx; /* enum virTristateSwitch */ +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 315deb5cfd..c3ad041959 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -1723,6 +1723,14 @@ qemuBuildDiskFrontendAttributeErrorPolicy(virDomainDiskDefPtr disk, + virBufferAsprintf(buf, ",werror=%s", wpolicy); + if (rpolicy) + virBufferAsprintf(buf, ",rerror=%s", rpolicy); ++ if ((disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY || ++ disk->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) && ++ disk->retry_interval >= 0) ++ virBufferAsprintf(buf, ",retry_interval=%ld", disk->retry_interval); ++ if ((disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY || ++ disk->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) && ++ disk->retry_timeout >= 0) ++ virBufferAsprintf(buf, ",retry_timeout=%ld", disk->retry_timeout); + } + + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index f89ff20a84..58493706a1 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -12308,6 +12308,8 @@ qemuDomainDiskChangeSupported(virDomainDiskDefPtr disk, + CHECK_EQ(cachemode, "cache", true); + CHECK_EQ(error_policy, "error_policy", true); + CHECK_EQ(rerror_policy, "rerror_policy", true); ++ CHECK_EQ(retry_interval, "retry_interval", true); ++ CHECK_EQ(retry_timeout, "retry_timeout", true); + CHECK_EQ(iomode, "io", true); + CHECK_EQ(ioeventfd, "ioeventfd", true); + CHECK_EQ(event_idx, "event_idx", true); +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/libvirt-Don-t-require-secdrivers-to-implement-.domainMoveIma.patch b/generic_vdpa/libvirt/libvirt-Don-t-require-secdrivers-to-implement-.domainMoveIma.patch new file mode 100644 index 0000000..579fbc7 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-Don-t-require-secdrivers-to-implement-.domainMoveIma.patch @@ -0,0 +1,42 @@ +From 19845de491a3102df4256a3457c7d5669bccda63 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 18 May 2020 10:07:30 +0200 +Subject: [PATCH] Don't require secdrivers to implement + .domainMoveImageMetadata + +The AppArmor secdriver does not use labels to grant access to +resources. Therefore, it doesn't use XATTRs and hence it lacks +implementation of .domainMoveImageMetadata callback. This leads +to a harmless but needless error message appearing in the logs: + + virSecurityManagerMoveImageMetadata:476 : this function is not + supported by the connection driver: virSecurityManagerMoveImageMetadata + +Closes: https://gitlab.com/libvirt/libvirt/-/issues/25 + +cherry-pick from commit: cc8c297e473afd55e5d8e35e18345d8df176059d + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +Signed-off-by: Jin Yan +--- + src/security/security_manager.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/security/security_manager.c b/src/security/security_manager.c +index fe03274..1445291 100644 +--- a/src/security/security_manager.c ++++ b/src/security/security_manager.c +@@ -473,8 +473,7 @@ virSecurityManagerMoveImageMetadata(virSecurityManagerPtr mgr, + return ret; + } + +- virReportUnsupportedError(); +- return -1; ++ return 0; + } + + +-- +1.8.3.1 + diff --git a/generic_vdpa/libvirt/libvirt-Fix-some-wrong-usage-of-ATTRIBUTE_NONNULL.patch b/generic_vdpa/libvirt/libvirt-Fix-some-wrong-usage-of-ATTRIBUTE_NONNULL.patch new file mode 100644 index 0000000..240f77e --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-Fix-some-wrong-usage-of-ATTRIBUTE_NONNULL.patch @@ -0,0 +1,56 @@ +From 42e4b74e1bbd08aad3afa46d741e46c40a8af73d Mon Sep 17 00:00:00 2001 +From: Bihong Yu +Date: Sat, 6 Jun 2020 18:52:35 +0800 +Subject: [PATCH] Fix some wrong usage of ATTRIBUTE_NONNULL() + +The virStateInitialize() function has ATTRIBUTE_NONNULL() +referring to @root argument (incorrectly anyway) but in +daemonRunStateInit() NULL is passed in anyway. + +Then there is virCommandAddArgPair() which also has +ATTRIBUTE_NONNULL() for one of its arguments and then checks the +argument for being NULL anyways. + +cherry-pick from commit: 2a372a5ad5fab3bf26fb9bea019d38fa04ba8b34 + +Signed-off-by:Bihong Yu +Reviewed-by:Chuan Zheng +Signed-off-by: Michal Privoznik +Reviewed-by: Michal Privoznik +Signed-off-by: Jin Yan +--- + src/libvirt_internal.h | 3 +-- + src/util/vircommand.h | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h +index 00ef7aa..72c6127 100644 +--- a/src/libvirt_internal.h ++++ b/src/libvirt_internal.h +@@ -33,8 +33,7 @@ int virStateInitialize(bool privileged, + bool mandatory, + const char *root, + virStateInhibitCallback inhibit, +- void *opaque) +- ATTRIBUTE_NONNULL(2); ++ void *opaque); + int virStateCleanup(void); + int virStateReload(void); + int virStateStop(void); +diff --git a/src/util/vircommand.h b/src/util/vircommand.h +index 9086f9a..4e6cb0a 100644 +--- a/src/util/vircommand.h ++++ b/src/util/vircommand.h +@@ -128,8 +128,7 @@ void virCommandAddArgFormat(virCommandPtr cmd, + + void virCommandAddArgPair(virCommandPtr cmd, + const char *name, +- const char *val) +- ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); ++ const char *val); + + void virCommandAddArgSet(virCommandPtr cmd, + const char *const*vals) ATTRIBUTE_NONNULL(2); +-- +1.8.3.1 + diff --git a/generic_vdpa/libvirt/libvirt-Substitute-security_context_t-with-char.patch b/generic_vdpa/libvirt/libvirt-Substitute-security_context_t-with-char.patch new file mode 100644 index 0000000..93ebe82 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-Substitute-security_context_t-with-char.patch @@ -0,0 +1,320 @@ +From 0ca4dd0cd279448ff28beb4c88e52107531783a3 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Tue, 4 Aug 2020 01:44:48 +0000 +Subject: [PATCH] Substitute security_context_t with char * + +Historically, we've used security_context_t for variables passed +to libselinux APIs. But almost 7 years ago, libselinux developers +admitted in their API that in fact, it's just a 'char *' type +[1]. Ever since then the APIs accept 'char *' instead, but they +kept the old alias just for API stability. Well, not anymore [2]. + +1: https://github.com/SELinuxProject/selinux/commit/9eb9c9327563014ad6a807814e7975424642d5b9 +2: https://github.com/SELinuxProject/selinux/commit/7a124ca2758136f49cc38efc26fb1a2d385ecfd9 + +Signed-off-by: Michal Privoznik +Reviewed-by: Andrea Bolognani +(cherry-picked from commit e71e13488dc1aa65456e54a4b41bc925821b4263) +Signed-off-by: Xu Yandong +--- + src/libvirt-lxc.c | 2 +- + src/rpc/virnetsocket.c | 2 +- + src/security/security_selinux.c | 26 +++++++++++++------------- + src/storage/storage_util.c | 2 +- + src/util/viridentity.c | 2 +- + tests/securityselinuxhelper.c | 16 ++++++++-------- + tests/securityselinuxlabeltest.c | 4 ++-- + tests/securityselinuxtest.c | 2 +- + tests/viridentitytest.c | 2 +- + 9 files changed, 29 insertions(+), 29 deletions(-) + +diff --git a/src/libvirt-lxc.c b/src/libvirt-lxc.c +index 47a06a3..25f1cfc 100644 +--- a/src/libvirt-lxc.c ++++ b/src/libvirt-lxc.c +@@ -204,7 +204,7 @@ virDomainLxcEnterSecurityLabel(virSecurityModelPtr model, + if (STREQ(model->model, "selinux")) { + #ifdef WITH_SELINUX + if (oldlabel) { +- security_context_t ctx; ++ char *ctx; + + if (getcon(&ctx) < 0) { + virReportSystemError(errno, +diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c +index 6c790cb..5537289 100644 +--- a/src/rpc/virnetsocket.c ++++ b/src/rpc/virnetsocket.c +@@ -1595,7 +1595,7 @@ int virNetSocketGetUNIXIdentity(virNetSocketPtr sock G_GNUC_UNUSED, + int virNetSocketGetSELinuxContext(virNetSocketPtr sock, + char **context) + { +- security_context_t seccon = NULL; ++ char *seccon = NULL; + int ret = -1; + + *context = NULL; +diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c +index 8aeb6e4..72d1658 100644 +--- a/src/security/security_selinux.c ++++ b/src/security/security_selinux.c +@@ -198,7 +198,7 @@ virSecuritySELinuxTransactionAppend(const char *path, + + static int + virSecuritySELinuxRememberLabel(const char *path, +- const security_context_t con) ++ const char *con) + { + return virSecuritySetRememberedLabel(SECURITY_SELINUX_NAME, + path, con); +@@ -207,7 +207,7 @@ virSecuritySELinuxRememberLabel(const char *path, + + static int + virSecuritySELinuxRecallLabel(const char *path, +- security_context_t *con) ++ char **con) + { + int rv; + +@@ -431,7 +431,7 @@ virSecuritySELinuxMCSGetProcessRange(char **sens, + int *catMin, + int *catMax) + { +- security_context_t ourSecContext = NULL; ++ char *ourSecContext = NULL; + context_t ourContext = NULL; + char *cat = NULL; + char *tmp; +@@ -530,8 +530,8 @@ virSecuritySELinuxMCSGetProcessRange(char **sens, + } + + static char * +-virSecuritySELinuxContextAddRange(security_context_t src, +- security_context_t dst) ++virSecuritySELinuxContextAddRange(char *src, ++ char *dst) + { + char *str = NULL; + char *ret = NULL; +@@ -575,7 +575,7 @@ virSecuritySELinuxGenNewContext(const char *basecontext, + context_t context = NULL; + char *ret = NULL; + char *str; +- security_context_t ourSecContext = NULL; ++ char *ourSecContext = NULL; + context_t ourContext = NULL; + + VIR_DEBUG("basecontext=%s mcs=%s isObjectContext=%d", +@@ -967,7 +967,7 @@ virSecuritySELinuxReserveLabel(virSecurityManagerPtr mgr, + virDomainDefPtr def, + pid_t pid) + { +- security_context_t pctx; ++ char *pctx; + context_t ctx = NULL; + const char *mcs; + int rv; +@@ -1217,7 +1217,7 @@ virSecuritySELinuxGetProcessLabel(virSecurityManagerPtr mgr G_GNUC_UNUSED, + pid_t pid, + virSecurityLabelPtr sec) + { +- security_context_t ctx; ++ char *ctx; + + if (getpidcon_raw(pid, &ctx) == -1) { + virReportSystemError(errno, +@@ -1330,7 +1330,7 @@ virSecuritySELinuxSetFilecon(virSecurityManagerPtr mgr, + bool remember) + { + bool privileged = virSecurityManagerGetPrivileged(mgr); +- security_context_t econ = NULL; ++ char *econ = NULL; + int refcount; + int rc; + bool rollback = false; +@@ -1440,7 +1440,7 @@ virSecuritySELinuxFSetFilecon(int fd, char *tcon) + /* Set fcon to the appropriate label for path and mode, or return -1. */ + static int + getContext(virSecurityManagerPtr mgr G_GNUC_UNUSED, +- const char *newpath, mode_t mode, security_context_t *fcon) ++ const char *newpath, mode_t mode, char **fcon) + { + virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr); + +@@ -1457,7 +1457,7 @@ virSecuritySELinuxRestoreFileLabel(virSecurityManagerPtr mgr, + { + bool privileged = virSecurityManagerGetPrivileged(mgr); + struct stat buf; +- security_context_t fcon = NULL; ++ char *fcon = NULL; + char *newpath = NULL; + int rc; + int ret = -1; +@@ -2972,7 +2972,7 @@ virSecuritySELinuxSetDaemonSocketLabel(virSecurityManagerPtr mgr G_GNUC_UNUSED, + { + /* TODO: verify DOI */ + virSecurityLabelDefPtr secdef; +- security_context_t scon = NULL; ++ char *scon = NULL; + char *str = NULL; + int rc = -1; + +@@ -3259,7 +3259,7 @@ virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr, + int fd) + { + struct stat buf; +- security_context_t fcon = NULL; ++ char *fcon = NULL; + virSecurityLabelDefPtr secdef; + char *str = NULL, *proc = NULL, *fd_path = NULL; + int rc = -1; +diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c +index 1ec1d13..4c67d3a 100644 +--- a/src/storage/storage_util.c ++++ b/src/storage/storage_util.c +@@ -1818,7 +1818,7 @@ virStorageBackendUpdateVolTargetInfoFD(virStorageSourcePtr target, + struct stat *sb) + { + #if WITH_SELINUX +- security_context_t filecon = NULL; ++ char *filecon = NULL; + #endif + + if (virStorageSourceUpdateBackingSizes(target, fd, sb) < 0) +diff --git a/src/util/viridentity.c b/src/util/viridentity.c +index 8cc2db2..2cb9042 100644 +--- a/src/util/viridentity.c ++++ b/src/util/viridentity.c +@@ -157,7 +157,7 @@ virIdentityPtr virIdentityGetSystem(void) + unsigned long long startTime; + g_autoptr(virIdentity) ret = NULL; + #if WITH_SELINUX +- security_context_t con; ++ char *con; + #endif + + if (!(ret = virIdentityNew())) +diff --git a/tests/securityselinuxhelper.c b/tests/securityselinuxhelper.c +index f89224c..63b5726 100644 +--- a/tests/securityselinuxhelper.c ++++ b/tests/securityselinuxhelper.c +@@ -58,7 +58,7 @@ static struct selabel_handle *(*real_selabel_open)(unsigned int backend, + unsigned nopts); + static void (*real_selabel_close)(struct selabel_handle *handle); + static int (*real_selabel_lookup_raw)(struct selabel_handle *handle, +- security_context_t *con, ++ char **con, + const char *key, + int type); + +@@ -94,7 +94,7 @@ static void init_syms(void) + * the virt_use_nfs bool is set. + */ + +-int getcon_raw(security_context_t *context) ++int getcon_raw(char **context) + { + if (!is_selinux_enabled()) { + errno = EINVAL; +@@ -109,12 +109,12 @@ int getcon_raw(security_context_t *context) + return 0; + } + +-int getcon(security_context_t *context) ++int getcon(char **context) + { + return getcon_raw(context); + } + +-int getpidcon_raw(pid_t pid, security_context_t *context) ++int getpidcon_raw(pid_t pid, char **context) + { + if (!is_selinux_enabled()) { + errno = EINVAL; +@@ -134,7 +134,7 @@ int getpidcon_raw(pid_t pid, security_context_t *context) + return 0; + } + +-int getpidcon(pid_t pid, security_context_t *context) ++int getpidcon(pid_t pid, char **context) + { + return getpidcon_raw(pid, context); + } +@@ -170,7 +170,7 @@ int setfilecon(const char *path, const char *con) + return setfilecon_raw(path, con); + } + +-int getfilecon_raw(const char *path, security_context_t *con) ++int getfilecon_raw(const char *path, char **con) + { + char *constr = NULL; + ssize_t len = getxattr(path, "user.libvirt.selinux", +@@ -194,7 +194,7 @@ int getfilecon_raw(const char *path, security_context_t *con) + } + + +-int getfilecon(const char *path, security_context_t *con) ++int getfilecon(const char *path, char **con) + { + return getfilecon_raw(path, con); + } +@@ -315,7 +315,7 @@ void selabel_close(struct selabel_handle *handle) + } + + int selabel_lookup_raw(struct selabel_handle *handle, +- security_context_t *con, ++ char **con, + const char *key, + int type) + { +diff --git a/tests/securityselinuxlabeltest.c b/tests/securityselinuxlabeltest.c +index 3040a36..50b447c 100644 +--- a/tests/securityselinuxlabeltest.c ++++ b/tests/securityselinuxlabeltest.c +@@ -252,7 +252,7 @@ static int + testSELinuxCheckLabels(testSELinuxFile *files, size_t nfiles) + { + size_t i; +- security_context_t ctx; ++ char *ctx; + + for (i = 0; i < nfiles; i++) { + ctx = NULL; +@@ -360,7 +360,7 @@ mymain(void) + if (virTestRun("Labelling " # name, testSELinuxLabeling, name) < 0) \ + ret = -1; + +- setcon((security_context_t)"system_r:system_u:libvirtd_t:s0:c0.c1023"); ++ setcon("system_r:system_u:libvirtd_t:s0:c0.c1023"); + + DO_TEST_LABELING("disks"); + DO_TEST_LABELING("kernel"); +diff --git a/tests/securityselinuxtest.c b/tests/securityselinuxtest.c +index 6c8314d..3f069c2 100644 +--- a/tests/securityselinuxtest.c ++++ b/tests/securityselinuxtest.c +@@ -217,7 +217,7 @@ testSELinuxGenLabel(const void *opaque) + context_t con = NULL; + context_t imgcon = NULL; + +- if (setcon_raw((security_context_t)data->pidcon) < 0) { ++ if (setcon_raw(data->pidcon) < 0) { + perror("Cannot set process security context"); + return -1; + } +diff --git a/tests/viridentitytest.c b/tests/viridentitytest.c +index 3f87af1..9a8c891 100644 +--- a/tests/viridentitytest.c ++++ b/tests/viridentitytest.c +@@ -120,7 +120,7 @@ static int testIdentityGetSystem(const void *data) + static int testSetFakeSELinuxContext(const void *data G_GNUC_UNUSED) + { + #if WITH_SELINUX +- return setcon_raw((security_context_t)data); ++ return setcon_raw(data); + #else + VIR_DEBUG("libvirt not compiled with SELinux, skipping this test"); + return EXIT_AM_SKIP; +-- +2.25.4 + diff --git a/generic_vdpa/libvirt/libvirt-cgroup-cleanup-eventParams-when-virTypedParamsAddULL.patch b/generic_vdpa/libvirt/libvirt-cgroup-cleanup-eventParams-when-virTypedParamsAddULL.patch new file mode 100644 index 0000000..c9f2a2e --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cgroup-cleanup-eventParams-when-virTypedParamsAddULL.patch @@ -0,0 +1,34 @@ +From 432afe3f14418ea5d2d69e62d678ef5bb08caaa1 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Wed, 15 Apr 2020 11:55:43 +0800 +Subject: cgroup: cleanup eventParams when virTypedParamsAddULLong failed + +Function virTypedParamsAddULLong use realloc to gain memory, +and doesn't free it when failed. so we need free eventParams to +prevent a memory leak. + +Signed-off-by: Xu Yandong +--- + src/qemu/qemu_cgroup.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c +index c0e30f6..057f871 100644 +--- a/src/qemu/qemu_cgroup.c ++++ b/src/qemu/qemu_cgroup.c +@@ -904,8 +904,11 @@ qemuSetupCpuCgroup(virDomainObjPtr vm) + if (virTypedParamsAddULLong(&eventParams, &eventNparams, + &eventMaxparams, + VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES, +- val) < 0) ++ val) < 0) { ++ if (eventParams) ++ virTypedParamsFree(eventParams, eventNparams); + return -1; ++ } + + event = virDomainEventTunableNewFromObj(vm, eventParams, eventNparams); + } +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-conf-Don-t-format-http-cookies-unless-VIR_DOMAIN_DEF.patch b/generic_vdpa/libvirt/libvirt-conf-Don-t-format-http-cookies-unless-VIR_DOMAIN_DEF.patch new file mode 100644 index 0000000..bb03503 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-conf-Don-t-format-http-cookies-unless-VIR_DOMAIN_DEF.patch @@ -0,0 +1,53 @@ +From cec735e6f4001caa0395eddc9d8a0fe18e97f9eb Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Tue, 4 Aug 2020 08:40:36 +0000 +Subject: [PATCH] conf: Don't format http cookies unless + VIR_DOMAIN_DEF_FORMAT_SECURE is used + +Starting with 3b076391befc3fe72deb0c244ac6c2b4c100b410 +(v6.1.0-122-g3b076391be) we support http cookies. Since they may contain +somewhat sensitive information we should not format them into the XML +unless VIR_DOMAIN_DEF_FORMAT_SECURE is asserted. + +Reported-by: Han Han +Signed-off-by: Peter Krempa +Reviewed-by: Erik Skultety +(cherry-picked from commit a5b064bf4b17a9884d7d361733737fb614ad8979) +Signed-off-by: Xu Yandong +--- + src/conf/domain_conf.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 914e03c..cf93a59 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -24565,11 +24565,15 @@ virDomainSourceDefFormatSeclabel(virBufferPtr buf, + + static void + virDomainDiskSourceFormatNetworkCookies(virBufferPtr buf, +- virStorageSourcePtr src) ++ virStorageSourcePtr src, ++ unsigned int flags) + { + g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf); + size_t i; + ++ if (!(flags & VIR_DOMAIN_DEF_FORMAT_SECURE)) ++ return; ++ + for (i = 0; i < src->ncookies; i++) { + virBufferEscapeString(&childBuf, "", src->cookies[i]->name); + virBufferEscapeString(&childBuf, "%s\n", src->cookies[i]->value); +@@ -24630,7 +24634,7 @@ virDomainDiskSourceFormatNetwork(virBufferPtr attrBuf, + virTristateBoolTypeToString(src->sslverify)); + } + +- virDomainDiskSourceFormatNetworkCookies(childBuf, src); ++ virDomainDiskSourceFormatNetworkCookies(childBuf, src, flags); + + if (src->readahead) + virBufferAsprintf(childBuf, "\n", src->readahead); +-- +2.25.4 + diff --git a/generic_vdpa/libvirt/libvirt-conf-Increase-cpuset-length-limit-for-CPU-pinning.patch b/generic_vdpa/libvirt/libvirt-conf-Increase-cpuset-length-limit-for-CPU-pinning.patch new file mode 100644 index 0000000..7c09892 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-conf-Increase-cpuset-length-limit-for-CPU-pinning.patch @@ -0,0 +1,33 @@ +From fc8c41dbb52eb9ce3ee36680ecb53a41f4146610 Mon Sep 17 00:00:00 2001 +From: Jiri Denemark +Date: Thu, 11 Jun 2020 13:53:27 +0200 +Subject: [PATCH] conf: Increase cpuset length limit for CPU pinning + +Domains are now allowed to be pinned to host CPUs with IDs up to 16383. +The new limit is as arbitrary as the old one. It's just bigger. + +cherry-pick from commit: e728ffba5119cfb1488aa7363fef596940449f50 + +Signed-off-by: Jiri Denemark +Reviewed-by: Michal Privoznik +Signed-off-by: Jin Yan +--- + src/conf/domain_conf.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index a40773a..16e6253 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -2241,7 +2241,7 @@ struct _virDomainHugePage { + unsigned long long size; /* hugepage size in KiB */ + }; + +-#define VIR_DOMAIN_CPUMASK_LEN 1024 ++#define VIR_DOMAIN_CPUMASK_LEN 16384 + + struct _virDomainIOThreadIDDef { + bool autofill; +-- +1.8.3.1 + diff --git a/generic_vdpa/libvirt/libvirt-conf-Set-default-values-of-retry-fileds.patch b/generic_vdpa/libvirt/libvirt-conf-Set-default-values-of-retry-fileds.patch new file mode 100644 index 0000000..457305c --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-conf-Set-default-values-of-retry-fileds.patch @@ -0,0 +1,87 @@ +From 04292a5ad4cb9741fa8f9687befd1e1c644043a6 Mon Sep 17 00:00:00 2001 +From: Jiahui Cen +Date: Thu, 18 Mar 2021 15:14:20 +0800 +Subject: [PATCH] libvirt/conf: Set default values of retry fileds + +Currently the default values of retry_interval and retry_timeout are set +to -1, when 'driver' option exists without retry fileds. It conflicts +with the default values when the 'driver' option does not exist. + +So let's set default values of retry_interval and retry_timeout to 0 when +retry policy is not enabled. + +Signed-off-by: Jiahui Cen +--- + src/conf/domain_conf.c | 18 ++++++++++++------ + src/conf/domain_conf.h | 3 +++ + 2 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 5c469cedd0..a4e9b3290c 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -10186,6 +10186,7 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, + xmlNodePtr cur) + { + g_autofree char *tmp = NULL; ++ bool retry_enabled = false; + + def->driverName = virXMLPropString(cur, "name"); + +@@ -10214,28 +10215,33 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, + } + VIR_FREE(tmp); + +- def->retry_interval = -1; ++ retry_enabled = (def->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (def->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY); ++ + if ((tmp = virXMLPropString(cur, "retry_interval")) && +- ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && +- def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (!retry_enabled || + (virStrToLong_l(tmp, NULL, 10, &def->retry_interval) < 0) || + (def->retry_interval < 0))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown disk retry interval '%s'"), tmp); + return -1; + } ++ if (retry_enabled && !tmp) { ++ def->retry_interval = VIR_DOMAIN_DISK_DEFAULT_RETRY_INTERVAL; ++ } + VIR_FREE(tmp); + +- def->retry_timeout = -1; + if ((tmp = virXMLPropString(cur, "retry_timeout")) && +- ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && +- def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || ++ (!retry_enabled || + (virStrToLong_l(tmp, NULL, 10, &def->retry_timeout) < 0) || + (def->retry_timeout < 0))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown disk retry interval '%s'"), tmp); + return -1; + } ++ if (retry_enabled && !tmp) { ++ def->retry_timeout = VIR_DOMAIN_DISK_DEFAULT_RETRY_TIMEOUT; ++ } + VIR_FREE(tmp); + + if ((tmp = virXMLPropString(cur, "io")) && +diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h +index 86a86d3090..ccee986849 100644 +--- a/src/conf/domain_conf.h ++++ b/src/conf/domain_conf.h +@@ -523,6 +523,9 @@ typedef enum { + } virDomainMemoryAllocation; + + ++#define VIR_DOMAIN_DISK_DEFAULT_RETRY_INTERVAL 1000 ++#define VIR_DOMAIN_DISK_DEFAULT_RETRY_TIMEOUT 0 ++ + /* Stores the virtual disk configuration */ + struct _virDomainDiskDef { + virStorageSourcePtr src; /* non-NULL. XXX Allow NULL for empty cdrom? */ +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/libvirt-conf-vmx-check-for-OOM-after-calling-xmlBufferCreate.patch b/generic_vdpa/libvirt/libvirt-conf-vmx-check-for-OOM-after-calling-xmlBufferCreate.patch new file mode 100644 index 0000000..e822e9d --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-conf-vmx-check-for-OOM-after-calling-xmlBufferCreate.patch @@ -0,0 +1,100 @@ +From 657c7f5d79fe43823ffb4d46e244bea15a65baf6 Mon Sep 17 00:00:00 2001 +From: Laine Stump +Date: Thu, 18 Jun 2020 12:49:09 -0400 +Subject: [PATCH 1/6] conf, vmx: check for OOM after calling xmlBufferCreate() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Although libvirt itself uses g_malloc0() and friends, which exit when +there isn't enouogh memory, libxml2 uses standard malloc(), which just +returns NULL on OOM - this means we must check for NULL on return from +any libxml2 functions that allocate memory. + +xmlBufferCreate(), for example, might return NULL, and we don't always +check for it. This patch adds checks where it isn't already done. + +(NB: Although libxml2 has a provision for changing behavior on OOM (by +calling xmlMemSetup() to change what functions are used to +allocating/freeing memory), we can't use that, since parts of libvirt +code end up in libvirt.so, which is linked and called directly by +applications that may themselves use libxml2 (and may have already set +their own alternate malloc()), e.g. drivers like esx which live totally +in the library rather than a separate process.) + +cherry pick from: b7a92bce070fd57844a59bf8b1c30cb4ef4f3acd + +Signed-off-by: Laine Stump +Reviewed-by: Ján Tomko +--- + src/conf/domain_conf.c | 6 +++++- + src/conf/network_conf.c | 6 +++++- + src/vmx/vmx.c | 11 +++++++---- + 3 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 914e03c..37c785a 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -29022,7 +29022,11 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, + * Thankfully, libxml maps what looks like globals into + * thread-local uses, so we are thread-safe. */ + xmlIndentTreeOutput = 1; +- xmlbuf = xmlBufferCreate(); ++ if (!(xmlbuf = xmlBufferCreate())) { ++ virReportOOMError(); ++ goto error; ++ } ++ + if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata, + virBufferGetIndent(buf) / 2, 1) < 0) { + xmlBufferFree(xmlbuf); +diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c +index 819b645..c379042 100644 +--- a/src/conf/network_conf.c ++++ b/src/conf/network_conf.c +@@ -2478,7 +2478,11 @@ virNetworkDefFormatBuf(virBufferPtr buf, + * Thankfully, libxml maps what looks like globals into + * thread-local uses, so we are thread-safe. */ + xmlIndentTreeOutput = 1; +- xmlbuf = xmlBufferCreate(); ++ if (!(xmlbuf = xmlBufferCreate())) { ++ virReportOOMError(); ++ return -1; ++ } ++ + if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata, + virBufferGetIndent(buf) / 2, 1) < 0) { + xmlBufferFree(xmlbuf); +diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c +index b1fd118..fbc8366 100644 +--- a/src/vmx/vmx.c ++++ b/src/vmx/vmx.c +@@ -697,8 +697,8 @@ virVMXConvertToUTF8(const char *encoding, const char *string) + { + char *result = NULL; + xmlCharEncodingHandlerPtr handler; +- xmlBufferPtr input; +- xmlBufferPtr utf8; ++ xmlBufferPtr input = NULL; ++ xmlBufferPtr utf8 = NULL; + + handler = xmlFindCharEncodingHandler(encoding); + +@@ -708,8 +708,11 @@ virVMXConvertToUTF8(const char *encoding, const char *string) + return NULL; + } + +- input = xmlBufferCreateStatic((char *)string, strlen(string)); +- utf8 = xmlBufferCreate(); ++ if (!(input = xmlBufferCreateStatic((char *)string, strlen(string))) || ++ !(utf8 = xmlBufferCreate())) { ++ virReportOOMError(); ++ goto cleanup; ++ } + + if (xmlCharEncInFunc(handler, utf8, input) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, +-- +1.8.3.1 + diff --git a/generic_vdpa/libvirt/libvirt-cpu-aarch64-enable-host-model-cpu-for-AArch64-archit.patch b/generic_vdpa/libvirt/libvirt-cpu-aarch64-enable-host-model-cpu-for-AArch64-archit.patch new file mode 100644 index 0000000..5391de0 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu-aarch64-enable-host-model-cpu-for-AArch64-archit.patch @@ -0,0 +1,44 @@ +From 1e6875a732d896138d3bc2351e5284d1ad13dd59 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Wed, 20 May 2020 02:33:27 -0400 +Subject: [PATCH] cpu/aarch64: enable host-model cpu for AArch64 architecture + +The 'host-model' cpu is support by kunpeng-v virtualization +suit, skip hypervisor host-model externsion checking on AArch64 +architecture. + +Signed-off-by: Xu Yandong +--- + src/qemu/qemu_command.c | 2 +- + tests/qemuxml2argvtest.c | 2 -- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 2f0e919..2f65b8d 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -6582,7 +6582,7 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver, + break; + } + +- if ((ARCH_IS_S390(def->os.arch) || ARCH_IS_ARM(def->os.arch)) && ++ if (ARCH_IS_S390(def->os.arch) && + cpu->features && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) { + virReportError(VIR_ERR_INTERNAL_ERROR, +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 596dd7a..2153e44 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -2736,8 +2736,6 @@ mymain(void) + DO_TEST("aarch64-noacpi-nouefi", NONE); + DO_TEST_PARSE_ERROR("aarch64-acpi-nouefi", NONE); + +- /* QEMU 4.0.0 didn't have support for aarch64 CPU features */ +- DO_TEST_CAPS_ARCH_VER_FAILURE("aarch64-features-sve", "aarch64", "4.0.0"); + /* aarch64 doesn't support the same CPU features as x86 */ + DO_TEST_CAPS_ARCH_LATEST_FAILURE("aarch64-features-wrong", "aarch64"); + /* Can't enable vector lengths when SVE is overall disabled */ +-- +1.8.3.1 + diff --git a/generic_vdpa/libvirt/libvirt-cpu-arm-add-cpu-data-free-function-to-virCPUarmDataF.patch b/generic_vdpa/libvirt/libvirt-cpu-arm-add-cpu-data-free-function-to-virCPUarmDataF.patch new file mode 100644 index 0000000..2adbb48 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu-arm-add-cpu-data-free-function-to-virCPUarmDataF.patch @@ -0,0 +1,51 @@ +From efde450d2d0648475cde04f04f5e26c1a006c226 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Fri, 17 Apr 2020 14:40:27 +0800 +Subject: cpu/arm: add cpu data free function to virCPUarmDataFree + +Signed-off-by: Xu Yandong +--- + src/cpu/cpu_arm.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c +index ee58021..230cd27 100644 +--- a/src/cpu/cpu_arm.c ++++ b/src/cpu/cpu_arm.c +@@ -61,6 +61,25 @@ virCPUarmFeatureFree(virCPUarmFeaturePtr feature) + + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmFeature, virCPUarmFeatureFree); + ++static void ++virCPUarmDataClear(virCPUarmData *data) ++{ ++ if (!data) ++ return; ++ ++ VIR_FREE(data->features); ++} ++ ++static void ++virCPUarmDataFree(virCPUDataPtr cpuData) ++{ ++ if (!cpuData) ++ return; ++ ++ virCPUarmDataClear(&cpuData->data.arm); ++ VIR_FREE(cpuData); ++} ++ + typedef struct _virCPUarmMap virCPUarmMap; + typedef virCPUarmMap *virCPUarmMapPtr; + struct _virCPUarmMap { +@@ -259,6 +278,7 @@ struct cpuArchDriver cpuDriverArm = { + .compare = virCPUarmCompare, + .decode = NULL, + .encode = NULL, ++ .dataFree = virCPUarmDataFree, + .baseline = virCPUarmBaseline, + .update = virCPUarmUpdate, + .validateFeatures = virCPUarmValidateFeatures, +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-cpu-arm-add-decode-function.patch b/generic_vdpa/libvirt/libvirt-cpu-arm-add-decode-function.patch new file mode 100644 index 0000000..6b43380 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu-arm-add-decode-function.patch @@ -0,0 +1,275 @@ +From c69a629367b0e9bfa1a034301a4c3f88ad080586 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Sat, 18 Apr 2020 11:16:13 +0800 +Subject: cpu/arm: add decode function + +Signed-off-by: Xu Yandong +--- + src/cpu/cpu_arm.c | 150 ++++++++++++++++++++++++++++++++++-------- + src/cpu_map/index.xml | 3 - + 2 files changed, 122 insertions(+), 31 deletions(-) + +diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c +index d85f111..eb9b1c9 100644 +--- a/src/cpu/cpu_arm.c ++++ b/src/cpu/cpu_arm.c +@@ -55,7 +55,6 @@ virCPUarmFeatureFree(virCPUarmFeaturePtr feature) + return; + + g_free(feature->name); +- + g_free(feature); + } + +@@ -80,6 +79,8 @@ virCPUarmDataFree(virCPUDataPtr cpuData) + g_free(cpuData); + } + ++G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUData, virCPUarmDataFree); ++ + typedef struct _virCPUarmVendor virCPUarmVendor; + typedef virCPUarmVendor *virCPUarmVendorPtr; + struct _virCPUarmVendor { +@@ -103,6 +104,8 @@ virCPUarmVendorFree(virCPUarmVendorPtr vendor) + VIR_FREE(vendor); + } + ++G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmVendor, virCPUarmVendorFree); ++ + typedef struct _virCPUarmModel virCPUarmModel; + typedef virCPUarmModel *virCPUarmModelPtr; + struct _virCPUarmModel { +@@ -175,6 +178,38 @@ virCPUarmMapFree(virCPUarmMapPtr map) + + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmMap, virCPUarmMapFree); + ++static virCPUarmVendorPtr ++virCPUarmVendorFindByID(virCPUarmMapPtr map, ++ unsigned long vendor_id) ++{ ++ size_t i; ++ ++ for (i = 0; i < map->vendors->len; i++) { ++ virCPUarmVendorPtr vendor = g_ptr_array_index(map->vendors, i); ++ ++ if (vendor->value == vendor_id) ++ return vendor; ++ } ++ ++ return NULL; ++} ++ ++static virCPUarmVendorPtr ++virCPUarmVendorFindByName(virCPUarmMapPtr map, ++ const char *name) ++{ ++ size_t i; ++ ++ for (i = 0; i < map->vendors->len; i++) { ++ virCPUarmVendorPtr vendor = g_ptr_array_index(map->vendors, i); ++ ++ if (STREQ(vendor->name, name)) ++ return vendor; ++ } ++ ++ return NULL; ++} ++ + static virCPUarmFeaturePtr + virCPUarmMapFeatureFind(virCPUarmMapPtr map, + const char *name) +@@ -213,36 +248,43 @@ virCPUarmMapFeatureParse(xmlXPathContextPtr ctxt G_GNUC_UNUSED, + return 0; + } + +-static virCPUarmVendorPtr +-virCPUarmVendorFindByID(virCPUarmMapPtr map, +- unsigned long vendor_id) ++static int ++armCpuDataParseFeatures(virCPUDefPtr cpu, ++ const virCPUarmData *cpuData) + { ++ int ret = -1; + size_t i; ++ char **features; + +- for (i = 0; i < map->vendors->len; i++) { +- virCPUarmVendorPtr vendor = g_ptr_array_index(map->vendors, i); ++ if (!cpu || !cpuData) ++ return ret; + +- if (vendor->value == vendor_id) +- return vendor; +- } ++ if (!(features = virStringSplitCount(cpuData->features, " ", ++ 0, &cpu->nfeatures))) ++ return ret; + +- return NULL; +-} ++ if (cpu->nfeatures) { ++ if (VIR_ALLOC_N(cpu->features, cpu->nfeatures) < 0) ++ goto error; + +-static virCPUarmVendorPtr +-virCPUarmVendorFindByName(virCPUarmMapPtr map, +- const char *name) +-{ +- size_t i; ++ for (i = 0; i < cpu->nfeatures; i++) { ++ cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE; ++ cpu->features[i].name = g_strdup(features[i]); ++ } ++ } + +- for (i = 0; i < map->vendors->len; i++) { +- virCPUarmVendorPtr vendor = g_ptr_array_index(map->vendors, i); ++ ret = 0; + +- if (STREQ(vendor->name, name)) +- return vendor; +- } ++cleanup: ++ virStringListFree(features); ++ return ret; + +- return NULL; ++error: ++ for (i = 0; i < cpu->nfeatures; i++) ++ VIR_FREE(cpu->features[i].name); ++ VIR_FREE(cpu->features); ++ cpu->nfeatures = 0; ++ goto cleanup; + } + + static int +@@ -252,7 +294,6 @@ virCPUarmVendorParse(xmlXPathContextPtr ctxt, + { + virCPUarmMapPtr map = (virCPUarmMapPtr)data; + g_autoptr(virCPUarmVendor) vendor = NULL; +- int ret = -1; + + if (virCPUarmVendorFindByName(map, name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -289,7 +330,7 @@ virCPUarmModelFindByPVR(virCPUarmMapPtr map, + for (i = 0; i < map->models->len; i++) { + virCPUarmModelPtr model = g_ptr_array_index(map->models, i); + +- if (STREQ(model->pvr, pvr)) ++ if (model->data.pvr == pvr) + return model; + } + +@@ -299,7 +340,7 @@ virCPUarmModelFindByPVR(virCPUarmMapPtr map, + + static virCPUarmModelPtr + virCPUarmModelFindByName(virCPUarmMapPtr map, +- const char *name) ++ const char *name) + { + size_t i; + +@@ -321,7 +362,6 @@ virCPUarmModelParse(xmlXPathContextPtr ctxt, + virCPUarmMapPtr map = (virCPUarmMapPtr)data; + g_autoptr(virCPUarmModel) model = NULL; + char *vendor = NULL; +- int ret = -1; + + if (virCPUarmModelFindByName(map, name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, +@@ -404,6 +444,60 @@ virCPUarmGetMap(void) + return cpuMap; + } + ++static int ++virCPUarmDecode(virCPUDefPtr cpu, ++ const virCPUarmData *cpuData, ++ virDomainCapsCPUModelsPtr models) ++{ ++ virCPUarmMapPtr map; ++ virCPUarmModelPtr model; ++ virCPUarmVendorPtr vendor = NULL; ++ ++ if (!cpuData || !(map = virCPUarmGetMap())) ++ return -1; ++ ++ if (!(model = virCPUarmModelFindByPVR(map, cpuData->pvr))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("Cannot find CPU model with PVR 0x%03lx"), ++ cpuData->pvr); ++ return -1; ++ } ++ ++ if (!virCPUModelIsAllowed(model->name, models)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("CPU model %s is not supported by hypervisor"), ++ model->name); ++ return -1; ++ } ++ ++ cpu->model = g_strdup(model->name); ++ ++ if (cpuData->vendor_id && ++ !(vendor = virCPUarmVendorFindByID(map, cpuData->vendor_id))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("Cannot find CPU vendor with vendor id 0x%02lx"), ++ cpuData->vendor_id); ++ return -1; ++ } ++ ++ if (vendor) ++ cpu->vendor = g_strdup(vendor->name); ++ ++ if (cpuData->features && ++ armCpuDataParseFeatures(cpu, cpuData) < 0) ++ return -1; ++ ++ return 0; ++} ++ ++static int ++virCPUarmDecodeCPUData(virCPUDefPtr cpu, ++ const virCPUData *data, ++ virDomainCapsCPUModelsPtr models) ++{ ++ return virCPUarmDecode(cpu, &data->data.arm, models); ++} ++ + static int + virCPUarmUpdate(virCPUDefPtr guest, + const virCPUDef *host) +@@ -432,7 +526,7 @@ virCPUarmUpdate(virCPUDefPtr guest, + guest->match = VIR_CPU_MATCH_EXACT; + ret = 0; + +- cleanup: ++cleanup: + virCPUDefFree(updated); + return ret; + } +@@ -493,7 +587,7 @@ struct cpuArchDriver cpuDriverArm = { + .arch = archs, + .narch = G_N_ELEMENTS(archs), + .compare = virCPUarmCompare, +- .decode = NULL, ++ .decode = virCPUarmDecodeCPUData, + .encode = NULL, + .dataFree = virCPUarmDataFree, + .baseline = virCPUarmBaseline, +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 2e78834..985af86 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -86,9 +86,6 @@ + + + +- +- +- + + + +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-cpu-arm-add-load-cpu-map-parse-function.patch b/generic_vdpa/libvirt/libvirt-cpu-arm-add-load-cpu-map-parse-function.patch new file mode 100644 index 0000000..cf59ab2 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu-arm-add-load-cpu-map-parse-function.patch @@ -0,0 +1,287 @@ +From a0574d45603010761d3f3034f97457fda94d2266 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Fri, 17 Apr 2020 18:13:32 +0800 +Subject: cpu/arm: add load cpu map parse function + +Signed-off-by: Xu Yandong +--- + src/cpu/cpu_arm.c | 223 +++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 220 insertions(+), 3 deletions(-) + +diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c +index 230cd27..d85f111 100644 +--- a/src/cpu/cpu_arm.c ++++ b/src/cpu/cpu_arm.c +@@ -67,7 +67,7 @@ virCPUarmDataClear(virCPUarmData *data) + if (!data) + return; + +- VIR_FREE(data->features); ++ g_free(data->features); + } + + static void +@@ -77,12 +77,64 @@ virCPUarmDataFree(virCPUDataPtr cpuData) + return; + + virCPUarmDataClear(&cpuData->data.arm); +- VIR_FREE(cpuData); ++ g_free(cpuData); + } + ++typedef struct _virCPUarmVendor virCPUarmVendor; ++typedef virCPUarmVendor *virCPUarmVendorPtr; ++struct _virCPUarmVendor { ++ char *name; ++ unsigned long value; ++}; ++ ++static virCPUarmVendorPtr ++virCPUarmVendorNew(void) ++{ ++ return g_new0(virCPUarmVendor, 1); ++} ++ ++static void ++virCPUarmVendorFree(virCPUarmVendorPtr vendor) ++{ ++ if (!vendor) ++ return; ++ ++ g_free(vendor->name); ++ VIR_FREE(vendor); ++} ++ ++typedef struct _virCPUarmModel virCPUarmModel; ++typedef virCPUarmModel *virCPUarmModelPtr; ++struct _virCPUarmModel { ++ char *name; ++ virCPUarmVendorPtr vendor; ++ virCPUarmData data; ++}; ++ ++static virCPUarmModelPtr ++virCPUarmModelNew(void) ++{ ++ return g_new0(virCPUarmModel, 1); ++} ++ ++static void ++virCPUarmModelFree(virCPUarmModelPtr model) ++{ ++ if (!model) ++ return; ++ ++ virCPUarmDataClear(&model->data); ++ g_free(model->name); ++ g_free(model); ++} ++ ++G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmModel, virCPUarmModelFree); ++ + typedef struct _virCPUarmMap virCPUarmMap; + typedef virCPUarmMap *virCPUarmMapPtr; + struct _virCPUarmMap { ++ GPtrArray *vendors; ++ GPtrArray *models; + GPtrArray *features; + }; + +@@ -93,6 +145,14 @@ virCPUarmMapNew(void) + + map = g_new0(virCPUarmMap, 1); + ++ map->vendors = g_ptr_array_new(); ++ g_ptr_array_set_free_func(map->vendors, ++ (GDestroyNotify) virCPUarmVendorFree); ++ ++ map->models = g_ptr_array_new(); ++ g_ptr_array_set_free_func(map->models, ++ (GDestroyNotify) virCPUarmModelFree); ++ + map->features = g_ptr_array_new(); + g_ptr_array_set_free_func(map->features, + (GDestroyNotify) virCPUarmFeatureFree); +@@ -106,6 +166,8 @@ virCPUarmMapFree(virCPUarmMapPtr map) + if (!map) + return; + ++ g_ptr_array_free(map->vendors, TRUE); ++ g_ptr_array_free(map->models, TRUE); + g_ptr_array_free(map->features, TRUE); + + g_free(map); +@@ -151,6 +213,161 @@ virCPUarmMapFeatureParse(xmlXPathContextPtr ctxt G_GNUC_UNUSED, + return 0; + } + ++static virCPUarmVendorPtr ++virCPUarmVendorFindByID(virCPUarmMapPtr map, ++ unsigned long vendor_id) ++{ ++ size_t i; ++ ++ for (i = 0; i < map->vendors->len; i++) { ++ virCPUarmVendorPtr vendor = g_ptr_array_index(map->vendors, i); ++ ++ if (vendor->value == vendor_id) ++ return vendor; ++ } ++ ++ return NULL; ++} ++ ++static virCPUarmVendorPtr ++virCPUarmVendorFindByName(virCPUarmMapPtr map, ++ const char *name) ++{ ++ size_t i; ++ ++ for (i = 0; i < map->vendors->len; i++) { ++ virCPUarmVendorPtr vendor = g_ptr_array_index(map->vendors, i); ++ ++ if (STREQ(vendor->name, name)) ++ return vendor; ++ } ++ ++ return NULL; ++} ++ ++static int ++virCPUarmVendorParse(xmlXPathContextPtr ctxt, ++ const char *name, ++ void *data) ++{ ++ virCPUarmMapPtr map = (virCPUarmMapPtr)data; ++ g_autoptr(virCPUarmVendor) vendor = NULL; ++ int ret = -1; ++ ++ if (virCPUarmVendorFindByName(map, name)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("CPU vendor %s already defined"), name); ++ return -1; ++ } ++ ++ vendor = virCPUarmVendorNew(); ++ vendor->name = g_strdup(name); ++ ++ if (virXPathULongHex("string(@value)", ctxt, &vendor->value) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ "%s", _("Missing CPU vendor value")); ++ return -1; ++ } ++ ++ if (virCPUarmVendorFindByID(map, vendor->value)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("CPU vendor value 0x%2lx already defined"), vendor->value); ++ return -1; ++ } ++ ++ g_ptr_array_add(map->vendors, g_steal_pointer(&vendor)); ++ ++ return 0; ++} ++ ++static virCPUarmModelPtr ++virCPUarmModelFindByPVR(virCPUarmMapPtr map, ++ unsigned long pvr) ++{ ++ size_t i; ++ ++ for (i = 0; i < map->models->len; i++) { ++ virCPUarmModelPtr model = g_ptr_array_index(map->models, i); ++ ++ if (STREQ(model->pvr, pvr)) ++ return model; ++ } ++ ++ return NULL; ++ ++} ++ ++static virCPUarmModelPtr ++virCPUarmModelFindByName(virCPUarmMapPtr map, ++ const char *name) ++{ ++ size_t i; ++ ++ for (i = 0; i < map->models->len; i++) { ++ virCPUarmModelPtr model = g_ptr_array_index(map->models, i); ++ ++ if (STREQ(model->name, name)) ++ return model; ++ } ++ ++ return NULL; ++} ++ ++static int ++virCPUarmModelParse(xmlXPathContextPtr ctxt, ++ const char *name, ++ void *data) ++{ ++ virCPUarmMapPtr map = (virCPUarmMapPtr)data; ++ g_autoptr(virCPUarmModel) model = NULL; ++ char *vendor = NULL; ++ int ret = -1; ++ ++ if (virCPUarmModelFindByName(map, name)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("CPU model %s already defined"), name); ++ return -1; ++ } ++ ++ model = virCPUarmModelNew(); ++ model->name = g_strdup(name); ++ ++ 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"), ++ name); ++ return -1; ++ } ++ ++ if (!(model->vendor = virCPUarmVendorFindByName(map, vendor))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown vendor %s referenced by CPU model %s"), ++ vendor, model->name); ++ return -1; ++ } ++ } ++ ++ if (!virXPathBoolean("boolean(./pvr)", ctxt)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing PVR information for CPU model %s"), ++ model->name); ++ return -1; ++ } ++ ++ if (virXPathULongHex("string(./pvr/@value)", ctxt, &model->data.pvr) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing or invalid PVR value in CPU model %s"), ++ model->name); ++ return -1; ++ } ++ ++ g_ptr_array_add(map->models, g_steal_pointer(&model)); ++ ++ return 0; ++} ++ + static virCPUarmMapPtr + virCPUarmLoadMap(void) + { +@@ -158,7 +375,7 @@ virCPUarmLoadMap(void) + + map = virCPUarmMapNew(); + +- if (cpuMapLoad("arm", NULL, virCPUarmMapFeatureParse, NULL, map) < 0) ++ if (cpuMapLoad("arm", virCPUarmVendorParse, virCPUarmMapFeatureParse, virCPUarmModelParse, map) < 0) + return NULL; + + return g_steal_pointer(&map); +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-cpu-arm-add-virCPUarmGetHost-implment.patch b/generic_vdpa/libvirt/libvirt-cpu-arm-add-virCPUarmGetHost-implment.patch new file mode 100644 index 0000000..9812042 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu-arm-add-virCPUarmGetHost-implment.patch @@ -0,0 +1,127 @@ +From 208c9f1eb9a06d2550b7b3cfe0172840925255d4 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Mon, 20 Apr 2020 17:29:17 +0800 +Subject: cpu/arm: add virCPUarmGetHost implment + +Signed-off-by: Xu Yandong +--- + src/cpu/cpu_arm.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 86 insertions(+) + +diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c +index eb9b1c9..78e604c 100644 +--- a/src/cpu/cpu_arm.c ++++ b/src/cpu/cpu_arm.c +@@ -26,9 +26,15 @@ + #include "cpu_map.h" + #include "virstring.h" + #include "virxml.h" ++#include "virfile.h" + + #define VIR_FROM_THIS VIR_FROM_CPU + ++static const char *sysinfoCpuinfo = "/proc/cpuinfo"; ++ ++#define CPUINFO sysinfoCpuinfo ++#define CPUINFO_FILE_LEN (1024*1024) /* 1MB limit for /proc/cpuinfo file */ ++ + static const virArch archs[] = { + VIR_ARCH_ARMV6L, + VIR_ARCH_ARMV7B, +@@ -531,6 +537,85 @@ cleanup: + return ret; + } + ++static int ++armCpuDataFromCpuInfo(virCPUarmData *data) ++{ ++ g_autofree char *str_vendor = NULL; ++ g_autofree char *str_pvr = NULL; ++ g_autofree char *outbuf = NULL; ++ char *eol = NULL; ++ const char *cur; ++ ++ if (!data) ++ return -1; ++ ++ if (virFileReadAll(CPUINFO, CPUINFO_FILE_LEN, &outbuf) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Failed to open %s"), CPUINFO); ++ return -1; ++ } ++ ++ /* Account for format 'CPU implementer : XXXX' */ ++ if ((cur = strstr(outbuf, "CPU implementer")) == NULL) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("there is no \"CPU implementer\" info in %s"), CPUINFO); ++ return -1; ++ } ++ ++ cur = strchr(cur, ':') + 1; ++ eol = strchr(cur, '\n'); ++ virSkipSpaces(&cur); ++ if (!eol || !(str_vendor = g_strndup(cur, eol - cur)) || ++ virStrToLong_ul(str_vendor, NULL, 16, &data->vendor_id) < 0) ++ return -1; ++ ++ /* Account for format 'CPU part : XXXX' */ ++ if ((cur = strstr(outbuf, "CPU part")) == NULL) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("there is no \"CPU part\" info in %s"), CPUINFO); ++ return -1; ++ } ++ ++ cur = strchr(cur, ':') + 1; ++ eol = strchr(cur, '\n'); ++ virSkipSpaces(&cur); ++ if (!eol || !(str_pvr = g_strndup(cur, eol - cur)) || ++ virStrToLong_ul(str_pvr, NULL, 16, &data->pvr) < 0) ++ return -1; ++ ++ /* Account for format 'CPU Features : XXXX' */ ++ if ((cur = strstr(outbuf, "Features")) == NULL) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("there is no \"Features\" info in %s"), CPUINFO); ++ return -1; ++ } ++ cur = strchr(cur, ':') + 1; ++ eol = strchr(cur, '\n'); ++ virSkipSpaces(&cur); ++ if (eol && !(data->features = g_strndup(cur, eol - cur))) ++ return -1; ++ ++ return 0; ++} ++ ++static int ++virCPUarmGetHost(virCPUDefPtr cpu, ++ virDomainCapsCPUModelsPtr models) ++{ ++ g_autoptr(virCPUData) cpuData = NULL; ++ ++ if (virCPUarmDriverInitialize() < 0) ++ return -1; ++ ++ if (!(cpuData = virCPUDataNew(archs[0]))) ++ return -1; ++ ++ if (armCpuDataFromCpuInfo(&cpuData->data.arm) < 0) ++ return -1; ++ ++ return virCPUarmDecodeCPUData(cpu, cpuData, models); ++} ++ + + static virCPUDefPtr + virCPUarmBaseline(virCPUDefPtr *cpus, +@@ -590,6 +675,7 @@ struct cpuArchDriver cpuDriverArm = { + .decode = virCPUarmDecodeCPUData, + .encode = NULL, + .dataFree = virCPUarmDataFree, ++ .getHost = virCPUarmGetHost, + .baseline = virCPUarmBaseline, + .update = virCPUarmUpdate, + .validateFeatures = virCPUarmValidateFeatures, +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-cpu-arm-implment-cpu-baseline-function.patch b/generic_vdpa/libvirt/libvirt-cpu-arm-implment-cpu-baseline-function.patch new file mode 100644 index 0000000..d9dc344 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu-arm-implment-cpu-baseline-function.patch @@ -0,0 +1,216 @@ +From 4606782bde2a6e75e88d782fc58e5db5365502c2 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Mon, 20 Apr 2020 19:17:56 +0800 +Subject: cpu/arm: implment cpu baseline function + +Signed-off-by: Xu Yandong +--- + src/cpu/cpu_arm.c | 178 ++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 174 insertions(+), 4 deletions(-) + +diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c +index 78e604c..a7c9523 100644 +--- a/src/cpu/cpu_arm.c ++++ b/src/cpu/cpu_arm.c +@@ -616,24 +616,194 @@ virCPUarmGetHost(virCPUDefPtr cpu, + return virCPUarmDecodeCPUData(cpu, cpuData, models); + } + ++static void ++virCPUarmDataIntersect(virCPUarmData *data1, ++ const virCPUarmData *data2) ++{ ++ char **features = NULL; ++ char **features1 = NULL; ++ char **features2 = NULL; ++ size_t count = 0; ++ size_t i; ++ ++ if (!data1 || !data2) ++ return; ++ ++ data1->pvr = MIN(data1->pvr, data2->pvr); ++ ++ if (virStringIsEmpty(data1->features) || ++ virStringIsEmpty(data2->features)) { ++ VIR_FREE(data1->features); ++ return; ++ } ++ ++ if (STREQ_NULLABLE(data1->features, data2->features)) ++ return; ++ ++ if (!(features = virStringSplitCount(data1->features, " ", 0, &count)) || ++ !(features1 = virStringSplitCount(data1->features, " ", 0, &count)) || ++ !(features2 = virStringSplit(data2->features, " ", 0))) ++ goto cleanup; ++ ++ for (i = 0; i < count; i++) { ++ if (!virStringListHasString((const char**)features2, features1[i])) ++ virStringListRemove(&features, features1[i]); ++ } ++ ++ VIR_FREE(data1->features); ++ if (features) ++ data1->features = virStringListJoin((const char**)features, " "); ++ ++cleanup: ++ virStringListFree(features); ++ virStringListFree(features1); ++ virStringListFree(features2); ++ return; ++} ++ ++static void ++virCPUarmDataCopy(virCPUarmData *dst, const virCPUarmData *src) ++{ ++ dst->features = g_strdup(src->features); ++ dst->vendor_id = src->vendor_id; ++ dst->pvr = src->pvr; ++} ++ ++static virCPUarmModelPtr ++virCPUarmModelCopy(virCPUarmModelPtr model) ++{ ++ g_autoptr(virCPUarmModel) copy = NULL; ++ ++ copy = virCPUarmModelNew(); ++ ++ virCPUarmDataCopy(©->data, &model->data); ++ copy->name = g_strdup(model->name); ++ copy->vendor = model->vendor; ++ ++ return g_steal_pointer(©); ++} ++ ++static virCPUarmModelPtr ++virCPUarmModelFromCPU(const virCPUDef *cpu, ++ virCPUarmMapPtr map) ++{ ++ g_autoptr(virCPUarmModel) model = NULL; ++ virCPUarmVendorPtr vendor = NULL; ++ char **features = NULL; ++ size_t i; ++ ++ if (!cpu->model) { ++ virReportError(VIR_ERR_INVALID_ARG, "%s", ++ _("no CPU model specified")); ++ return NULL; ++ } ++ ++ if (!(model = virCPUarmModelFindByName(map, cpu->model))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown CPU model %s"), cpu->model); ++ return NULL; ++ } ++ ++ if (!(model = virCPUarmModelCopy(model))) ++ return NULL; ++ ++ if (cpu->vendor) { ++ if (!(vendor = virCPUarmVendorFindByName(map, cpu->vendor))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown CPU vendor %s"), cpu->vendor); ++ return NULL; ++ } ++ model->data.vendor_id = vendor->value; ++ } ++ ++ if (cpu->nfeatures) { ++ if (VIR_REALLOC_N(features, cpu->nfeatures + 1) < 0) ++ return model; ++ ++ features[cpu->nfeatures] = NULL; ++ for (i = 0; i < cpu->nfeatures; i++) ++ features[i] = g_strdup(cpu->features[i].name); ++ VIR_FREE(model->data.features); ++ model->data.features = virStringListJoin((const char **)features, " "); ++ } ++ ++ virStringListFree(features); ++ return g_steal_pointer(&model); ++} + + static virCPUDefPtr + virCPUarmBaseline(virCPUDefPtr *cpus, +- unsigned int ncpus G_GNUC_UNUSED, +- virDomainCapsCPUModelsPtr models G_GNUC_UNUSED, ++ unsigned int ncpus, ++ virDomainCapsCPUModelsPtr models, + const char **features G_GNUC_UNUSED, + bool migratable G_GNUC_UNUSED) + { +- virCPUDefPtr cpu = NULL; ++ virCPUarmMapPtr map = NULL; ++ g_autoptr(virCPUDef) cpu = NULL; ++ g_autoptr(virCPUarmModel) model = NULL; ++ g_autoptr(virCPUarmModel) baseModel = NULL; ++ virCPUarmVendorPtr vendor = NULL; ++ bool outputVendor = true; ++ size_t i; + + cpu = virCPUDefNew(); + + cpu->model = g_strdup(cpus[0]->model); + ++ cpu->arch = cpus[0]->arch; + cpu->type = VIR_CPU_TYPE_GUEST; + cpu->match = VIR_CPU_MATCH_EXACT; ++ cpu->fallback = VIR_CPU_FALLBACK_FORBID; ++ ++ if (!(map = virCPUarmGetMap())) ++ return NULL; ++ ++ if (!(baseModel = virCPUarmModelFromCPU(cpus[0], map))) ++ return NULL; ++ ++ if (!cpus[0]->vendor) { ++ outputVendor = false; ++ } else if (!(vendor = virCPUarmVendorFindByName(map, cpus[0]->vendor))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("Unknown CPU vendor %s"), cpus[0]->vendor); ++ return NULL; ++ } ++ ++ for (i = 0; i < ncpus; i++) { ++ const char *vn = NULL; ++ if (!(model = virCPUarmModelFromCPU(cpus[i], map))) ++ return NULL; ++ ++ if (cpus[i]->vendor) { ++ vn = cpus[i]->vendor; ++ } else { ++ outputVendor = false; ++ } ++ ++ if (vn) { ++ if (!vendor) { ++ if (!(vendor = virCPUarmVendorFindByName(map, vn))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("Unknown CPU vendor %s"), vn); ++ return NULL; ++ } ++ } else if (STRNEQ(vendor->name, vn)) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ "%s", _("CPU vendors do not match")); ++ return NULL; ++ } ++ ++ virCPUarmDataIntersect(&baseModel->data, &model->data); ++ } ++ } ++ ++ if (virCPUarmDecode(cpu, &baseModel->data, models) < 0) ++ return NULL; ++ ++ if (!outputVendor) ++ g_free(cpu->vendor); + +- return cpu; ++ return g_steal_pointer(&cpu); + } + + static virCPUCompareResult +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-cpu-arm-implment-cpu-compare-function.patch b/generic_vdpa/libvirt/libvirt-cpu-arm-implment-cpu-compare-function.patch new file mode 100644 index 0000000..c08e4bb --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu-arm-implment-cpu-compare-function.patch @@ -0,0 +1,239 @@ +From 1a70b1e3bdbd8d0dcf9281341bc23b4ff2ffaa3a Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Mon, 20 Apr 2020 19:33:49 +0800 +Subject: cpu/arm: implment cpu compare function + +Signed-off-by: Xu Yandong +--- + src/cpu/cpu_arm.c | 196 +++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 193 insertions(+), 3 deletions(-) + +diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c +index a7c9523..3ef54b9 100644 +--- a/src/cpu/cpu_arm.c ++++ b/src/cpu/cpu_arm.c +@@ -21,6 +21,7 @@ + + #include + ++#include "virlog.h" + #include "viralloc.h" + #include "cpu.h" + #include "cpu_map.h" +@@ -30,6 +31,8 @@ + + #define VIR_FROM_THIS VIR_FROM_CPU + ++VIR_LOG_INIT("cpu.cpu_arm"); ++ + static const char *sysinfoCpuinfo = "/proc/cpuinfo"; + + #define CPUINFO sysinfoCpuinfo +@@ -806,14 +809,201 @@ virCPUarmBaseline(virCPUDefPtr *cpus, + return g_steal_pointer(&cpu); + } + ++static bool ++virCPUarmFeaturesIsSub(char *subFeatures, ++ char *fullFeatures) ++{ ++ bool ret = false; ++ char **sub = NULL; ++ char **full = NULL; ++ size_t subCount = 0; ++ size_t fullCount = 0; ++ size_t i; ++ ++ if (virStringIsEmpty(subFeatures)) ++ return true; ++ ++ if (virStringIsEmpty(fullFeatures)) ++ return ret; ++ ++ if (STREQ(subFeatures, fullFeatures)) ++ return true; ++ ++ if (!(sub = virStringSplitCount(subFeatures, " ", 0, &subCount)) || ++ !(full = virStringSplitCount(fullFeatures, " ", 0, &fullCount)) || ++ subCount > fullCount) ++ goto cleanup; ++ ++ for (i = 0; i < subCount; i++) { ++ if (!virStringListHasString((const char**)full, sub[i])) ++ goto cleanup; ++ } ++ ++ ret = true; ++ ++ cleanup: ++ virStringListFree(sub); ++ virStringListFree(full); ++ return ret; ++} ++ ++static virCPUDataPtr ++armMakeCPUData(virArch arch, ++ virCPUarmData *data) ++{ ++ virCPUDataPtr cpuData; ++ ++ if (!(cpuData = virCPUDataNew(arch))) ++ return NULL; ++ ++ virCPUarmDataCopy(&cpuData->data.arm, data); ++ ++ return cpuData; ++} ++ + static virCPUCompareResult +-virCPUarmCompare(virCPUDefPtr host G_GNUC_UNUSED, +- virCPUDefPtr cpu G_GNUC_UNUSED, +- bool failMessages G_GNUC_UNUSED) ++armCompute(virCPUDefPtr host, ++ virCPUDefPtr cpu, ++ virCPUDataPtr *guestData, ++ char **message) + { ++ virCPUarmMapPtr map = NULL; ++ g_autoptr(virCPUarmModel) hostModel = NULL; ++ g_autoptr(virCPUarmModel) guestModel = NULL; ++ virArch arch; ++ size_t i; ++ ++ 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)); ++ ++ return VIR_CPU_COMPARE_INCOMPATIBLE; ++ } ++ 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); ++ ++ return VIR_CPU_COMPARE_INCOMPATIBLE; ++ } ++ ++ if (!(map = virCPUarmGetMap())) ++ return VIR_CPU_COMPARE_ERROR; ++ ++ /* Host CPU information */ ++ if (!(hostModel = virCPUarmModelFromCPU(host, map))) ++ return VIR_CPU_COMPARE_ERROR; ++ ++ 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 */ ++ guestModel = virCPUarmModelCopy(hostModel); ++ break; ++ ++ case VIR_CPU_MODE_CUSTOM: ++ /* custom: ++ * look up guest CPU information */ ++ guestModel = virCPUarmModelFromCPU(cpu, map); ++ break; ++ } ++ } else { ++ /* Other host CPU information */ ++ guestModel = virCPUarmModelFromCPU(cpu, map); ++ } ++ ++ if (!guestModel) ++ return VIR_CPU_COMPARE_ERROR; ++ ++ if (STRNEQ(guestModel->name, hostModel->name)) { ++ VIR_DEBUG("host CPU model %s does not match required CPU model %s", ++ hostModel->name, guestModel->name); ++ if (message) ++ *message = g_strdup_printf(_("host CPU model %s does not match required " ++ "CPU model %s"), ++ hostModel->name, guestModel->name); ++ ++ return VIR_CPU_COMPARE_INCOMPATIBLE; ++ } ++ ++ if (!virCPUarmFeaturesIsSub(guestModel->data.features, hostModel->data.features)) { ++ VIR_DEBUG("guest CPU features '%s' is not subset of " ++ "host CPU features '%s'", ++ guestModel->data.features, hostModel->data.features); ++ if (message) ++ *message = g_strdup_printf(_("guest CPU features '%s' is not subset of " ++ "host CPU features '%s'"), ++ guestModel->data.features, ++ hostModel->data.features); ++ ++ return VIR_CPU_COMPARE_INCOMPATIBLE; ++ } ++ ++ if (guestData && ++ !(*guestData = armMakeCPUData(arch, &guestModel->data))) ++ return VIR_CPU_COMPARE_ERROR; ++ + return VIR_CPU_COMPARE_IDENTICAL; + } + ++static virCPUCompareResult ++virCPUarmCompare(virCPUDefPtr host, ++ virCPUDefPtr cpu, ++ bool failMessages) ++{ ++ virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR; ++ g_autofree char *message = NULL; ++ ++ if (!host || !host->model) { ++ if (failMessages) { ++ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", ++ _("unknown host CPU")); ++ } else { ++ VIR_WARN("unknown host CPU"); ++ return VIR_CPU_COMPARE_INCOMPATIBLE; ++ } ++ return VIR_CPU_COMPARE_ERROR; ++ } ++ ++ ret = armCompute(host, cpu, NULL, &message); ++ ++ if (failMessages && ret == VIR_CPU_COMPARE_INCOMPATIBLE) { ++ if (message) { ++ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", message); ++ } else { ++ virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL); ++ } ++ return VIR_CPU_COMPARE_ERROR; ++ } ++ ++ return ret; ++} ++ + static int + virCPUarmValidateFeatures(virCPUDefPtr cpu) + { +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-cpu-introduce-virCPUarmData-to-virCPUData.patch b/generic_vdpa/libvirt/libvirt-cpu-introduce-virCPUarmData-to-virCPUData.patch new file mode 100644 index 0000000..51afaa1 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu-introduce-virCPUarmData-to-virCPUData.patch @@ -0,0 +1,76 @@ +From 43ebd81b60121ce002a58ebc046b19f31bb23cb6 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Thu, 16 Apr 2020 11:00:49 +0800 +Subject: cpu: introduce virCPUarmData to virCPUData + +introduce virCPUarmData to virCPUData union, CPUarmData include +vendor id, pvr and cpu features. + +Signed-off-by: Xu Yandong +--- + src/cpu/cpu.h | 2 ++ + src/cpu/cpu_arm_data.h | 32 ++++++++++++++++++++++++++++++++ + 2 files changed, 34 insertions(+) + create mode 100644 src/cpu/cpu_arm_data.h + +diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h +index f779d2b..ec22a18 100644 +--- a/src/cpu/cpu.h ++++ b/src/cpu/cpu.h +@@ -27,6 +27,7 @@ + #include "cpu_conf.h" + #include "cpu_x86_data.h" + #include "cpu_ppc64_data.h" ++#include "cpu_arm_data.h" + + + typedef struct _virCPUData virCPUData; +@@ -36,6 +37,7 @@ struct _virCPUData { + union { + virCPUx86Data x86; + virCPUppc64Data ppc64; ++ virCPUarmData arm; + /* generic driver needs no data */ + } data; + }; +diff --git a/src/cpu/cpu_arm_data.h b/src/cpu/cpu_arm_data.h +new file mode 100644 +index 0000000..72b3a29 +--- /dev/null ++++ b/src/cpu/cpu_arm_data.h +@@ -0,0 +1,32 @@ ++/* ++ * cpu_arm_data.h: 64-bit arm CPU specific data ++ * ++ * Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved. ++ * ++ * 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 ++ * . ++ * ++ */ ++ ++#pragma once ++ ++ ++#define VIR_CPU_ARM_DATA_INIT { 0 } ++ ++typedef struct _virCPUarmData virCPUarmData; ++struct _virCPUarmData { ++ unsigned long vendor_id; ++ unsigned long pvr; ++ char *features; ++}; +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-cpu_map-Introduce-arm-CPU-models.patch b/generic_vdpa/libvirt/libvirt-cpu_map-Introduce-arm-CPU-models.patch new file mode 100644 index 0000000..b47a7c5 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu_map-Introduce-arm-CPU-models.patch @@ -0,0 +1,150 @@ +From b305f4c05d22277ba6092bc0c2a15b752959bdec Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Thu, 16 Apr 2020 10:57:11 +0800 +Subject: cpu_map: Introduce arm CPU models + +Support vendor and model for virConnectGetCapabilities in ARM, +add arm cpu info to cpu map. + +Signed-off-by: Xu Yandong +--- + src/cpu_map/Makefile.inc.am | 5 +++++ + src/cpu_map/arm_Kunpeng-920.xml | 24 ++++++++++++++++++++++++ + src/cpu_map/arm_cortex-a53.xml | 6 ++++++ + src/cpu_map/arm_cortex-a57.xml | 6 ++++++ + src/cpu_map/arm_cortex-a72.xml | 6 ++++++ + src/cpu_map/arm_vendors.xml | 14 ++++++++++++++ + src/cpu_map/index.xml | 12 ++++++++++++ + 7 files changed, 73 insertions(+) + create mode 100644 src/cpu_map/arm_Kunpeng-920.xml + create mode 100644 src/cpu_map/arm_cortex-a53.xml + create mode 100644 src/cpu_map/arm_cortex-a57.xml + create mode 100644 src/cpu_map/arm_cortex-a72.xml + create mode 100644 src/cpu_map/arm_vendors.xml + +diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am +index be64c9a..8663877 100644 +--- a/src/cpu_map/Makefile.inc.am ++++ b/src/cpu_map/Makefile.inc.am +@@ -67,6 +67,11 @@ cpumap_DATA = \ + cpu_map/x86_Skylake-Server-noTSX-IBRS.xml \ + cpu_map/x86_Westmere.xml \ + cpu_map/x86_Westmere-IBRS.xml \ ++ cpu_map/arm_vendors.xml \ ++ cpu_map/arm_cortex-a53.xml \ ++ cpu_map/arm_cortex-a57.xml \ ++ cpu_map/arm_cortex-a72.xml \ ++ cpu_map/arm_Kunpeng-920.xml \ + $(NULL) + + EXTRA_DIST += $(cpumap_DATA) +diff --git a/src/cpu_map/arm_Kunpeng-920.xml b/src/cpu_map/arm_Kunpeng-920.xml +new file mode 100644 +index 0000000..b681546 +--- /dev/null ++++ b/src/cpu_map/arm_Kunpeng-920.xml +@@ -0,0 +1,24 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/arm_cortex-a53.xml b/src/cpu_map/arm_cortex-a53.xml +new file mode 100644 +index 0000000..3580236 +--- /dev/null ++++ b/src/cpu_map/arm_cortex-a53.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/arm_cortex-a57.xml b/src/cpu_map/arm_cortex-a57.xml +new file mode 100644 +index 0000000..3bc4324 +--- /dev/null ++++ b/src/cpu_map/arm_cortex-a57.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/arm_cortex-a72.xml b/src/cpu_map/arm_cortex-a72.xml +new file mode 100644 +index 0000000..c509a40 +--- /dev/null ++++ b/src/cpu_map/arm_cortex-a72.xml +@@ -0,0 +1,6 @@ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/arm_vendors.xml b/src/cpu_map/arm_vendors.xml +new file mode 100644 +index 0000000..840bf9a +--- /dev/null ++++ b/src/cpu_map/arm_vendors.xml +@@ -0,0 +1,14 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 50b030d..2e78834 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -87,4 +87,16 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-cpu_map-add-kunpeng-920-features-as-known-features.patch b/generic_vdpa/libvirt/libvirt-cpu_map-add-kunpeng-920-features-as-known-features.patch new file mode 100644 index 0000000..aefd050 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-cpu_map-add-kunpeng-920-features-as-known-features.patch @@ -0,0 +1,41 @@ +From f67e57fa41c76e21effd9e61773319ef424a5265 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Tue, 26 May 2020 20:08:07 +0800 +Subject: [PATCH] cpu_map: add kunpeng-920 features to arm features + +Signed-off-by: Xu Yandong +--- + src/cpu_map/arm_features.xml | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/src/cpu_map/arm_features.xml b/src/cpu_map/arm_features.xml +index 8a53384..5bed298 100644 +--- a/src/cpu_map/arm_features.xml ++++ b/src/cpu_map/arm_features.xml +@@ -19,4 +19,23 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-ensure-defresult-is-used-in-virConnectAuthCa.patch b/generic_vdpa/libvirt/libvirt-ensure-defresult-is-used-in-virConnectAuthCa.patch new file mode 100644 index 0000000..68964c3 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-ensure-defresult-is-used-in-virConnectAuthCa.patch @@ -0,0 +1,39 @@ +From fe9f75a69b6dac1dec4f77d8b17ec2406415d89d Mon Sep 17 00:00:00 2001 +From: Matt Coleman +Date: Mon, 21 Sep 2020 22:01:46 -0400 +Subject: [PATCH 037/108] libvirt: ensure defresult is used in + virConnectAuthCallbackDefault +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A previous change to this function's password handling broke the use of +default values for credential types other than VIR_CRED_PASSPHRASE and +VIR_CRED_NOECHOPROMPT. + +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Neal Gompa +Signed-off-by: Matt Coleman +(cherry picked from commit 1bb9f872a02f8be50c8f98b0ad13de62d2986fa9) +--- + src/libvirt.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/libvirt.c b/src/libvirt.c +index 76bf1fa677..b11a15d7fe 100644 +--- a/src/libvirt.c ++++ b/src/libvirt.c +@@ -146,7 +146,9 @@ virConnectAuthCallbackDefault(virConnectCredentialPtr cred, + len = strlen(buf); + if (len != 0 && buf[len-1] == '\n') + buf[len-1] = '\0'; +- bufptr = g_strdup(buf); ++ ++ if (strlen(buf) > 0) ++ bufptr = g_strdup(buf); + break; + + case VIR_CRED_PASSPHRASE: +-- +2.33.0 + diff --git a/generic_vdpa/libvirt/libvirt-guests-Sync-time-for-autostarted-guests.patch b/generic_vdpa/libvirt/libvirt-guests-Sync-time-for-autostarted-guests.patch new file mode 100644 index 0000000..16a14d4 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-guests-Sync-time-for-autostarted-guests.patch @@ -0,0 +1,40 @@ +From bad0bdbee1225d4d5831bc7ea7d4113df4de743d Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Tue, 29 Nov 2022 10:01:51 +0000 +Subject: [PATCH 08/24] libvirt-guests: Sync time for autostarted guests + Setting SYNC_TIME=1 does not work on autostarted guests. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +See https://bugzilla.redhat.com/show_bug.cgi?id=1555398. + +Signed-off-by: Tim Wiederhake +Reviewed-by: Daniel P. Berrangé + +Signed-off-by: tangbin +(cherry-pick from a501fa7cae2b93807496295945e6d3b51e5ccb3f) +--- + tools/libvirt-guests.sh.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/libvirt-guests.sh.in b/tools/libvirt-guests.sh.in +index a881f6266e..74286a12c4 100644 +--- a/tools/libvirt-guests.sh.in ++++ b/tools/libvirt-guests.sh.in +@@ -200,9 +200,9 @@ start() { + retval run_virsh "$uri" start $bypass "$name" \ + >/dev/null && \ + gettext "done"; echo +- if "$sync_time"; then +- run_virsh "$uri" domtime --sync "$name" >/dev/null +- fi ++ fi ++ if "$sync_time"; then ++ run_virsh "$uri" domtime --sync "$name" >/dev/null + fi + fi + done +-- +2.27.0 + diff --git a/generic_vdpa/libvirt/libvirt-leaseshelper-Report-more-errors.patch b/generic_vdpa/libvirt/libvirt-leaseshelper-Report-more-errors.patch new file mode 100644 index 0000000..b6dce6f --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-leaseshelper-Report-more-errors.patch @@ -0,0 +1,66 @@ +From cc842aa3030697b1a454e15ccfb2a201e57d5602 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Mon, 15 Jun 2020 12:53:48 +0200 +Subject: [PATCH 3/6] leaseshelper: Report more errors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some functions or code paths that may fail don't report error +(e.g. when acquiring PID file fails) leading to a silent quit +of the leaseshelper. This makes it super hard for us and users +to debug what is happening. Fortunately, dnsmasq captures both +stdout and stderr so we can write an error message there. + +cherry pick from: 9ed345ac1a035c8cf1de37431de638f4bac41de3 + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +--- + src/network/leaseshelper.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c +index 86c847d..2b5fc0f 100644 +--- a/src/network/leaseshelper.c ++++ b/src/network/leaseshelper.c +@@ -131,8 +131,10 @@ main(int argc, char **argv) + * events for expired leases. So, libvirtd sets another env var for this + * purpose */ + if (!interface && +- !(interface = getenv("VIR_BRIDGE_NAME"))) +- goto cleanup; ++ !(interface = getenv("VIR_BRIDGE_NAME"))) { ++ fprintf(stderr, _("interface not set\n")); ++ exit(EXIT_FAILURE); ++ } + + ip = argv[3]; + mac = argv[2]; +@@ -160,13 +162,21 @@ main(int argc, char **argv) + pid_file = g_strdup(RUNSTATEDIR "/leaseshelper.pid"); + + /* Try to claim the pidfile, exiting if we can't */ +- if ((pid_file_fd = virPidFileAcquirePath(pid_file, true, getpid())) < 0) ++ if ((pid_file_fd = virPidFileAcquirePath(pid_file, true, getpid())) < 0) { ++ fprintf(stderr, ++ _("Unable to acquire PID file: %s\n errno=%d"), ++ pid_file, errno); + goto cleanup; ++ } + + /* Since interfaces can be hot plugged, we need to make sure that the + * corresponding custom lease file exists. If not, 'touch' it */ +- if (virFileTouch(custom_lease_file, 0644) < 0) ++ if (virFileTouch(custom_lease_file, 0644) < 0) { ++ fprintf(stderr, ++ _("Unable to create: %s\n errno=%d"), ++ custom_lease_file, errno); + goto cleanup; ++ } + + switch ((enum virLeaseActionFlags) action) { + case VIR_LEASE_ACTION_ADD: +-- +1.8.3.1 + diff --git a/generic_vdpa/libvirt/libvirt-leaseshelper-Wait-to-acquire-PID-file.patch b/generic_vdpa/libvirt/libvirt-leaseshelper-Wait-to-acquire-PID-file.patch new file mode 100644 index 0000000..4cbdd02 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-leaseshelper-Wait-to-acquire-PID-file.patch @@ -0,0 +1,45 @@ +From 173b80e8f8103f26438d344e9b97335d4e5036b4 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Thu, 11 Jun 2020 16:43:22 +0200 +Subject: [PATCH 2/6] leaseshelper: Wait to acquire PID file +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On a DHCP transaction, dnsmasq runs our leases helper which +updates corresponding JSON files. While one dnsmasq won't run the +leaseshelper in parallel, two dnsmasqs (from two distinct +networks) might. To avoid corrupting JSON file, the leaseshelper +acquires PID file first. Well, the way it's acquiring it is not +ideal - it calls virPidFileAcquirePath(wait = false); which +means, that either it acquires the PID file instantly or returns +an error and does not touch the JSON at all. This in turn means +that there might be a leases record missing. With wait = true, +this won't happen. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1840307 + +cherry pick from: 876211ef4a192df1603b45715044ec14567d7e9f + +Signed-off-by: Michal Privoznik +Reviewed-by: Daniel P. Berrangé +--- + src/network/leaseshelper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c +index a1780ca..86c847d 100644 +--- a/src/network/leaseshelper.c ++++ b/src/network/leaseshelper.c +@@ -160,7 +160,7 @@ main(int argc, char **argv) + pid_file = g_strdup(RUNSTATEDIR "/leaseshelper.pid"); + + /* Try to claim the pidfile, exiting if we can't */ +- if ((pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) ++ if ((pid_file_fd = virPidFileAcquirePath(pid_file, true, getpid())) < 0) + goto cleanup; + + /* Since interfaces can be hot plugged, we need to make sure that the +-- +1.8.3.1 + diff --git a/generic_vdpa/libvirt/libvirt-libxl-fix-crash-when-initializing-driver.patch b/generic_vdpa/libvirt/libvirt-libxl-fix-crash-when-initializing-driver.patch new file mode 100644 index 0000000..4d295c0 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-libxl-fix-crash-when-initializing-driver.patch @@ -0,0 +1,48 @@ +From 0e95f7b912055cf254b71b0b02dcb0acf7da3870 Mon Sep 17 00:00:00 2001 +From: Jim Fehlig +Date: Fri, 3 Apr 2020 15:51:48 -0600 +Subject: [PATCH 1/8] libxl: fix crash when initializing driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 54a401af478 split out DriverConfigInit from DriverConfigNew, but +then called it a bit late from libxlStateInitialize. The cfg is used in +libxlDriverConfigLoadFile and when uninitialized results in a crash. +Calling DriverConfigInit immediately after DriverConfigNew fixes the +crash. + +Signed-off-by: Jim Fehlig +Reviewed-by: Erik Skultety +Reviewed-by: Ján Tomko +(cherry-picked from commit 88011ed2) +Signed-off-by: AlexChen +--- + src/libxl/libxl_driver.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c +index 7ec4fcc3d1..980984b199 100644 +--- a/src/libxl/libxl_driver.c ++++ b/src/libxl/libxl_driver.c +@@ -702,14 +702,14 @@ libxlStateInitialize(bool privileged, + if (!(cfg = libxlDriverConfigNew())) + goto error; + ++ if (libxlDriverConfigInit(cfg) < 0) ++ goto error; ++ + driverConf = g_strdup_printf("%s/libxl.conf", cfg->configBaseDir); + + if (libxlDriverConfigLoadFile(cfg, driverConf) < 0) + goto error; + +- if (libxlDriverConfigInit(cfg) < 0) +- goto error; +- + /* Register the callbacks providing access to libvirt's event loop */ + libxl_osevent_register_hooks(cfg->ctx, &libxl_osevent_callbacks, cfg->ctx); + +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-nodedev-fix-potential-heap-use-after-free.patch b/generic_vdpa/libvirt/libvirt-nodedev-fix-potential-heap-use-after-free.patch new file mode 100644 index 0000000..827d260 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-nodedev-fix-potential-heap-use-after-free.patch @@ -0,0 +1,48 @@ +From cdf8379fbddb8c51f35af2934908e80524a3fd6a Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Wed, 15 Apr 2020 14:03:07 +0800 +Subject: nodedev: fix potential heap use after free + +After move device enumumeration into a thread(commit 9f0ae0b18e3), +flag driversInitialized no longer represent stateInitialized finished +complete, so reference driver->devs before use it to prevent devs freed +by virStateCleanup. + +Signed-off-by: Xu Yandong +--- + src/node_device/node_device_udev.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c +index 8451903..a1391fb 100644 +--- a/src/node_device/node_device_udev.c ++++ b/src/node_device/node_device_udev.c +@@ -1261,8 +1261,8 @@ udevSetParent(struct udev_device *device, + virNodeDeviceDefPtr objdef; + + parent_device = device; ++ virObjectRef(driver->devs); + do { +- + parent_device = udev_device_get_parent(parent_device); + if (parent_device == NULL) + break; +@@ -1272,6 +1272,7 @@ udevSetParent(struct udev_device *device, + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get syspath for parent of '%s'"), + udev_device_get_syspath(parent_device)); ++ virObjectUnref(driver->devs); + return -1; + } + +@@ -1289,6 +1290,7 @@ udevSetParent(struct udev_device *device, + if (!def->parent) + def->parent = g_strdup("computer"); + ++ virObjectUnref(driver->devs); + return 0; + } + +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-po-Refresh-translation-for-running-state.patch b/generic_vdpa/libvirt/libvirt-po-Refresh-translation-for-running-state.patch new file mode 100644 index 0000000..146ef47 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-po-Refresh-translation-for-running-state.patch @@ -0,0 +1,26 @@ +From 26c64d58383d391add464b7f640fd6111f0d82d3 Mon Sep 17 00:00:00 2001 +From: Xu Yandong +Date: Wed, 15 Apr 2020 14:17:32 +0800 +Subject: po: Refresh translation for running state + +Signed-off-by: Xu Yandong +--- + po/zh_CN.mini.po | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/po/zh_CN.mini.po b/po/zh_CN.mini.po +index 94920d1..3d588ab 100644 +--- a/po/zh_CN.mini.po ++++ b/po/zh_CN.mini.po +@@ -19075,7 +19075,7 @@ msgid "rule node requires direction attribute" + msgstr "rule 节点需要 direction 属性" + + msgid "running" +-msgstr "running" ++msgstr "运行中" + + msgid "sanlock is too old to support lock failure action" + msgstr "sanlock 太旧不支持锁失败动作" +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-qemu-Revoke-access-to-mirror-on-failed-blockcopy.patch b/generic_vdpa/libvirt/libvirt-qemu-Revoke-access-to-mirror-on-failed-blockcopy.patch new file mode 100644 index 0000000..2fadfad --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-qemu-Revoke-access-to-mirror-on-failed-blockcopy.patch @@ -0,0 +1,72 @@ +From 19d06bcb3c64662d5c131a035146d2caa8c5a437 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 14 Apr 2020 11:18:02 +0200 +Subject: [PATCH 4/8] qemu: Revoke access to mirror on failed blockcopy + +When preparing to do a blockcopy, the mirror image is modified so +that QEMU can access it. For instance, the mirror has seclabels +set, if it is a NVMe disk it is detached from the host and so on. +And usually, the restore is done upon successful finish of the +blockcopy operation. But, if something fails then we need to +explicitly revoke the access to the mirror image (and thus +reattach NVMe disk back to the host). + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1822538 + +Signed-off-by: Michal Privoznik +Reviewed-by: Pavel Mores +(cherry-picked from commit 67e19fc9) +Signed-off-by: AlexChen +--- + src/qemu/qemu_driver.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 8bc5368b2f..7162875492 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -17972,6 +17972,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, + virDomainDiskDefPtr disk = NULL; + int ret = -1; + bool need_unlink = false; ++ bool need_revoke = false; + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + const char *format = NULL; + bool mirror_reuse = !!(flags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT); +@@ -18146,6 +18147,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, + + if (qemuDomainStorageSourceChainAccessAllow(driver, vm, mirror) < 0) + goto endjob; ++ need_revoke = true; + + if (blockdev) { + if (mirror_reuse) { +@@ -18254,14 +18256,17 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, + + endjob: + if (ret < 0 && +- virDomainObjIsActive(vm) && +- (data || crdata)) { +- qemuDomainObjEnterMonitor(driver, vm); +- if (data) +- qemuBlockStorageSourceChainDetach(priv->mon, data); +- if (crdata) +- qemuBlockStorageSourceAttachRollback(priv->mon, crdata->srcdata[0]); +- ignore_value(qemuDomainObjExitMonitor(driver, vm)); ++ virDomainObjIsActive(vm)) { ++ if (data || crdata) { ++ qemuDomainObjEnterMonitor(driver, vm); ++ if (data) ++ qemuBlockStorageSourceChainDetach(priv->mon, data); ++ if (crdata) ++ qemuBlockStorageSourceAttachRollback(priv->mon, crdata->srcdata[0]); ++ ignore_value(qemuDomainObjExitMonitor(driver, vm)); ++ } ++ if (need_revoke) ++ qemuDomainStorageSourceChainAccessRevoke(driver, vm, mirror); + } + if (need_unlink && virStorageFileUnlink(mirror) < 0) + VIR_WARN("%s", _("unable to remove just-created copy target")); +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-qemu-Skip-pre-creation-of-NVMe-disks.patch b/generic_vdpa/libvirt/libvirt-qemu-Skip-pre-creation-of-NVMe-disks.patch new file mode 100644 index 0000000..d1c07be --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-qemu-Skip-pre-creation-of-NVMe-disks.patch @@ -0,0 +1,53 @@ +From a7f7d8f7513af2b98d01259480f63167cf44cced Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +Date: Tue, 26 May 2020 16:26:25 +0200 +Subject: [PATCH] qemu: Skip pre-creation of NVMe disks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upon migration with disks, libvirt determines if each disk exists +on the destination and tries to pre-create missing ones. Well, +NVMe disks can't be pre-created, but they can be checked for +presence. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1823639 + +cherry-pick from commit: a5a297f387fee9e9aa4cbc2df6788c330fd33ad1 + +Signed-off-by: Michal Privoznik +Reviewed-by: Ján Tomko +Signed-off-by: Jin Yan +--- + src/qemu/qemu_migration.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 65b47ec..3f4627b 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -315,6 +315,7 @@ qemuMigrationDstPrecreateStorage(virDomainObjPtr vm, + for (i = 0; i < nbd->ndisks; i++) { + virDomainDiskDefPtr disk; + const char *diskSrcPath; ++ g_autofree char *nvmePath = NULL; + + VIR_DEBUG("Looking up disk target '%s' (capacity=%llu)", + nbd->disks[i].target, nbd->disks[i].capacity); +@@ -326,7 +327,12 @@ qemuMigrationDstPrecreateStorage(virDomainObjPtr vm, + goto cleanup; + } + +- diskSrcPath = virDomainDiskGetSource(disk); ++ if (disk->src->type == VIR_STORAGE_TYPE_NVME) { ++ virPCIDeviceAddressGetSysfsFile(&disk->src->nvme->pciAddr, &nvmePath); ++ diskSrcPath = nvmePath; ++ } else { ++ diskSrcPath = virDomainDiskGetSource(disk); ++ } + + /* Skip disks we don't want to migrate and already existing disks. */ + if (!qemuMigrationAnyCopyDisk(disk, nmigrate_disks, migrate_disks) || +-- +1.8.3.1 + diff --git a/generic_vdpa/libvirt/libvirt-qemu-add-pointer-check-in-qemuMonitorLastError.patch b/generic_vdpa/libvirt/libvirt-qemu-add-pointer-check-in-qemuMonitorLastError.patch new file mode 100644 index 0000000..d844230 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-qemu-add-pointer-check-in-qemuMonitorLastError.patch @@ -0,0 +1,32 @@ +From 2d72ad8dfbd8987379a58fd9b280cdaf4d191542 Mon Sep 17 00:00:00 2001 +From: Feng Ni +Date: Wed, 15 Apr 2020 11:14:35 +0800 +Subject: qemu: add pointer check in qemuMonitorLastError + +We found a exception when libvirt occurrs segmentation fault. +thread 1 is waiting object lock in qemuConnectMonitor, +qemu process exits and sends EOF event as well, so thread 2 invokes +qemuMonitorLastError but pointer mon is NULL. + +Signed-off-by: Feng Ni +Signed-off-by: Xu Yandong +--- + src/qemu/qemu_monitor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index a62fed8..cc62948 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -966,7 +966,7 @@ qemuMonitorSend(qemuMonitorPtr mon, + virErrorPtr + qemuMonitorLastError(qemuMonitorPtr mon) + { +- if (mon->lastError.code == VIR_ERR_OK) ++ if (!mon || mon->lastError.code == VIR_ERR_OK) + return NULL; + + return virErrorCopyNew(&mon->lastError); +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-qemu-do-not-add-model-when-actual-iface-type-is-host.patch b/generic_vdpa/libvirt/libvirt-qemu-do-not-add-model-when-actual-iface-type-is-host.patch new file mode 100644 index 0000000..c3b8255 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-qemu-do-not-add-model-when-actual-iface-type-is-host.patch @@ -0,0 +1,34 @@ +From c8a043dcdf4f04288bcfc34c25054dcef571a6a7 Mon Sep 17 00:00:00 2001 +From: Paulo de Rezende Pinatti +Date: Tue, 16 Jun 2020 16:32:10 +0200 +Subject: [PATCH] qemu: do not add model when actual iface type is hostdev + +No default model should be added to the interface +entry at post parse when its actual network type is hostdev +as doing so might cause a mismatch between the interface +definition and its actual device type. + +cherry-pick from commit: bdb8f2e41867ae5dbcc040909b1b8c20fd864a40 + +Signed-off-by: Paulo de Rezende Pinatti +Reviewed-by: Laine Stump +Signed-off-by: Jin Yan +--- + src/qemu/qemu_domain.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 91c1a49..cfada81 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -9334,6 +9334,7 @@ qemuDomainDeviceNetDefPostParse(virDomainNetDefPtr net, + virQEMUCapsPtr qemuCaps) + { + if (net->type != VIR_DOMAIN_NET_TYPE_HOSTDEV && ++ virDomainNetResolveActualType(net) != VIR_DOMAIN_NET_TYPE_HOSTDEV && + !virDomainNetGetModelString(net)) + net->model = qemuDomainDefaultNetModel(def, qemuCaps); + +-- +1.8.3.1 + diff --git a/generic_vdpa/libvirt/libvirt-qemu-fix-a-concurrent-operation-situation.patch b/generic_vdpa/libvirt/libvirt-qemu-fix-a-concurrent-operation-situation.patch new file mode 100644 index 0000000..4d6531b --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-qemu-fix-a-concurrent-operation-situation.patch @@ -0,0 +1,34 @@ +From d6cf1204db14d2ba76b640268f253d2ea6f0c131 Mon Sep 17 00:00:00 2001 +From: Feng Ni +Date: Wed, 15 Apr 2020 11:28:41 +0800 +Subject: qemu: fix a concurrent operation situation + +Migrate vm and shutdown in guestos, interface do not return occasionally. +In function qemuMigrationSrcNBDStorageCopy, it may be alays in while loop +if qemu exits. + +Signed-off-by: Feng Ni +Signed-off-by: Xu Yandong +--- + src/qemu/qemu_migration.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 8a1801d..65b47ec 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -1048,6 +1048,11 @@ qemuMigrationSrcNBDStorageCopy(virQEMUDriverPtr driver, + if (rv < 0) + return -1; + ++ if (!virDomainObjIsActive(vm)) { ++ VIR_ERROR(_("domain is no longer running, migrate will end")); ++ return -1; ++ } ++ + if (priv->job.abortJob) { + priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_CANCELED; + virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"), +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-qemu-fix-hang-in-p2p-xbzrle-compression-parallel-mig.patch b/generic_vdpa/libvirt/libvirt-qemu-fix-hang-in-p2p-xbzrle-compression-parallel-mig.patch new file mode 100644 index 0000000..5905cf7 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-qemu-fix-hang-in-p2p-xbzrle-compression-parallel-mig.patch @@ -0,0 +1,48 @@ +From f15935ea3b510bf0633dc2219a132412a7a8e96c Mon Sep 17 00:00:00 2001 +From: Lin Ma +Date: Thu, 16 Apr 2020 12:44:51 +0800 +Subject: [PATCH 3/8] qemu: fix hang in p2p + xbzrle compression + parallel + migration + +When we do parallel migration, The multifd-channels migration parameter +needs to be set on the destination side as well before incoming migration +URI, unless we accept the default number of connections(2). + +Usually, This can be correctly handled by libvirtd. But in this case if +we use p2p + xbzrle compression without parameter '--comp-xbzrle-cache', +qemuMigrationParamsDump returns too early, The corresponding migration +parameter will not be set on the destination side, It results QEMU hangs. + +Reproducer: +virsh migrate --live --p2p --comp-methods xbzrle \ +--parallel --parallel-connections 3 GUEST qemu+ssh://dsthost/system + +or + +virsh migrate --live --p2p --compressed \ +--parallel --parallel-connections 3 GUEST qemu+ssh://dsthost/system + +Signed-off-by: Lin Ma +Message-Id: <20200416044451.21134-1-lma@suse.com> +Reviewed-by: Jiri Denemark +(cherry-picked from commit 93b15ba0) +Signed-off-by: AlexChen +--- + src/qemu/qemu_migration_params.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c +index dd5e2ce1b6..810199370f 100644 +--- a/src/qemu/qemu_migration_params.c ++++ b/src/qemu/qemu_migration_params.c +@@ -630,7 +630,6 @@ qemuMigrationParamsDump(qemuMigrationParamsPtr migParams, + if (migParams->compMethods == 1ULL << QEMU_MIGRATION_COMPRESS_XBZRLE && + !migParams->params[QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE].set) { + *flags |= VIR_MIGRATE_COMPRESSED; +- return 0; + } + + for (i = 0; i < QEMU_MIGRATION_COMPRESS_LAST; ++i) { +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-qemu-fix-potential-memory-leak.patch b/generic_vdpa/libvirt/libvirt-qemu-fix-potential-memory-leak.patch new file mode 100644 index 0000000..40d03c5 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-qemu-fix-potential-memory-leak.patch @@ -0,0 +1,75 @@ +From 4f4ebf64009e402db79bf53db1226966bf5c0a99 Mon Sep 17 00:00:00 2001 +From: Feng Ni +Date: Wed, 15 Apr 2020 11:11:16 +0800 +Subject: qemu: fix potential memory leak + +function virTypedParamsAddString may return -1 but alloc params, +so invoker should free it. + +Signed-off-by: Feng Ni +Signed-off-by: Xu Yandong +--- + src/qemu/qemu_driver.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index ff97f10..8bc5368 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -5175,6 +5175,8 @@ qemuDomainPinVcpuLive(virDomainObjPtr vm, + goto cleanup; + + event = virDomainEventTunableNewFromObj(vm, eventParams, eventNparams); ++ eventParams = NULL; ++ eventNparams = 0; + + ret = 0; + +@@ -5182,6 +5184,8 @@ qemuDomainPinVcpuLive(virDomainObjPtr vm, + virBitmapFree(tmpmap); + virCgroupFree(&cgroup_vcpu); + virObjectEventStateQueue(driver->domainEventState, event); ++ if (eventParams) ++ virTypedParamsFree(eventParams, eventNparams); + return ret; + } + +@@ -5388,6 +5392,8 @@ qemuDomainPinEmulator(virDomainPtr dom, + goto endjob; + + event = virDomainEventTunableNewFromDom(dom, eventParams, eventNparams); ++ eventParams = NULL; ++ eventNparams = 0; + } + + if (persistentDef) { +@@ -5409,6 +5415,8 @@ qemuDomainPinEmulator(virDomainPtr dom, + cleanup: + if (cgroup_emulator) + virCgroupFree(&cgroup_emulator); ++ if (eventParams) ++ virTypedParamsFree(eventParams, eventNparams); + virObjectEventStateQueue(driver->domainEventState, event); + virBitmapFree(pcpumap); + virDomainObjEndAPI(&vm); +@@ -5871,6 +5879,8 @@ qemuDomainPinIOThread(virDomainPtr dom, + goto endjob; + + event = virDomainEventTunableNewFromDom(dom, eventParams, eventNparams); ++ eventParams = NULL; ++ eventNparams = 0; + } + + if (persistentDef) { +@@ -5902,6 +5912,8 @@ qemuDomainPinIOThread(virDomainPtr dom, + cleanup: + if (cgroup_iothread) + virCgroupFree(&cgroup_iothread); ++ if (eventParams) ++ virTypedParamsFree(eventParams, eventNparams); + virObjectEventStateQueue(driver->domainEventState, event); + virBitmapFree(pcpumap); + virDomainObjEndAPI(&vm); +-- +2.23.0 + diff --git a/generic_vdpa/libvirt/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch b/generic_vdpa/libvirt/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch new file mode 100644 index 0000000..0cbf3a4 --- /dev/null +++ b/generic_vdpa/libvirt/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch @@ -0,0 +1,107 @@ +From e017f95c7d833c0e9a463a1613d01fe93020606b Mon Sep 17 00:00:00 2001 +From: Jonathon Jongsma +Date: Tue, 23 Jun 2020 13:29:56 -0500 +Subject: [PATCH 5/6] qemu: format 'ramfb' attribute for mediated devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's possible to use ramfb as the boot display of an assigned vgpu +device. This was introduced in 4b95738c, but unfortunately the attribute +was not formatted into the xml output for such a device. This patch +fixes that oversight and adds a xml2xml test to verify proper behavior. + +https://bugzilla.redhat.com/show_bug.cgi?id=1847791 + +cherry pick from: c5815b31976f3982d18c7f6c1367ab6e403eb7eb + +Signed-off-by: Jonathon Jongsma +Reviewed-by: Daniel Henrique Barboza +Signed-off-by: Ján Tomko +Reviewed-by: Ján Tomko +--- + src/conf/domain_conf.c | 3 ++ + .../hostdev-mdev-display-ramfb.x86_64-latest.xml | 44 ++++++++++++++++++++++ + tests/qemuxml2xmltest.c | 1 + + 3 files changed, 48 insertions(+) + create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 37c785a..93e78a0 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -27849,6 +27849,9 @@ virDomainHostdevDefFormat(virBufferPtr buf, + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) + virBufferAsprintf(buf, " display='%s'", + virTristateSwitchTypeToString(mdevsrc->display)); ++ if (mdevsrc->ramfb != VIR_TRISTATE_SWITCH_ABSENT) ++ virBufferAsprintf(buf, " ramfb='%s'", ++ virTristateSwitchTypeToString(mdevsrc->ramfb)); + } + + } +diff --git a/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml b/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml +new file mode 100644 +index 0000000..c134400 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml +@@ -0,0 +1,44 @@ ++ ++ QEMUGuest2 ++ c7a5fdbd-edaf-9455-926a-d65c16db1809 ++ 219136 ++ 219136 ++ 1 ++ ++ hvm ++ ++ ++ ++ qemu64 ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-i386 ++ ++

++ ++ ++ ++
++ ++ ++ ++ ++ ++ ++