From 4c3a9684e7fccef83158a4a2f74680c6d8e166f7 Mon Sep 17 00:00:00 2001
From: Xu Yandong <xuyandong2@huawei.com>
Date: Fri, 6 Sep 2019 10:56:39 +0800
Subject: [PATCH] cpu: add getHostCPU for ARM CPUS

support vendor and model for virConnectGetCapabilities in ARM,
introduce getHost frame for arm

Signed-off-by: Xu Yandong <xuyandong2@huawei.com>
---
 src/cpu/cpu_arm.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
index b4c41c5..b3bc379 100644
--- a/src/cpu/cpu_arm.c
+++ b/src/cpu/cpu_arm.c
@@ -532,6 +532,74 @@ armMakeCPUData(virArch arch,
 }
 
 
+
+static int
+armCpuDataFromCpuInfo(virCPUarmData *data)
+{
+    int ret = -1;
+    char *eol = NULL;
+    char *str_vendor = NULL;
+    char *str_pvr = NULL;
+    char *outbuf = NULL;
+    const char *cur;
+
+    if (!data)
+        return ret;
+
+    if (virFileReadAll(CPUINFO, CPUINFO_FILE_LEN, &outbuf) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Failed to open %s"), CPUINFO);
+        goto cleanup;
+    }
+
+    if ((cur = strstr(outbuf, "CPU implementer")) == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("there is no \"CPU implementer\" info in %s"), CPUINFO);
+        goto cleanup;
+    }
+
+    /* Account for format 'CPU implementer : XXXX'*/
+    cur = strchr(cur, ':') + 1;
+    eol = strchr(cur, '\n');
+    virSkipSpaces(&cur);
+    if (!eol || VIR_STRNDUP(str_vendor, cur, eol - cur) < 0 ||
+        virStrToLong_ul(str_vendor, NULL, 16, &data->vendor_id) < 0)
+        goto cleanup;
+
+    if ((cur = strstr(outbuf, "CPU part")) == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("there is no \"CPU part\" info in %s"), CPUINFO);
+        goto cleanup;
+    }
+
+    cur = strchr(cur, ':') + 1;
+    eol = strchr(cur, '\n');
+    virSkipSpaces(&cur);
+    if (!eol || VIR_STRNDUP(str_pvr, cur, eol - cur) < 0 ||
+        virStrToLong_ul(str_pvr, NULL, 16, &data->pvr) < 0)
+        goto cleanup;
+
+    if ((cur = strstr(outbuf, "Features")) == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("there is no \"Features\" info in %s"), CPUINFO);
+        goto cleanup;
+    }
+    cur = strchr(cur, ':') + 1;
+    eol = strchr(cur, '\n');
+    virSkipSpaces(&cur);
+    if (eol && VIR_STRNDUP(data->features, cur, eol - cur) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(outbuf);
+    VIR_FREE(str_vendor);
+    VIR_FREE(str_pvr);
+    return ret;
+}
+
+
 static int
 armCpuDataParseFeatures(virCPUDefPtr cpu,
                         const virCPUarmData *cpuData)
@@ -628,6 +696,29 @@ armDecodeCPUData(virCPUDefPtr cpu,
     return armDecode(cpu, &data->data.arm, models);
 }
 
+static int
+virCPUarmGetHost(virCPUDefPtr cpu,
+                 virDomainCapsCPUModelsPtr models)
+{
+    virCPUDataPtr cpuData = NULL;
+    int ret = -1;
+
+    if (virCPUarmDriverInitialize() < 0)
+        goto cleanup;
+
+    if (!(cpuData = virCPUDataNew(archs[0])))
+        goto cleanup;
+
+    if (armCpuDataFromCpuInfo(&cpuData->data.arm) < 0)
+        goto cleanup;
+
+    ret = armDecodeCPUData(cpu, cpuData, models);
+
+ cleanup:
+    virCPUarmDataFree(cpuData);
+    return ret;
+}
+
 
 static int
 virCPUarmUpdate(virCPUDefPtr guest,
@@ -926,6 +1017,7 @@ struct cpuArchDriver cpuDriverArm = {
     .decode = armDecodeCPUData,
     .encode = NULL,
     .dataFree = virCPUarmDataFree,
+    .getHost = virCPUarmGetHost,
     .baseline = virCPUarmBaseline,
     .update = virCPUarmUpdate,
 };
-- 
2.19.1

