diff --git a/Add-bios-path-for-loongarch.patch b/Add-bios-path-for-loongarch.patch new file mode 100644 index 0000000000000000000000000000000000000000..05ee8ff11df853eabbb2897174d2ea1958363c5b --- /dev/null +++ b/Add-bios-path-for-loongarch.patch @@ -0,0 +1,57 @@ +From 09616f083df506ad60100c16b5d4a9cdd9b40b57 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Thu, 17 Aug 2023 04:28:13 -0400 +Subject: [PATCH 5/5] Add bios path for loongarch + +Add a default BIOS file name for Loongarch. + +Signed-off-by: lixianglai +--- + src/qemu/qemu.conf.in | 3 ++- + src/qemu/qemu_conf.c | 3 ++- + src/qemu/test_libvirtd_qemu.aug.in | 1 + + 3 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu.conf.in b/src/qemu/qemu.conf.in +index 3895d42..44c1696 100644 +--- a/src/qemu/qemu.conf.in ++++ b/src/qemu/qemu.conf.in +@@ -840,7 +840,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_conf.c b/src/qemu/qemu_conf.c +index d9460d8..102c2ad 100644 +--- a/src/qemu/qemu_conf.c ++++ b/src/qemu/qemu_conf.c +@@ -93,7 +93,8 @@ VIR_ONCE_GLOBAL_INIT(virQEMUConfig); + "/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/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in +index 1dbd692..eb763dc 100644 +--- a/src/qemu/test_libvirtd_qemu.aug.in ++++ b/src/qemu/test_libvirtd_qemu.aug.in +@@ -99,6 +99,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.27.0 + diff --git a/Add-loongarch-cpu-model-and-vendor-info.patch b/Add-loongarch-cpu-model-and-vendor-info.patch new file mode 100644 index 0000000000000000000000000000000000000000..1409bdaceb79a26066a59c0f3670ec9d9fa9d2c5 --- /dev/null +++ b/Add-loongarch-cpu-model-and-vendor-info.patch @@ -0,0 +1,69 @@ +From 3d80718fb56a2e1495785f9d1a24c0f1347cfaae Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 28 Jul 2023 02:51:11 -0400 +Subject: [PATCH 2/5] Add loongarch cpu model and vendor info + +Define loongarch cpu model type and vendor id in +cpu_map/loongarch.xml + +Signed-off-by: lixianglai +--- + src/cpu_map/index.xml | 5 +++++ + src/cpu_map/loongarch_3a5000.xml | 6 ++++++ + src/cpu_map/loongarch_vendors.xml | 3 +++ + src/cpu_map/meson.build | 2 ++ + 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/index.xml b/src/cpu_map/index.xml +index deae925..d92fe0c 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -117,4 +117,9 @@ + + + ++ ++ ++ ++ ++ + +diff --git a/src/cpu_map/loongarch_3a5000.xml b/src/cpu_map/loongarch_3a5000.xml +new file mode 100644 +index 0000000..f6fe338 +--- /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 0000000..c744654 +--- /dev/null ++++ b/src/cpu_map/loongarch_vendors.xml +@@ -0,0 +1,3 @@ ++ ++ ++ +diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build +index 55c3703..79b2b39 100644 +--- a/src/cpu_map/meson.build ++++ b/src/cpu_map/meson.build +@@ -82,6 +82,8 @@ cpumap_data = [ + 'x86_vendors.xml', + 'x86_Westmere-IBRS.xml', + 'x86_Westmere.xml', ++ 'loongarch_vendors.xml', ++ 'loongarch_3a5000.xml', + ] + + install_data(cpumap_data, install_dir: pkgdatadir / 'cpu_map') +-- +2.27.0 + diff --git a/Add-loongarch-cpu-support.patch b/Add-loongarch-cpu-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..8d440fe79b0bc8106b9a1f992f7f1a29fc220443 --- /dev/null +++ b/Add-loongarch-cpu-support.patch @@ -0,0 +1,993 @@ +From 8f0ce843cfecb4786ac527434cee15e8f36aff4d Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 28 Jul 2023 02:45:55 -0400 +Subject: [PATCH 1/5] Add loongarch cpu support + +Add loongarch cpu support: Define new cpu type 'loongarch64' +and implement it's driver functions. + +Signed-off-by: lixianglai +--- + po/POTFILES | 1 + + src/conf/schemas/basictypes.rng | 1 + + src/cpu/cpu.c | 2 + + src/cpu/cpu.h | 2 + + src/cpu/cpu_loongarch.c | 745 ++++++++++++++++++++++++++++++++ + src/cpu/cpu_loongarch.h | 25 ++ + src/cpu/cpu_loongarch_data.h | 37 ++ + src/cpu/meson.build | 1 + + src/qemu/qemu_capabilities.c | 1 + + src/qemu/qemu_domain.c | 4 + + src/util/virarch.c | 2 + + src/util/virarch.h | 4 + + 12 files changed, 825 insertions(+) + 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/po/POTFILES b/po/POTFILES +index b122f02..ad74296 100644 +--- a/po/POTFILES ++++ b/po/POTFILES +@@ -70,6 +70,7 @@ src/cpu/cpu.c + src/cpu/cpu_arm.c + src/cpu/cpu_map.c + src/cpu/cpu_ppc64.c ++src/cpu/cpu_loongarch.c + src/cpu/cpu_s390.c + src/cpu/cpu_x86.c + src/datatypes.c +diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng +index 2d6f1a2..053206d 100644 +--- a/src/conf/schemas/basictypes.rng ++++ b/src/conf/schemas/basictypes.rng +@@ -470,6 +470,7 @@ + x86_64 + xtensa + xtensaeb ++ loongarch64 + + + +diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c +index bb5737e..1741a34 100644 +--- a/src/cpu/cpu.c ++++ b/src/cpu/cpu.c +@@ -27,6 +27,7 @@ + #include "cpu_ppc64.h" + #include "cpu_s390.h" + #include "cpu_arm.h" ++#include "cpu_loongarch.h" + #include "cpu_riscv64.h" + #include "capabilities.h" + +@@ -41,6 +42,7 @@ static struct cpuArchDriver *drivers[] = { + &cpuDriverS390, + &cpuDriverArm, + &cpuDriverRiscv64, ++ &cpuDriverLoongArch, + }; + + +diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h +index a4cdb37..9ec0a10 100644 +--- a/src/cpu/cpu.h ++++ b/src/cpu/cpu.h +@@ -27,6 +27,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; +@@ -36,6 +37,7 @@ struct _virCPUData { + virCPUx86Data x86; + virCPUppc64Data ppc64; + virCPUarmData arm; ++ virCPULoongArchData loongarch; + /* generic driver needs no data */ + } data; + }; +diff --git a/src/cpu/cpu_loongarch.c b/src/cpu/cpu_loongarch.c +new file mode 100644 +index 0000000..a6462dd +--- /dev/null ++++ b/src/cpu/cpu_loongarch.c +@@ -0,0 +1,745 @@ ++/* ++ * 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 "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 _virCPULoongArchVendor virCPULoongArchVendor; ++struct _virCPULoongArchVendor { ++ char *name; ++}; ++ ++typedef struct _virCPULoongArchModel virCPULoongArchModel; ++struct _virCPULoongArchModel { ++ char *name; ++ const virCPULoongArchVendor *vendor; ++ virCPULoongArchData data; ++}; ++ ++typedef struct _virCPULoongArchMap virCPULoongArchMap; ++struct _virCPULoongArchMap { ++ size_t nvendors; ++ virCPULoongArchVendor **vendors; ++ size_t nmodels; ++ virCPULoongArchModel **models; ++}; ++ ++static void ++virCPULoongArchDataClear(virCPULoongArchData *data) ++{ ++ if (!data) ++ return; ++ ++ VIR_FREE(data->prid); ++} ++ ++static int ++virCPULoongArchDataCopy(virCPULoongArchData *dst, ++ const virCPULoongArchData *src) ++{ ++ size_t i; ++ ++ dst->prid = g_new0(virCPULoongArchPrid, src->len); ++ if (!dst->prid) ++ 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 ++virCPULoongArchVendorFree(virCPULoongArchVendor *vendor) ++{ ++ if (!vendor) ++ return; ++ ++ VIR_FREE(vendor->name); ++ VIR_FREE(vendor); ++} ++ ++static virCPULoongArchVendor * ++virCPULoongArchVendorFind(const virCPULoongArchMap *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 ++virCPULoongArchModelFree(virCPULoongArchModel *model) ++{ ++ if (!model) ++ return; ++ ++ virCPULoongArchDataClear(&model->data); ++ VIR_FREE(model->name); ++ VIR_FREE(model); ++} ++ ++static virCPULoongArchModel * ++virCPULoongArchModelCopy(const virCPULoongArchModel *model) ++{ ++ virCPULoongArchModel *copy; ++ ++ copy = g_new0(virCPULoongArchModel, 1); ++ if (!copy) ++ goto cleanup; ++ ++ copy->name = g_strdup(model->name); ++ ++ if (virCPULoongArchDataCopy(©->data, &model->data) < 0) ++ goto cleanup; ++ ++ copy->vendor = model->vendor; ++ ++ return copy; ++ ++ cleanup: ++ virCPULoongArchModelFree(copy); ++ return NULL; ++} ++ ++static virCPULoongArchModel * ++virCPULoongArchModelFind(const virCPULoongArchMap *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 virCPULoongArchModel * ++virCPULoongArchModelFindPrid(const virCPULoongArchMap *map, ++ uint32_t prid) ++{ ++ size_t i; ++ size_t j; ++ ++ for (i = 0; i < map->nmodels; i++) { ++ virCPULoongArchModel *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 virCPULoongArchModel * ++virCPULoongArchModelFromCPU(const virCPUDef *cpu, ++ const virCPULoongArchMap *map) ++{ ++ virCPULoongArchModel *model; ++ ++ if (!cpu->model) { ++ virReportError(VIR_ERR_INVALID_ARG, "%s", ++ _("no CPU model specified")); ++ return NULL; ++ } ++ ++ if (!(model = virCPULoongArchModelFind(map, cpu->model))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown CPU model %1$s"), cpu->model); ++ return NULL; ++ } ++ ++ return virCPULoongArchModelCopy(model); ++} ++ ++static void ++virCPULoongArchMapFree(virCPULoongArchMap *map) ++{ ++ size_t i; ++ ++ if (!map) ++ return; ++ ++ for (i = 0; i < map->nmodels; i++) ++ virCPULoongArchModelFree(map->models[i]); ++ VIR_FREE(map->models); ++ ++ for (i = 0; i < map->nvendors; i++) ++ virCPULoongArchVendorFree(map->vendors[i]); ++ VIR_FREE(map->vendors); ++ ++ VIR_FREE(map); ++} ++ ++static int ++virCPULoongArchVendorParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED, ++ const char *name, ++ void *data) ++{ ++ virCPULoongArchMap *map = data; ++ virCPULoongArchVendor *vendor; ++ int ret = -1; ++ ++ vendor = g_new0(virCPULoongArchVendor, 1); ++ if (!vendor) ++ return ret; ++ vendor->name = g_strdup(name); ++ ++ if (virCPULoongArchVendorFind(map, vendor->name)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("CPU vendor %1$s already defined"), vendor->name); ++ goto cleanup; ++ } ++ ++ VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor); ++ ++ ret = 0; ++ ++ cleanup: ++ virCPULoongArchVendorFree(vendor); ++ return ret; ++} ++ ++static int ++virCPULoongArchModelParse(xmlXPathContextPtr ctxt, ++ const char *name, ++ void *data) ++{ ++ virCPULoongArchMap *map = data; ++ virCPULoongArchModel *model; ++ xmlNodePtr *nodes = NULL; ++ char *vendor = NULL; ++ uint32_t prid; ++ size_t i; ++ int n; ++ int ret = -1; ++ ++ model = g_new0(virCPULoongArchModel, 1); ++ if (!model) ++ goto cleanup; ++ ++ model->name = g_strdup(name); ++ ++ if (virCPULoongArchModelFind(map, model->name)) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("CPU model %1$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 %1$s"), ++ model->name); ++ goto cleanup; ++ } ++ ++ if (!(model->vendor = virCPULoongArchVendorFind(map, vendor))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown vendor %1$s referenced by CPU model %2$s"), ++ vendor, model->name); ++ goto cleanup; ++ } ++ } ++ ++ if ((n = virXPathNodeSet("./prid", ctxt, &nodes)) <= 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing Prid information for CPU model %1$s"), ++ model->name); ++ goto cleanup; ++ } ++ ++ model->data.prid = g_new0(virCPULoongArchPrid, n); ++ if (!model->data.prid) ++ goto cleanup; ++ ++ model->data.len = n; ++ ++ for (i = 0; i < n; i++) { ++ ++ if (virXMLPropUInt(nodes[i], "value", 16, VIR_XML_PROP_REQUIRED, ++ &prid) < 0) ++ { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing or invalid Prid value in CPU model %1$s"), ++ model->name); ++ goto cleanup; ++ } ++ model->data.prid[i].value = prid; ++ ++ if (virXMLPropUInt(nodes[i], "mask", 16, VIR_XML_PROP_REQUIRED, ++ &prid) < 0) ++ { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Missing or invalid PVR mask in CPU model %1$s"), ++ model->name); ++ goto cleanup; ++ } ++ model->data.prid[i].mask = prid; ++ } ++ ++ VIR_APPEND_ELEMENT(map->models, map->nmodels, model); ++ ++ ret = 0; ++ ++ cleanup: ++ virCPULoongArchModelFree(model); ++ VIR_FREE(vendor); ++ VIR_FREE(nodes); ++ return ret; ++} ++ ++static virCPULoongArchMap * ++virCPULoongArchLoadMap(void) ++{ ++ virCPULoongArchMap *map; ++ ++ map = g_new0(virCPULoongArchMap, 1); ++ if (!map) ++ goto cleanup; ++ ++ if (cpuMapLoad("loongarch64", virCPULoongArchVendorParse, NULL, ++ virCPULoongArchModelParse, map) < 0) ++ goto cleanup; ++ ++ return map; ++ ++ cleanup: ++ virCPULoongArchMapFree(map); ++ return NULL; ++} ++ ++static virCPUData * ++virCPULoongArchMakeCPUData(virArch arch, ++ virCPULoongArchData *data) ++{ ++ virCPUData * cpuData; ++ ++ cpuData = g_new0(virCPUData, 1); ++ if (!cpuData) ++ return NULL; ++ ++ cpuData->arch = arch; ++ ++ if (virCPULoongArchDataCopy(&cpuData->data.loongarch, data) < 0) ++ VIR_FREE(cpuData); ++ ++ return cpuData; ++} ++ ++static virCPUCompareResult ++virCPULoongArchCompute(virCPUDef *host, ++ const virCPUDef *other, ++ virCPUData **guestData, ++ char **message) ++{ ++ virCPULoongArchMap *map = NULL; ++ virCPULoongArchModel *host_model = NULL; ++ virCPULoongArchModel *guest_model = NULL; ++ virCPUDef *cpu = NULL; ++ virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR; ++ virArch arch; ++ size_t i; ++ ++ /* Ensure existing configurations are handled correctly */ ++ if (!(cpu = virCPUDefCopy(other))) ++ goto cleanup; ++ ++ if (cpu->arch != VIR_ARCH_NONE) { ++ bool found = false; ++ ++ for (i = 0; i < G_N_ELEMENTS(archs); i++) { ++ if (archs[i] == cpu->arch) { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) { ++ VIR_DEBUG("CPU arch %s does not match host arch", ++ virArchToString(cpu->arch)); ++ if (message) { ++ *message = g_strdup_printf(_("CPU arch %1$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 = virCPULoongArchLoadMap())) ++ goto cleanup; ++ ++ /* Host CPU information */ ++ if (!(host_model = virCPULoongArchModelFromCPU(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 = virCPULoongArchModelCopy(host_model); ++ break; ++ ++ case VIR_CPU_MODE_CUSTOM: ++ /* custom: ++ * look up guest CPU information */ ++ guest_model = virCPULoongArchModelFromCPU(cpu, map); ++ break; ++ } ++ } else { ++ /* Other host CPU information */ ++ guest_model = virCPULoongArchModelFromCPU(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 = virCPULoongArchMakeCPUData(arch, &guest_model->data))) ++ goto cleanup; ++ ++ ret = VIR_CPU_COMPARE_IDENTICAL; ++ ++ cleanup: ++ virCPUDefFree(cpu); ++ virCPULoongArchMapFree(map); ++ virCPULoongArchModelFree(host_model); ++ virCPULoongArchModelFree(guest_model); ++ return ret; ++} ++ ++static virCPUCompareResult ++virCPULoongArchCompare(virCPUDef *host, ++ virCPUDef *cpu, ++ bool failIncompatible) ++{ ++ virCPUCompareResult ret; ++ char *message = NULL; ++ ++ if (!host || !host->model) { ++ if (failIncompatible) { ++ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", ++ _("unknown host CPU")); ++ } else { ++ VIR_WARN("unknown host CPU"); ++ ret = VIR_CPU_COMPARE_INCOMPATIBLE; ++ } ++ return -1; ++ } ++ ++ ret = virCPULoongArchCompute(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 ++virCPULoongArchDriverDecode(virCPUDef *cpu, ++ const virCPUData *data, ++ virDomainCapsCPUModels *models) ++{ ++ int ret = -1; ++ virCPULoongArchMap *map; ++ const virCPULoongArchModel *model; ++ ++ if (!data || !(map = virCPULoongArchLoadMap())) ++ return -1; ++ ++ if (!(model = virCPULoongArchModelFindPrid(map, data->data.loongarch.prid[0].value))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("Cannot find CPU model with Prid 0x%1$08x"), ++ data->data.loongarch.prid[0].value); ++ goto cleanup; ++ } ++ ++ if (!virCPUModelIsAllowed(model->name, models)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("CPU model %1$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: ++ virCPULoongArchMapFree(map); ++ ++ return ret; ++} ++ ++static void ++virCPULoongArchDataFree(virCPUData *data) ++{ ++ if (!data) ++ return; ++ ++ virCPULoongArchDataClear(&data->data.loongarch); ++ VIR_FREE(data); ++} ++ ++static int ++virCPULoongArchGetHostPRID(void) ++{ ++ return 0x14c010; ++} ++ ++static int ++virCPULoongArchGetHost(virCPUDef *cpu, ++ virDomainCapsCPUModels *models) ++{ ++ virCPUData *cpuData = NULL; ++ virCPULoongArchData *data; ++ int ret = -1; ++ ++ if (!(cpuData = virCPUDataNew(archs[0]))) ++ goto cleanup; ++ ++ data = &cpuData->data.loongarch; ++ data->prid = g_new0(virCPULoongArchPrid, 1); ++ if (!data->prid) ++ goto cleanup; ++ ++ ++ data->len = 1; ++ ++ data->prid[0].value = virCPULoongArchGetHostPRID(); ++ data->prid[0].mask = 0xffff00ul; ++ ++ ret = virCPULoongArchDriverDecode(cpu, cpuData, models); ++ ++ cleanup: ++ virCPULoongArchDataFree(cpuData); ++ return ret; ++} ++ ++ ++static int ++virCPULoongArchUpdate(virCPUDef *guest, ++ const virCPUDef *host ATTRIBUTE_UNUSED, ++ bool relative G_GNUC_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 virCPUDef * ++virCPULoongArchDriverBaseline(virCPUDef **cpus, ++ unsigned int ncpus, ++ virDomainCapsCPUModels *models ATTRIBUTE_UNUSED, ++ const char **features ATTRIBUTE_UNUSED, ++ bool migratable ATTRIBUTE_UNUSED) ++{ ++ virCPULoongArchMap *map; ++ const virCPULoongArchModel *model; ++ const virCPULoongArchVendor *vendor = NULL; ++ virCPUDef *cpu = NULL; ++ size_t i; ++ ++ if (!(map = virCPULoongArchLoadMap())) ++ goto error; ++ ++ if (!(model = virCPULoongArchModelFind(map, cpus[0]->model))) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Unknown CPU model %1$s"), cpus[0]->model); ++ goto error; ++ } ++ ++ for (i = 0; i < ncpus; i++) { ++ const virCPULoongArchVendor *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 = virCPULoongArchVendorFind(map, cpus[i]->vendor))) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("Unknown CPU vendor %1$s"), cpus[i]->vendor); ++ goto error; ++ } ++ ++ if (model->vendor) { ++ if (model->vendor != vnd) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("CPU vendor %1$s of model %2$s differs from " ++ "vendor %3$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: ++ virCPULoongArchMapFree(map); ++ return cpu; ++ ++ error: ++ virCPUDefFree(cpu); ++ cpu = NULL; ++ goto cleanup; ++} ++ ++static int ++virCPULoongArchDriverGetModels(char ***models) ++{ ++ virCPULoongArchMap *map; ++ size_t i; ++ int ret = -1; ++ ++ if (!(map = virCPULoongArchLoadMap())) { ++ return -1; ++ } ++ ++ if (models) { ++ *models = g_new0(char *, map->nmodels + 1); ++ if (!(*models)) ++ return -1; ++ ++ for (i = 0; i < map->nmodels; i++) { ++ (*models)[i] = g_strdup(map->models[i]->name); ++ } ++ } ++ ++ ret = map->nmodels; ++ ++ return ret; ++} ++ ++struct cpuArchDriver cpuDriverLoongArch = { ++ .name = "LoongArch", ++ .arch = archs, ++ .narch = G_N_ELEMENTS(archs), ++ .compare = virCPULoongArchCompare, ++ .decode = virCPULoongArchDriverDecode, ++ .encode = NULL, ++ .dataFree = virCPULoongArchDataFree, ++ .getHost = virCPULoongArchGetHost, ++ .baseline = virCPULoongArchDriverBaseline, ++ .update = virCPULoongArchUpdate, ++ .getModels = virCPULoongArchDriverGetModels, ++}; +diff --git a/src/cpu/cpu_loongarch.h b/src/cpu/cpu_loongarch.h +new file mode 100644 +index 0000000..bebc16a +--- /dev/null ++++ b/src/cpu/cpu_loongarch.h +@@ -0,0 +1,25 @@ ++/* ++ * 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 ++ * . ++ */ ++ ++#pragma once ++ ++# include "cpu.h" ++ ++extern struct cpuArchDriver cpuDriverLoongArch; +diff --git a/src/cpu/cpu_loongarch_data.h b/src/cpu/cpu_loongarch_data.h +new file mode 100644 +index 0000000..43ae044 +--- /dev/null ++++ b/src/cpu/cpu_loongarch_data.h +@@ -0,0 +1,37 @@ ++/* ++ * 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 ++ * . ++ */ ++ ++#pragma once ++ ++# 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; ++}; +diff --git a/src/cpu/meson.build b/src/cpu/meson.build +index 5539690..254d6b4 100644 +--- a/src/cpu/meson.build ++++ b/src/cpu/meson.build +@@ -6,6 +6,7 @@ cpu_sources = [ + 'cpu_riscv64.c', + 'cpu_s390.c', + 'cpu_x86.c', ++ 'cpu_loongarch.c', + ] + + cpu_lib = static_library( +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index cf85d42..12dcfad 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2728,6 +2728,7 @@ static const char *preferredMachines[] = + + "sim", /* VIR_ARCH_XTENSA */ + "sim", /* VIR_ARCH_XTENSAEB */ ++ "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 d556e21..36fc062 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -4183,6 +4183,10 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver, + addPCIRoot = 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 2134dd6..3765ecf 100644 +--- a/src/util/virarch.c ++++ b/src/util/virarch.c +@@ -83,6 +83,8 @@ static const struct virArchData { + + { "xtensa", 32, VIR_ARCH_LITTLE_ENDIAN }, + { "xtensaeb", 32, VIR_ARCH_BIG_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 81b1b27..2ace17c 100644 +--- a/src/util/virarch.h ++++ b/src/util/virarch.h +@@ -69,6 +69,8 @@ typedef enum { + VIR_ARCH_XTENSA, /* XTensa 32 LE https://en.wikipedia.org/wiki/Xtensa#Processor_Cores */ + VIR_ARCH_XTENSAEB, /* XTensa 32 BE https://en.wikipedia.org/wiki/Xtensa#Processor_Cores */ + ++ VIR_ARCH_LOONGARCH64, /* LoongArch 64 LE */ ++ + VIR_ARCH_LAST, + } virArch; + +@@ -103,6 +105,8 @@ typedef enum { + #define ARCH_IS_MIPS64(arch) ((arch) == VIR_ARCH_MIPS64 ||\ + (arch) == VIR_ARCH_MIPS64EL) + ++#define ARCH_IS_LOONGARCH(arch) ((arch) == VIR_ARCH_LOONGARCH64) ++ + typedef enum { + VIR_ARCH_LITTLE_ENDIAN, + VIR_ARCH_BIG_ENDIAN, +-- +2.27.0 + diff --git a/Config-some-capabilities-for-loongarch-virt-machine.patch b/Config-some-capabilities-for-loongarch-virt-machine.patch new file mode 100644 index 0000000000000000000000000000000000000000..5af90f164f71adc1ec92d98b6773cab67b252287 --- /dev/null +++ b/Config-some-capabilities-for-loongarch-virt-machine.patch @@ -0,0 +1,197 @@ +From b8832257742fd815185c7d04853df41981e34dc1 Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 28 Jul 2023 03:18:44 -0400 +Subject: [PATCH 3/5] 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: lixianglai +--- + src/qemu/qemu_capabilities.c | 5 ++++ + src/qemu/qemu_domain.c | 31 ++++++++++++++++++- + src/qemu/qemu_domain.h | 1 + + src/qemu/qemu_domain_address.c | 55 ++++++++++++++++++++++++++++++++++ + src/qemu/qemu_validate.c | 2 +- + 5 files changed, 92 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 12dcfad..a319dbc 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -2080,6 +2080,11 @@ bool virQEMUCapsHasPCIMultiBus(const virDomainDef *def) + return true; + } + ++ /* loongarch64 support PCI-multibus on all machine types ++ * since forever */ ++ if (ARCH_IS_LOONGARCH(def->os.arch)) ++ return true; ++ + return false; + } + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 36fc062..c3a1f7f 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -5501,6 +5501,11 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont, + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; + else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) + cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; ++ } else if (ARCH_IS_LOONGARCH(def->os.arch)) { ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI)) ++ cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI; ++ else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI)) ++ cont->model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI; + } + } + /* forbid usb model 'qusb1' and 'qusb2' in this kind of hyperviosr */ +@@ -8978,6 +8983,22 @@ qemuDomainMachineIsPSeries(const char *machine, + } + + ++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; ++} ++ ++ + static bool + qemuDomainMachineIsMipsMalta(const char *machine, + const virArch arch) +@@ -9001,7 +9022,8 @@ qemuDomainMachineHasBuiltinIDE(const char *machine, + return qemuDomainMachineIsI440FX(machine, arch) || + STREQ(machine, "malta") || + STREQ(machine, "sun4u") || +- STREQ(machine, "g3beige"); ++ STREQ(machine, "g3beige") || ++ STREQ(machine, "loongson7a"); + } + + +@@ -9071,6 +9093,13 @@ qemuDomainIsMipsMalta(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 eaa75de..c8e62f0 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -842,6 +842,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 qemuDomainIsMipsMalta(const virDomainDef *def); + bool qemuDomainHasPCIRoot(const virDomainDef *def); + bool qemuDomainHasPCIeRoot(const virDomainDef *def); +diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c +index 49c5e19..84be2a0 100644 +--- a/src/qemu/qemu_domain_address.c ++++ b/src/qemu/qemu_domain_address.c +@@ -2073,6 +2073,56 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDef *def, + } + + ++static int ++qemuDomainValidateDevicePCISlotsLoongson(virDomainDef *def, ++ virDomainPCIAddressSet *addrs) ++{ ++ virPCIDeviceAddress tmp_addr; ++ 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 */ ++ virDomainVideoDef *primaryVideo = def->videos[0]; ++ ++ if (virDeviceInfoPCIAddressIsWanted(&primaryVideo->info)) { ++ memset(&tmp_addr, 0, sizeof(tmp_addr)); ++ tmp_addr.slot = 2; ++ ++ if (!(addrStr = virPCIDeviceAddressAsString(&tmp_addr))) ++ return -1; ++ if (!virDomainPCIAddressValidate(addrs, &tmp_addr, ++ addrStr, flags, true)) ++ return -1; ++ ++ if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { ++ if (qemuDomainPCIAddressReserveNextAddr(addrs, ++ &primaryVideo->info) < 0) { ++ return -1; ++ } ++ } else { ++ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, 0) < 0) ++ return -1; ++ primaryVideo->info.addr.pci = tmp_addr; ++ primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++ + static int + qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def, + virDomainPCIAddressSet *addrs) +@@ -2087,6 +2137,11 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDef *def, + return -1; + } + ++ if (qemuDomainIsLoongson(def) && ++ qemuDomainValidateDevicePCISlotsLoongson(def, addrs) < 0) { ++ return -1; ++ } ++ + return 0; + } + +diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c +index da4b9a3..d6f6273 100644 +--- a/src/qemu/qemu_validate.c ++++ b/src/qemu/qemu_validate.c +@@ -100,7 +100,7 @@ qemuValidateDomainDefFeatures(const virDomainDef *def, + switch ((virDomainFeature) i) { + case VIR_DOMAIN_FEATURE_IOAPIC: + if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) { +- if (!ARCH_IS_X86(def->os.arch)) { ++ if (!ARCH_IS_X86(def->os.arch) && !ARCH_IS_LOONGARCH(def->os.arch)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("The '%1$s' feature is not supported for architecture '%2$s' or machine type '%3$s'"), + featureName, +-- +2.27.0 + diff --git a/Fix-the-compile-error.patch b/Fix-the-compile-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..9eceb754e88a96b9049b9e543d8ff2539e77e02d --- /dev/null +++ b/Fix-the-compile-error.patch @@ -0,0 +1,29 @@ +From ec37c1993a9f1e752a5ce2f57275757a2e60a300 Mon Sep 17 00:00:00 2001 +From: xianglai li +Date: Mon, 23 Oct 2023 02:01:58 +0000 +Subject: [PATCH] Fix the compile error + +Fix compilation issues caused by changes to libssh2 +structure LIBSSH2_USERAUTH_KBDINT_PROMPT. + +Signed-off-by: xianglai li +--- + src/rpc/virnetsshsession.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/rpc/virnetsshsession.c b/src/rpc/virnetsshsession.c +index f848058..6045ccb 100644 +--- a/src/rpc/virnetsshsession.c ++++ b/src/rpc/virnetsshsession.c +@@ -217,7 +217,7 @@ virNetSSHKbIntCb(const char *name G_GNUC_UNUSED, + /* fill data structures for auth callback */ + for (i = 0; i < num_prompts; i++) { + char *prompt; +- prompt = g_strdup(prompts[i].text); ++ prompt = g_strdup((char *)prompts[i].text); + askcred[i].prompt = prompt; + + /* remove colon and trailing spaces from prompts, as default behavior +-- +2.40.1 + diff --git a/Implement-the-method-of-getting-host-info-for-loonga.patch b/Implement-the-method-of-getting-host-info-for-loonga.patch new file mode 100644 index 0000000000000000000000000000000000000000..6f4cf8709d55d4658bf8d7d9a1bed186e579986b --- /dev/null +++ b/Implement-the-method-of-getting-host-info-for-loonga.patch @@ -0,0 +1,75 @@ +From a119d517af97d90e21435d486ddb88d04302b24e Mon Sep 17 00:00:00 2001 +From: lixianglai +Date: Fri, 28 Jul 2023 03:27:41 -0400 +Subject: [PATCH 4/5] 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: lixianglai +--- + src/util/virarch.c | 2 ++ + src/util/virhostcpu.c | 4 ++-- + src/util/virsysinfo.c | 5 +++-- + 3 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/util/virarch.c b/src/util/virarch.c +index 3765ecf..09edece 100644 +--- a/src/util/virarch.c ++++ b/src/util/virarch.c +@@ -224,6 +224,8 @@ virArch virArchFromHost(void) + arch = VIR_ARCH_X86_64; + } else if (STREQ(ut.machine, "arm64")) { + arch = VIR_ARCH_AARCH64; ++ } else if (STREQ(ut.machine, "loongarch64")) { ++ arch = VIR_ARCH_LOONGARCH64; + } else { + /* Otherwise assume the canonical name */ + if ((arch = virArchFromString(ut.machine)) == VIR_ARCH_NONE) { +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index 19195a1..ca57af3 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -544,7 +544,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)) +@@ -579,7 +579,7 @@ virHostCPUParsePhysAddrSize(FILE *cpuinfo, unsigned int *addrsz) + char *str; + char *endptr; + +- if (!(str = STRSKIP(line, "address sizes"))) ++ if (!(str = STRCASESKIP(line, "address sizes"))) + continue; + + /* Skip the colon. */ +diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c +index 36a861c..3a09497 100644 +--- a/src/util/virsysinfo.c ++++ b/src/util/virsysinfo.c +@@ -1241,14 +1241,15 @@ 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(); + #elif !defined(WIN32) && \ + (defined(__x86_64__) || \ + defined(__i386__) || \ +- defined(__amd64__)) ++ defined(__amd64__) || \ ++ defined(__loongarch__)) + return virSysinfoReadDMI(); + #else /* WIN32 || not supported arch */ + /* +-- +2.27.0 + diff --git a/libvirt.spec b/libvirt.spec index 628a8fb10d0eea1b6f64d6bd63b79d20593f06fe..40419c79515ede3dc8d76c906549416857ea6c10 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -1,8 +1,8 @@ -%define anolis_release 1 +%define anolis_release 2 -%define arches_qemu_kvm x86_64 aarch64 +%define arches_qemu_kvm x86_64 aarch64 loongarch64 -%define arches_64bit x86_64 aarch64 riscv64 +%define arches_64bit x86_64 aarch64 riscv64 loongarch64 %define arches_x86 x86_64 %define arches_systemtap_64bit %{arches_64bit} @@ -161,6 +161,13 @@ URL: https://libvirt.org/ %endif Source: https://download.libvirt.org/libvirt-%{version}.tar.xz +Patch0000: Add-loongarch-cpu-support.patch +Patch0001: Add-loongarch-cpu-model-and-vendor-info.patch +Patch0002: Config-some-capabilities-for-loongarch-virt-machine.patch +Patch0003: Implement-the-method-of-getting-host-info-for-loonga.patch +Patch0004: Add-bios-path-for-loongarch.patch +Patch0005: Fix-the-compile-error.patch + Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} Requires: libvirt-daemon-config-nwfilter = %{version}-%{release} @@ -2133,6 +2140,9 @@ exit 0 %changelog +* Mon Aug 28 2023 lixianglai - 9.3.0-2 +- Add loongarch support for libvirt + * Wed May 03 2023 Funda Wang - 9.3.0-1 - New version 9.3.0