加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
libvirt-cpu-arm-implment-cpu-compare-function.patch 6.89 KB
一键复制 编辑 原始数据 按行查看 历史
From 1a70b1e3bdbd8d0dcf9281341bc23b4ff2ffaa3a Mon Sep 17 00:00:00 2001
From: Xu Yandong <xuyandong2@huawei.com>
Date: Mon, 20 Apr 2020 19:33:49 +0800
Subject: cpu/arm: implment cpu compare function
Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
---
src/cpu/cpu_arm.c | 196 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 193 insertions(+), 3 deletions(-)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index a7c9523..3ef54b9 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -21,6 +21,7 @@
#include <config.h>
+#include "virlog.h"
#include "viralloc.h"
#include "cpu.h"
#include "cpu_map.h"
@@ -30,6 +31,8 @@
#define VIR_FROM_THIS VIR_FROM_CPU
+VIR_LOG_INIT("cpu.cpu_arm");
+
static const char *sysinfoCpuinfo = "/proc/cpuinfo";
#define CPUINFO sysinfoCpuinfo
@@ -806,14 +809,201 @@ virCPUarmBaseline(virCPUDefPtr *cpus,
return g_steal_pointer(&cpu);
}
+static bool
+virCPUarmFeaturesIsSub(char *subFeatures,
+ char *fullFeatures)
+{
+ bool ret = false;
+ char **sub = NULL;
+ char **full = NULL;
+ size_t subCount = 0;
+ size_t fullCount = 0;
+ size_t i;
+
+ if (virStringIsEmpty(subFeatures))
+ return true;
+
+ if (virStringIsEmpty(fullFeatures))
+ return ret;
+
+ if (STREQ(subFeatures, fullFeatures))
+ return true;
+
+ if (!(sub = virStringSplitCount(subFeatures, " ", 0, &subCount)) ||
+ !(full = virStringSplitCount(fullFeatures, " ", 0, &fullCount)) ||
+ subCount > fullCount)
+ goto cleanup;
+
+ for (i = 0; i < subCount; i++) {
+ if (!virStringListHasString((const char**)full, sub[i]))
+ goto cleanup;
+ }
+
+ ret = true;
+
+ cleanup:
+ virStringListFree(sub);
+ virStringListFree(full);
+ return ret;
+}
+
+static virCPUDataPtr
+armMakeCPUData(virArch arch,
+ virCPUarmData *data)
+{
+ virCPUDataPtr cpuData;
+
+ if (!(cpuData = virCPUDataNew(arch)))
+ return NULL;
+
+ virCPUarmDataCopy(&cpuData->data.arm, data);
+
+ return cpuData;
+}
+
static virCPUCompareResult
-virCPUarmCompare(virCPUDefPtr host G_GNUC_UNUSED,
- virCPUDefPtr cpu G_GNUC_UNUSED,
- bool failMessages G_GNUC_UNUSED)
+armCompute(virCPUDefPtr host,
+ virCPUDefPtr cpu,
+ virCPUDataPtr *guestData,
+ char **message)
{
+ virCPUarmMapPtr map = NULL;
+ g_autoptr(virCPUarmModel) hostModel = NULL;
+ g_autoptr(virCPUarmModel) guestModel = NULL;
+ virArch arch;
+ size_t i;
+
+ if (cpu->arch != VIR_ARCH_NONE) {
+ bool found = false;
+
+ for (i = 0; i < G_N_ELEMENTS(archs); i++) {
+ if (archs[i] == cpu->arch) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ VIR_DEBUG("CPU arch %s does not match host arch",
+ virArchToString(cpu->arch));
+ if (message)
+ *message = g_strdup_printf(_("CPU arch %s does not match host arch"),
+ virArchToString(cpu->arch));
+
+ return VIR_CPU_COMPARE_INCOMPATIBLE;
+ }
+ arch = cpu->arch;
+ } else {
+ arch = host->arch;
+ }
+
+ if (cpu->vendor &&
+ (!host->vendor || STRNEQ(cpu->vendor, host->vendor))) {
+ VIR_DEBUG("host CPU vendor does not match required CPU vendor %s",
+ cpu->vendor);
+ if (message)
+ *message = g_strdup_printf(_("host CPU vendor does not match required "
+ "CPU vendor %s"),
+ cpu->vendor);
+
+ return VIR_CPU_COMPARE_INCOMPATIBLE;
+ }
+
+ if (!(map = virCPUarmGetMap()))
+ return VIR_CPU_COMPARE_ERROR;
+
+ /* Host CPU information */
+ if (!(hostModel = virCPUarmModelFromCPU(host, map)))
+ return VIR_CPU_COMPARE_ERROR;
+
+ if (cpu->type == VIR_CPU_TYPE_GUEST) {
+ /* Guest CPU information */
+ switch (cpu->mode) {
+ case VIR_CPU_MODE_HOST_MODEL:
+ case VIR_CPU_MODE_HOST_PASSTHROUGH:
+ /* host-model and host-passthrough:
+ * the guest CPU is the same as the host */
+ guestModel = virCPUarmModelCopy(hostModel);
+ break;
+
+ case VIR_CPU_MODE_CUSTOM:
+ /* custom:
+ * look up guest CPU information */
+ guestModel = virCPUarmModelFromCPU(cpu, map);
+ break;
+ }
+ } else {
+ /* Other host CPU information */
+ guestModel = virCPUarmModelFromCPU(cpu, map);
+ }
+
+ if (!guestModel)
+ return VIR_CPU_COMPARE_ERROR;
+
+ if (STRNEQ(guestModel->name, hostModel->name)) {
+ VIR_DEBUG("host CPU model %s does not match required CPU model %s",
+ hostModel->name, guestModel->name);
+ if (message)
+ *message = g_strdup_printf(_("host CPU model %s does not match required "
+ "CPU model %s"),
+ hostModel->name, guestModel->name);
+
+ return VIR_CPU_COMPARE_INCOMPATIBLE;
+ }
+
+ if (!virCPUarmFeaturesIsSub(guestModel->data.features, hostModel->data.features)) {
+ VIR_DEBUG("guest CPU features '%s' is not subset of "
+ "host CPU features '%s'",
+ guestModel->data.features, hostModel->data.features);
+ if (message)
+ *message = g_strdup_printf(_("guest CPU features '%s' is not subset of "
+ "host CPU features '%s'"),
+ guestModel->data.features,
+ hostModel->data.features);
+
+ return VIR_CPU_COMPARE_INCOMPATIBLE;
+ }
+
+ if (guestData &&
+ !(*guestData = armMakeCPUData(arch, &guestModel->data)))
+ return VIR_CPU_COMPARE_ERROR;
+
return VIR_CPU_COMPARE_IDENTICAL;
}
+static virCPUCompareResult
+virCPUarmCompare(virCPUDefPtr host,
+ virCPUDefPtr cpu,
+ bool failMessages)
+{
+ virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
+ g_autofree char *message = NULL;
+
+ if (!host || !host->model) {
+ if (failMessages) {
+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s",
+ _("unknown host CPU"));
+ } else {
+ VIR_WARN("unknown host CPU");
+ return VIR_CPU_COMPARE_INCOMPATIBLE;
+ }
+ return VIR_CPU_COMPARE_ERROR;
+ }
+
+ ret = armCompute(host, cpu, NULL, &message);
+
+ if (failMessages && ret == VIR_CPU_COMPARE_INCOMPATIBLE) {
+ if (message) {
+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s", message);
+ } else {
+ virReportError(VIR_ERR_CPU_INCOMPATIBLE, NULL);
+ }
+ return VIR_CPU_COMPARE_ERROR;
+ }
+
+ return ret;
+}
+
static int
virCPUarmValidateFeatures(virCPUDefPtr cpu)
{
--
2.23.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化