!217 libvirt update to version 6.2.0-52
From: @Mayunlong541 Reviewed-by: @yezengruan Signed-off-by: @yezengruan
This commit is contained in:
commit
4157a39461
69
Add-loongarch-cpu-model-and-vendor-info.patch
Normal file
69
Add-loongarch-cpu-model-and-vendor-info.patch
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
From 55c7dc34b8ff1a75bb011ca783b6cd3c7f1a5643 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhaotianrui <zhaotianrui@loongson.cn>
|
||||||
|
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 <zhaotianrui@loongson.cn>
|
||||||
|
---
|
||||||
|
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 @@
|
||||||
|
<include filename='arm_FT-2000plus.xml'/>
|
||||||
|
<include filename='arm_Tengyun-S2500.xml'/>
|
||||||
|
</arch>
|
||||||
|
+
|
||||||
|
+ <arch name='loongarch64'>
|
||||||
|
+ <include filename="loongarch_vendors.xml"/>
|
||||||
|
+ <include filename="loongarch_3a5000.xml"/>
|
||||||
|
+ </arch>
|
||||||
|
</cpus>
|
||||||
|
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 @@
|
||||||
|
+<cpus>
|
||||||
|
+ <model name='Loongson-3A5000'>
|
||||||
|
+ <vendor name='Loongson'/>
|
||||||
|
+ <prid value='0x14c010' mask='0xfffff0'/>
|
||||||
|
+ </model>
|
||||||
|
+</cpus>
|
||||||
|
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 @@
|
||||||
|
+<cpus>
|
||||||
|
+ <vendor name='Loongson'/>
|
||||||
|
+</cpus>
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
994
Add-loongarch-cpu-support.patch
Normal file
994
Add-loongarch-cpu-support.patch
Normal file
@ -0,0 +1,994 @@
|
|||||||
|
From c0b26612cf12d5f0594a9dfa5bd97fcf7acfe9da Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhaotianrui <zhaotianrui@loongson.cn>
|
||||||
|
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 <zhaotianrui@loongson.cn>
|
||||||
|
---
|
||||||
|
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 @@
|
||||||
|
<value>x86_64</value>
|
||||||
|
<value>xtensa</value>
|
||||||
|
<value>xtensaeb</value>
|
||||||
|
+ <value>loongarch64</value>
|
||||||
|
</choice>
|
||||||
|
</define>
|
||||||
|
|
||||||
|
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
|
||||||
|
+ * <http://www.gnu.org/licenses/>.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <config.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <sys/time.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <sys/resource.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#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
|
||||||
|
+ * <http://www.gnu.org/licenses/>.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#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
|
||||||
|
+ * <http://www.gnu.org/licenses/>.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef __VIR_CPU_LOONGARCH_DATA_H__
|
||||||
|
+# define __VIR_CPU_LOONGARCH_DATA_H__
|
||||||
|
+
|
||||||
|
+# include <stdint.h>
|
||||||
|
+
|
||||||
|
+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
|
||||||
|
|
||||||
263
Config-some-capabilities-for-loongarch-virt-machine.patch
Normal file
263
Config-some-capabilities-for-loongarch-virt-machine.patch
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
From 4b7f6284eaa3e3b15360e25848fc68b37ee6c768 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhaotianrui <zhaotianrui@loongson.cn>
|
||||||
|
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 <zhaotianrui@loongson.cn>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
||||||
65
Implement-the-method-of-getting-host-info-for-loonga.patch
Normal file
65
Implement-the-method-of-getting-host-info-for-loonga.patch
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
From 4123437e633f05af0ae8091d5db440597394ba36 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhaotianrui <zhaotianrui@loongson.cn>
|
||||||
|
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 <zhaotianrui@loongson.cn>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
||||||
43
bugfix-move-the-check-function-qemuDomainDiskBlockIo.patch
Normal file
43
bugfix-move-the-check-function-qemuDomainDiskBlockIo.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From 35de7404370eb24089b6160d109f6fe559a91864 Mon Sep 17 00:00:00 2001
|
||||||
|
From: mayunlong <mayunlong6@huawei.com>
|
||||||
|
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<mayunlong6@huawei.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
||||||
19
libvirt.spec
19
libvirt.spec
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
%define with_qemu_tcg %{with_qemu}
|
%define with_qemu_tcg %{with_qemu}
|
||||||
|
|
||||||
%define qemu_kvm_arches %{ix86} x86_64 aarch64
|
%define qemu_kvm_arches %{ix86} x86_64 aarch64 loongarch64
|
||||||
|
|
||||||
%ifarch %{qemu_kvm_arches}
|
%ifarch %{qemu_kvm_arches}
|
||||||
%define with_qemu_kvm %{with_qemu}
|
%define with_qemu_kvm %{with_qemu}
|
||||||
@ -44,7 +44,7 @@
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%define with_storage_zfs 0%{!?_without_storage_zfs:1}
|
%define with_storage_zfs 0%{!?_without_storage_zfs:1}
|
||||||
%ifarch aarch64 x86_64
|
%ifarch aarch64 x86_64 loongarch64
|
||||||
%define with_storage_zfs 0
|
%define with_storage_zfs 0
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
@ -101,7 +101,7 @@
|
|||||||
Summary: Library providing a simple virtualization API
|
Summary: Library providing a simple virtualization API
|
||||||
Name: libvirt
|
Name: libvirt
|
||||||
Version: 6.2.0
|
Version: 6.2.0
|
||||||
Release: 51
|
Release: 52
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
URL: https://libvirt.org/
|
URL: https://libvirt.org/
|
||||||
|
|
||||||
@ -468,6 +468,11 @@ Patch0355: virsh-Check-whether-enough-arguments-was-passed-to-i.patch
|
|||||||
Patch0356: virNetDevSaveNetConfig-Pass-mode-to-virFileWriteStr.patch
|
Patch0356: virNetDevSaveNetConfig-Pass-mode-to-virFileWriteStr.patch
|
||||||
Patch0357: live_migrate-virsh-migrate-command-supports-the-zstd.patch
|
Patch0357: live_migrate-virsh-migrate-command-supports-the-zstd.patch
|
||||||
Patch0358: glibcompat-Provide-implementation-for-G_GNUC_NO_INLI.patch
|
Patch0358: glibcompat-Provide-implementation-for-G_GNUC_NO_INLI.patch
|
||||||
|
Patch0359: bugfix-move-the-check-function-qemuDomainDiskBlockIo.patch
|
||||||
|
Patch0360: Add-loongarch-cpu-support.patch
|
||||||
|
Patch0361: Add-loongarch-cpu-model-and-vendor-info.patch
|
||||||
|
Patch0362: Config-some-capabilities-for-loongarch-virt-machine.patch
|
||||||
|
Patch0363: Implement-the-method-of-getting-host-info-for-loonga.patch
|
||||||
|
|
||||||
Requires: libvirt-daemon = %{version}-%{release}
|
Requires: libvirt-daemon = %{version}-%{release}
|
||||||
Requires: libvirt-daemon-config-network = %{version}-%{release}
|
Requires: libvirt-daemon-config-network = %{version}-%{release}
|
||||||
@ -1358,6 +1363,8 @@ LOADERS="$LOADERS:/usr/share/edk2/ovmf-ia32/OVMF_CODE.fd:/usr/share/edk2/ovmf-ia
|
|||||||
LOADERS="$LOADERS:/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw:/usr/share/edk2/aarch64/vars-template-pflash.raw"
|
LOADERS="$LOADERS:/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw:/usr/share/edk2/aarch64/vars-template-pflash.raw"
|
||||||
# Fedora edk2-arm
|
# Fedora edk2-arm
|
||||||
LOADERS="$LOADERS:/usr/share/edk2/arm/QEMU_EFI-pflash.raw:/usr/share/edk2/arm/vars-template-pflash.raw"
|
LOADERS="$LOADERS:/usr/share/edk2/arm/QEMU_EFI-pflash.raw:/usr/share/edk2/arm/vars-template-pflash.raw"
|
||||||
|
# LoongArch
|
||||||
|
LOADERS="$LOADERS:/usr/share/qemu-kvm/loongarch_bios.bin:/usr/share/qemu-kvm/loongarch_bios.bin"
|
||||||
%define arg_loader_nvram --with-loader-nvram="$LOADERS"
|
%define arg_loader_nvram --with-loader-nvram="$LOADERS"
|
||||||
|
|
||||||
# place macros above and build commands below this comment
|
# place macros above and build commands below this comment
|
||||||
@ -2080,7 +2087,7 @@ exit 0
|
|||||||
%{_bindir}/virt-pki-validate
|
%{_bindir}/virt-pki-validate
|
||||||
%{_bindir}/virt-host-validate
|
%{_bindir}/virt-host-validate
|
||||||
|
|
||||||
%ifnarch aarch64 x86_64
|
%ifnarch aarch64 x86_64 loongarch64
|
||||||
%{_datadir}/systemtap/tapset/libvirt_probes*.stp
|
%{_datadir}/systemtap/tapset/libvirt_probes*.stp
|
||||||
%{_datadir}/systemtap/tapset/libvirt_functions.stp
|
%{_datadir}/systemtap/tapset/libvirt_functions.stp
|
||||||
%if %{with_qemu}
|
%if %{with_qemu}
|
||||||
@ -2202,6 +2209,10 @@ exit 0
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Mar 28 2023 mayunlong <mayunlong6@huawei.com> - 6.2.0-52
|
||||||
|
- bugfix: move qemuDomainDiskBlockIoTunelsSupported to currect place
|
||||||
|
- libvirt: add loongarch support
|
||||||
|
|
||||||
* Tue Feb 14 2023 mayunlong <mayunlong6@huawei.com> - 6.2.0-51
|
* Tue Feb 14 2023 mayunlong <mayunlong6@huawei.com> - 6.2.0-51
|
||||||
- live_migrate: virsh migrate command supports the zstd compression algorithm
|
- live_migrate: virsh migrate command supports the zstd compression algorithm
|
||||||
- glibcompat: Provide implementation for G_GNUC_NO_INLINE
|
- glibcompat: Provide implementation for G_GNUC_NO_INLINE
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user