[PATCH V3 0/5] Introduce getHost support for ARM CPU driver

Introduce getHost support for ARM CPU driver. First add some data about commonly used ARM CPU models, and their vendors into cpu_map, then added some helper methods as callbacks to load them. Read and parse vendor_id, part_id and CPU flags of local CPU from corresponding registers. Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> ZhengZhenyu (5): cpu_map: Introduce ARM cpu models cpu: Introduce virCPUarmData to virCPUData cpu: Introduce ARM related structs cpu: Add helper funtions to parse vendor and model cpu: Introduce getHost support for ARM CPU driver src/cpu/Makefile.inc.am | 1 + src/cpu/cpu.h | 2 + src/cpu/cpu_arm.c | 450 +++++++++++++++++++++++++++++- src/cpu/cpu_arm_data.h | 31 ++ src/cpu_map/Makefile.inc.am | 7 + src/cpu_map/arm_Falkor.xml | 16 ++ src/cpu_map/arm_Kunpeng-920.xml | 24 ++ src/cpu_map/arm_ThunderX299xx.xml | 16 ++ src/cpu_map/arm_cortex-a53.xml | 16 ++ src/cpu_map/arm_cortex-a57.xml | 15 + src/cpu_map/arm_cortex-a72.xml | 15 + src/cpu_map/arm_vendors.xml | 14 + src/cpu_map/index.xml | 15 + 13 files changed, 619 insertions(+), 3 deletions(-) create mode 100644 src/cpu/cpu_arm_data.h create mode 100644 src/cpu_map/arm_Falkor.xml create mode 100644 src/cpu_map/arm_Kunpeng-920.xml create mode 100644 src/cpu_map/arm_ThunderX299xx.xml create mode 100644 src/cpu_map/arm_cortex-a53.xml create mode 100644 src/cpu_map/arm_cortex-a57.xml create mode 100644 src/cpu_map/arm_cortex-a72.xml create mode 100644 src/cpu_map/arm_vendors.xml -- 2.26.0.windows.1

Introduce vendors and some commonly used models for ARM arch, these will be used for virConnectionGetCapabilities for ARM CPUs. Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu_map/Makefile.inc.am | 7 +++++++ src/cpu_map/arm_Falkor.xml | 16 ++++++++++++++++ src/cpu_map/arm_Kunpeng-920.xml | 24 ++++++++++++++++++++++++ src/cpu_map/arm_ThunderX299xx.xml | 16 ++++++++++++++++ src/cpu_map/arm_cortex-a53.xml | 16 ++++++++++++++++ src/cpu_map/arm_cortex-a57.xml | 15 +++++++++++++++ src/cpu_map/arm_cortex-a72.xml | 15 +++++++++++++++ src/cpu_map/arm_vendors.xml | 14 ++++++++++++++ src/cpu_map/index.xml | 15 +++++++++++++++ 9 files changed, 138 insertions(+) create mode 100644 src/cpu_map/arm_Falkor.xml create mode 100644 src/cpu_map/arm_Kunpeng-920.xml create mode 100644 src/cpu_map/arm_ThunderX299xx.xml create mode 100644 src/cpu_map/arm_cortex-a53.xml create mode 100644 src/cpu_map/arm_cortex-a57.xml create mode 100644 src/cpu_map/arm_cortex-a72.xml create mode 100644 src/cpu_map/arm_vendors.xml diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am index be64c9a0d4..93c2b19ddf 100644 --- a/src/cpu_map/Makefile.inc.am +++ b/src/cpu_map/Makefile.inc.am @@ -2,7 +2,14 @@ cpumapdir = $(pkgdatadir)/cpu_map cpumap_DATA = \ + cpu_map/arm_cortex-a53.xml \ + cpu_map/arm_cortex-a57.xml \ + cpu_map/arm_cortex-a72.xml \ cpu_map/arm_features.xml \ + cpu_map/arm_Kunpeng-920.xml \ + cpu_map/arm_ThunderX299xx.xml \ + cpu_map/arm_Falkor.xml \ + cpu_map/arm_vendors.xml \ cpu_map/index.xml \ cpu_map/ppc64_vendors.xml \ cpu_map/ppc64_POWER7.xml \ diff --git a/src/cpu_map/arm_Falkor.xml b/src/cpu_map/arm_Falkor.xml new file mode 100644 index 0000000000..902ed2b6ba --- /dev/null +++ b/src/cpu_map/arm_Falkor.xml @@ -0,0 +1,16 @@ +<cpus> + <model name='Falkor'> + <vendor name='Qualcomm'/> + <pvr value='0xc00'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + <feature name="asimdrdm"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_Kunpeng-920.xml b/src/cpu_map/arm_Kunpeng-920.xml new file mode 100644 index 0000000000..668b8b50dc --- /dev/null +++ b/src/cpu_map/arm_Kunpeng-920.xml @@ -0,0 +1,24 @@ +<cpus> + <model name='Kunpeng-920'> + <vendor name='HiSilicon'/> + <pvr value='0xd01'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="atomics"/> + <feature name="fphp"/> + <feature name="asimdhp"/> + <feature name="cpuid"/> + <feature name="asimdrdm"/> + <feature name="jscvt"/> + <feature name="fcma"/> + <feature name="dcpop"/> + <feature name="asimddp"/> + <feature name="asimdfhm"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_ThunderX299xx.xml b/src/cpu_map/arm_ThunderX299xx.xml new file mode 100644 index 0000000000..9ab3d939e9 --- /dev/null +++ b/src/cpu_map/arm_ThunderX299xx.xml @@ -0,0 +1,16 @@ +<cpus> + <model name='ThunderX2 99xx'> + <vendor name='Cavium'/> + <pvr value='0x0af'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + <feature name="asimdrdm"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_cortex-a53.xml b/src/cpu_map/arm_cortex-a53.xml new file mode 100644 index 0000000000..963d6d36e3 --- /dev/null +++ b/src/cpu_map/arm_cortex-a53.xml @@ -0,0 +1,16 @@ +<cpus> + <model name='cortex-a53'> + <vendor name='ARM'/> + <pvr value='0xd03'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + <feature name="asimdrdm"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_cortex-a57.xml b/src/cpu_map/arm_cortex-a57.xml new file mode 100644 index 0000000000..92a044ea92 --- /dev/null +++ b/src/cpu_map/arm_cortex-a57.xml @@ -0,0 +1,15 @@ +<cpus> + <model name='cortex-a57'> + <vendor name='ARM'/> + <pvr value='0xd07'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_cortex-a72.xml b/src/cpu_map/arm_cortex-a72.xml new file mode 100644 index 0000000000..9664eacd7b --- /dev/null +++ b/src/cpu_map/arm_cortex-a72.xml @@ -0,0 +1,15 @@ +<cpus> + <model name='cortex-a72'> + <vendor name='ARM'/> + <pvr value='0xd08'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_vendors.xml b/src/cpu_map/arm_vendors.xml new file mode 100644 index 0000000000..703c2112b1 --- /dev/null +++ b/src/cpu_map/arm_vendors.xml @@ -0,0 +1,14 @@ +<cpus> + <vendor name="ARM" value="0x41"/> + <vendor name="Broadcom" value="0x42"/> + <vendor name="Cavium" value="0x43"/> + <vendor name="DigitalEquipment" value="0x44"/> + <vendor name="HiSilicon" value="0x48"/> + <vendor name="Infineon" value="0x49"/> + <vendor name="Freescale" value="0x4D"/> + <vendor name="NVIDIA" value="0x4E"/> + <vendor name="APM" value="0x50"/> + <vendor name="Qualcomm" value="0x51"/> + <vendor name="Marvell" value="0x56"/> + <vendor name="Intel" value="0x69"/> +</cpus> diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml index 50b030de29..20646a031c 100644 --- a/src/cpu_map/index.xml +++ b/src/cpu_map/index.xml @@ -85,6 +85,21 @@ </arch> <arch name='arm'> + <include filename="arm_vendors.xml"/> <include filename='arm_features.xml'/> + + <!-- ARM-based CPU models --> + <include filename="arm_cortex-a53.xml"/> + <include filename="arm_cortex-a57.xml"/> + <include filename="arm_cortex-a72.xml"/> + + <!-- Qualcomm-based CPU models --> + <include filename='arm_Falkor.xml'/> + + <!-- Cavium-based CPU models --> + <include filename='arm_ThunderX299xx.xml'/> + + <!-- Hisilicon-based CPU models --> + <include filename="arm_Kunpeng-920.xml"/> </arch> </cpus> -- 2.26.0.windows.1

ping for reviews On Wed, Apr 22, 2020 at 3:12 PM ZhengZhenyu <zheng.zhenyu@foxmail.com> wrote:
Introduce vendors and some commonly used models for ARM arch, these will be used for virConnectionGetCapabilities for ARM CPUs.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu_map/Makefile.inc.am | 7 +++++++ src/cpu_map/arm_Falkor.xml | 16 ++++++++++++++++ src/cpu_map/arm_Kunpeng-920.xml | 24 ++++++++++++++++++++++++ src/cpu_map/arm_ThunderX299xx.xml | 16 ++++++++++++++++ src/cpu_map/arm_cortex-a53.xml | 16 ++++++++++++++++ src/cpu_map/arm_cortex-a57.xml | 15 +++++++++++++++ src/cpu_map/arm_cortex-a72.xml | 15 +++++++++++++++ src/cpu_map/arm_vendors.xml | 14 ++++++++++++++ src/cpu_map/index.xml | 15 +++++++++++++++ 9 files changed, 138 insertions(+) create mode 100644 src/cpu_map/arm_Falkor.xml create mode 100644 src/cpu_map/arm_Kunpeng-920.xml create mode 100644 src/cpu_map/arm_ThunderX299xx.xml create mode 100644 src/cpu_map/arm_cortex-a53.xml create mode 100644 src/cpu_map/arm_cortex-a57.xml create mode 100644 src/cpu_map/arm_cortex-a72.xml create mode 100644 src/cpu_map/arm_vendors.xml
diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am index be64c9a0d4..93c2b19ddf 100644 --- a/src/cpu_map/Makefile.inc.am +++ b/src/cpu_map/Makefile.inc.am @@ -2,7 +2,14 @@
cpumapdir = $(pkgdatadir)/cpu_map cpumap_DATA = \ + cpu_map/arm_cortex-a53.xml \ + cpu_map/arm_cortex-a57.xml \ + cpu_map/arm_cortex-a72.xml \ cpu_map/arm_features.xml \ + cpu_map/arm_Kunpeng-920.xml \ + cpu_map/arm_ThunderX299xx.xml \ + cpu_map/arm_Falkor.xml \ + cpu_map/arm_vendors.xml \ cpu_map/index.xml \ cpu_map/ppc64_vendors.xml \ cpu_map/ppc64_POWER7.xml \ diff --git a/src/cpu_map/arm_Falkor.xml b/src/cpu_map/arm_Falkor.xml new file mode 100644 index 0000000000..902ed2b6ba --- /dev/null +++ b/src/cpu_map/arm_Falkor.xml @@ -0,0 +1,16 @@ +<cpus> + <model name='Falkor'> + <vendor name='Qualcomm'/> + <pvr value='0xc00'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + <feature name="asimdrdm"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_Kunpeng-920.xml b/src/cpu_map/arm_Kunpeng-920.xml new file mode 100644 index 0000000000..668b8b50dc --- /dev/null +++ b/src/cpu_map/arm_Kunpeng-920.xml @@ -0,0 +1,24 @@ +<cpus> + <model name='Kunpeng-920'> + <vendor name='HiSilicon'/> + <pvr value='0xd01'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="atomics"/> + <feature name="fphp"/> + <feature name="asimdhp"/> + <feature name="cpuid"/> + <feature name="asimdrdm"/> + <feature name="jscvt"/> + <feature name="fcma"/> + <feature name="dcpop"/> + <feature name="asimddp"/> + <feature name="asimdfhm"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_ThunderX299xx.xml b/src/cpu_map/arm_ThunderX299xx.xml new file mode 100644 index 0000000000..9ab3d939e9 --- /dev/null +++ b/src/cpu_map/arm_ThunderX299xx.xml @@ -0,0 +1,16 @@ +<cpus> + <model name='ThunderX2 99xx'> + <vendor name='Cavium'/> + <pvr value='0x0af'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + <feature name="asimdrdm"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_cortex-a53.xml b/src/cpu_map/arm_cortex-a53.xml new file mode 100644 index 0000000000..963d6d36e3 --- /dev/null +++ b/src/cpu_map/arm_cortex-a53.xml @@ -0,0 +1,16 @@ +<cpus> + <model name='cortex-a53'> + <vendor name='ARM'/> + <pvr value='0xd03'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + <feature name="asimdrdm"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_cortex-a57.xml b/src/cpu_map/arm_cortex-a57.xml new file mode 100644 index 0000000000..92a044ea92 --- /dev/null +++ b/src/cpu_map/arm_cortex-a57.xml @@ -0,0 +1,15 @@ +<cpus> + <model name='cortex-a57'> + <vendor name='ARM'/> + <pvr value='0xd07'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_cortex-a72.xml b/src/cpu_map/arm_cortex-a72.xml new file mode 100644 index 0000000000..9664eacd7b --- /dev/null +++ b/src/cpu_map/arm_cortex-a72.xml @@ -0,0 +1,15 @@ +<cpus> + <model name='cortex-a72'> + <vendor name='ARM'/> + <pvr value='0xd08'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + </model> +</cpus> diff --git a/src/cpu_map/arm_vendors.xml b/src/cpu_map/arm_vendors.xml new file mode 100644 index 0000000000..703c2112b1 --- /dev/null +++ b/src/cpu_map/arm_vendors.xml @@ -0,0 +1,14 @@ +<cpus> + <vendor name="ARM" value="0x41"/> + <vendor name="Broadcom" value="0x42"/> + <vendor name="Cavium" value="0x43"/> + <vendor name="DigitalEquipment" value="0x44"/> + <vendor name="HiSilicon" value="0x48"/> + <vendor name="Infineon" value="0x49"/> + <vendor name="Freescale" value="0x4D"/> + <vendor name="NVIDIA" value="0x4E"/> + <vendor name="APM" value="0x50"/> + <vendor name="Qualcomm" value="0x51"/> + <vendor name="Marvell" value="0x56"/> + <vendor name="Intel" value="0x69"/> +</cpus> diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml index 50b030de29..20646a031c 100644 --- a/src/cpu_map/index.xml +++ b/src/cpu_map/index.xml @@ -85,6 +85,21 @@ </arch>
<arch name='arm'> + <include filename="arm_vendors.xml"/> <include filename='arm_features.xml'/> + + <!-- ARM-based CPU models --> + <include filename="arm_cortex-a53.xml"/> + <include filename="arm_cortex-a57.xml"/> + <include filename="arm_cortex-a72.xml"/> + + <!-- Qualcomm-based CPU models --> + <include filename='arm_Falkor.xml'/> + + <!-- Cavium-based CPU models --> + <include filename='arm_ThunderX299xx.xml'/> + + <!-- Hisilicon-based CPU models --> + <include filename="arm_Kunpeng-920.xml"/> </arch> </cpus> -- 2.26.0.windows.1

On Wed, Apr 22, 2020 at 15:11:16 +0800, ZhengZhenyu wrote:
Introduce vendors and some commonly used models for ARM arch, these will be used for virConnectionGetCapabilities for ARM CPUs.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu_map/Makefile.inc.am | 7 +++++++ src/cpu_map/arm_Falkor.xml | 16 ++++++++++++++++ src/cpu_map/arm_Kunpeng-920.xml | 24 ++++++++++++++++++++++++ src/cpu_map/arm_ThunderX299xx.xml | 16 ++++++++++++++++ src/cpu_map/arm_cortex-a53.xml | 16 ++++++++++++++++ src/cpu_map/arm_cortex-a57.xml | 15 +++++++++++++++ src/cpu_map/arm_cortex-a72.xml | 15 +++++++++++++++ src/cpu_map/arm_vendors.xml | 14 ++++++++++++++ src/cpu_map/index.xml | 15 +++++++++++++++ 9 files changed, 138 insertions(+) create mode 100644 src/cpu_map/arm_Falkor.xml create mode 100644 src/cpu_map/arm_Kunpeng-920.xml create mode 100644 src/cpu_map/arm_ThunderX299xx.xml create mode 100644 src/cpu_map/arm_cortex-a53.xml create mode 100644 src/cpu_map/arm_cortex-a57.xml create mode 100644 src/cpu_map/arm_cortex-a72.xml create mode 100644 src/cpu_map/arm_vendors.xml
This patch should be moved just before the last one to make sure libvirt can be built after each patch.
diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am index be64c9a0d4..93c2b19ddf 100644 --- a/src/cpu_map/Makefile.inc.am +++ b/src/cpu_map/Makefile.inc.am @@ -2,7 +2,14 @@
cpumapdir = $(pkgdatadir)/cpu_map cpumap_DATA = \ + cpu_map/arm_cortex-a53.xml \
This line is indented with 4 spaces while it should start with a tab instead.
+ cpu_map/arm_cortex-a57.xml \ + cpu_map/arm_cortex-a72.xml \ cpu_map/arm_features.xml \ + cpu_map/arm_Kunpeng-920.xml \ + cpu_map/arm_ThunderX299xx.xml \ + cpu_map/arm_Falkor.xml \ + cpu_map/arm_vendors.xml \ cpu_map/index.xml \ cpu_map/ppc64_vendors.xml \ cpu_map/ppc64_POWER7.xml \ diff --git a/src/cpu_map/arm_Falkor.xml b/src/cpu_map/arm_Falkor.xml new file mode 100644 index 0000000000..902ed2b6ba --- /dev/null +++ b/src/cpu_map/arm_Falkor.xml @@ -0,0 +1,16 @@ +<cpus> + <model name='Falkor'> + <vendor name='Qualcomm'/> + <pvr value='0xc00'/> + <feature name="fp"/> + <feature name="asimd"/> + <feature name="evtstrm"/> + <feature name="aes"/> + <feature name="pmull"/> + <feature name="sha1"/> + <feature name="sha2"/> + <feature name="crc32"/> + <feature name="cpuid"/> + <feature name="asimdrdm"/>
What is the purpose of the feature list here when you don't parse them anywhere?
+ </model> +</cpus>
Jirka

Introduce virCPUarmData to virCPUData Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/Makefile.inc.am | 1 + src/cpu/cpu.h | 2 ++ src/cpu/cpu_arm_data.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/cpu/cpu_arm_data.h diff --git a/src/cpu/Makefile.inc.am b/src/cpu/Makefile.inc.am index 0abeee87b6..bea203fb5c 100644 --- a/src/cpu/Makefile.inc.am +++ b/src/cpu/Makefile.inc.am @@ -10,6 +10,7 @@ CPU_SOURCES = \ cpu/cpu_s390.c \ cpu/cpu_arm.h \ cpu/cpu_arm.c \ + cpu/cpu_arm_data.h \ cpu/cpu_ppc64.h \ cpu/cpu_ppc64.c \ cpu/cpu_ppc64_data.h \ diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index f779d2be17..ec22a183a1 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -27,6 +27,7 @@ #include "cpu_conf.h" #include "cpu_x86_data.h" #include "cpu_ppc64_data.h" +#include "cpu_arm_data.h" typedef struct _virCPUData virCPUData; @@ -36,6 +37,7 @@ struct _virCPUData { union { virCPUx86Data x86; virCPUppc64Data ppc64; + virCPUarmData arm; /* generic driver needs no data */ } data; }; diff --git a/src/cpu/cpu_arm_data.h b/src/cpu/cpu_arm_data.h new file mode 100644 index 0000000000..cf12ca8c2e --- /dev/null +++ b/src/cpu/cpu_arm_data.h @@ -0,0 +1,31 @@ +/* + * cpu_arm_data.h: 64-bit arm CPU specific data + * + * Copyright (C) 2020 Huawei Technologies Co., Ltd. + * + * 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/>. + * + */ + +#pragma once + +#define VIR_CPU_ARM_DATA_INIT { 0 } + +typedef struct _virCPUarmData virCPUarmData; +struct _virCPUarmData { + unsigned long vendor_id; + unsigned long pvr; + char *features; +}; -- 2.26.0.windows.1

ping for reviews On Wed, Apr 22, 2020 at 3:12 PM ZhengZhenyu <zheng.zhenyu@foxmail.com> wrote:
Introduce virCPUarmData to virCPUData
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/Makefile.inc.am | 1 + src/cpu/cpu.h | 2 ++ src/cpu/cpu_arm_data.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/cpu/cpu_arm_data.h
diff --git a/src/cpu/Makefile.inc.am b/src/cpu/Makefile.inc.am index 0abeee87b6..bea203fb5c 100644 --- a/src/cpu/Makefile.inc.am +++ b/src/cpu/Makefile.inc.am @@ -10,6 +10,7 @@ CPU_SOURCES = \ cpu/cpu_s390.c \ cpu/cpu_arm.h \ cpu/cpu_arm.c \ + cpu/cpu_arm_data.h \ cpu/cpu_ppc64.h \ cpu/cpu_ppc64.c \ cpu/cpu_ppc64_data.h \ diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index f779d2be17..ec22a183a1 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -27,6 +27,7 @@ #include "cpu_conf.h" #include "cpu_x86_data.h" #include "cpu_ppc64_data.h" +#include "cpu_arm_data.h"
typedef struct _virCPUData virCPUData; @@ -36,6 +37,7 @@ struct _virCPUData { union { virCPUx86Data x86; virCPUppc64Data ppc64; + virCPUarmData arm; /* generic driver needs no data */ } data; }; diff --git a/src/cpu/cpu_arm_data.h b/src/cpu/cpu_arm_data.h new file mode 100644 index 0000000000..cf12ca8c2e --- /dev/null +++ b/src/cpu/cpu_arm_data.h @@ -0,0 +1,31 @@ +/* + * cpu_arm_data.h: 64-bit arm CPU specific data + * + * Copyright (C) 2020 Huawei Technologies Co., Ltd. + * + * 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/>. + * + */ + +#pragma once + +#define VIR_CPU_ARM_DATA_INIT { 0 } + +typedef struct _virCPUarmData virCPUarmData; +struct _virCPUarmData { + unsigned long vendor_id; + unsigned long pvr; + char *features; +}; -- 2.26.0.windows.1

On Wed, Apr 22, 2020 at 15:11:18 +0800, ZhengZhenyu wrote:
Introduce virCPUarmData to virCPUData
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/Makefile.inc.am | 1 + src/cpu/cpu.h | 2 ++ src/cpu/cpu_arm_data.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/cpu/cpu_arm_data.h
This patch needs to be the first one in the series and either the corresponding hunks from the following patch should be squashed here or the this and the following patch could be squashed into a single one. ...
diff --git a/src/cpu/cpu_arm_data.h b/src/cpu/cpu_arm_data.h new file mode 100644 index 0000000000..cf12ca8c2e --- /dev/null +++ b/src/cpu/cpu_arm_data.h @@ -0,0 +1,31 @@ +/* + * cpu_arm_data.h: 64-bit arm CPU specific data + * + * Copyright (C) 2020 Huawei Technologies Co., Ltd. + * + * 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/>. + * + */ + +#pragma once + +#define VIR_CPU_ARM_DATA_INIT { 0 } + +typedef struct _virCPUarmData virCPUarmData; +struct _virCPUarmData { + unsigned long vendor_id; + unsigned long pvr; + char *features;
Make this a list of strings: char **features;
+};
Jirka

Introduce vendor and model struct and related cleanup functions for ARM cpu. Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index ee5802198f..2009904cc9 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -1,6 +1,7 @@ /* * cpu_arm.c: CPU driver for arm CPUs * + * Copyright (C) 2020 Huawei Technologies Co., Ltd. * Copyright (C) 2013 Red Hat, Inc. * Copyright (C) Canonical Ltd. 2012 * @@ -23,7 +24,9 @@ #include "viralloc.h" #include "cpu.h" +#include "cpu_arm.h" #include "cpu_map.h" +#include "virlog.h" #include "virstring.h" #include "virxml.h" @@ -36,6 +39,21 @@ static const virArch archs[] = { VIR_ARCH_AARCH64, }; +typedef struct _virCPUarmVendor virCPUarmVendor; +typedef virCPUarmVendor *virCPUarmVendorPtr; +struct _virCPUarmVendor { + char *name; + unsigned long value; +}; + +typedef struct _virCPUarmModel virCPUarmModel; +typedef virCPUarmModel *virCPUarmModelPtr; +struct _virCPUarmModel { + char *name; + virCPUarmVendorPtr vendor; + virCPUarmData data; +}; + typedef struct _virCPUarmFeature virCPUarmFeature; typedef virCPUarmFeature *virCPUarmFeaturePtr; struct _virCPUarmFeature { @@ -64,6 +82,10 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmFeature, virCPUarmFeatureFree); typedef struct _virCPUarmMap virCPUarmMap; typedef virCPUarmMap *virCPUarmMapPtr; struct _virCPUarmMap { + size_t nvendors; + virCPUarmVendorPtr *vendors; + size_t nmodels; + virCPUarmModelPtr *models; GPtrArray *features; }; @@ -81,12 +103,62 @@ virCPUarmMapNew(void) return map; } +static void +virCPUarmDataClear(virCPUarmData *data) +{ + if (!data) + return; + + VIR_FREE(data->features); +} + +static void +virCPUarmDataFree(virCPUDataPtr cpuData) +{ + if (!cpuData) + return; + + virCPUarmDataClear(&cpuData->data.arm); + VIR_FREE(cpuData); +} + +static void +virCPUarmModelFree(virCPUarmModelPtr model) +{ + if (!model) + return; + + virCPUarmDataClear(&model->data); + g_free(model->name); + g_free(model); +} + +static void +virCPUarmVendorFree(virCPUarmVendorPtr vendor) +{ + if (!vendor) + return; + + g_free(vendor->name); + g_free(vendor); +} + static void virCPUarmMapFree(virCPUarmMapPtr map) { if (!map) return; + size_t i; + + for (i = 0; i < map->nmodels; i++) + virCPUarmModelFree(map->models[i]); + g_free(map->models); + + for (i = 0; i < map->nvendors; i++) + virCPUarmVendorFree(map->vendors[i]); + g_free(map->vendors); + g_ptr_array_free(map->features, TRUE); g_free(map); @@ -259,6 +331,7 @@ struct cpuArchDriver cpuDriverArm = { .compare = virCPUarmCompare, .decode = NULL, .encode = NULL, + .dataFree = virCPUarmDataFree, .baseline = virCPUarmBaseline, .update = virCPUarmUpdate, .validateFeatures = virCPUarmValidateFeatures, -- 2.26.0.windows.1

ping for reviews On Wed, Apr 22, 2020 at 3:12 PM ZhengZhenyu <zheng.zhenyu@foxmail.com> wrote:
Introduce vendor and model struct and related cleanup functions for ARM cpu.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index ee5802198f..2009904cc9 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -1,6 +1,7 @@ /* * cpu_arm.c: CPU driver for arm CPUs * + * Copyright (C) 2020 Huawei Technologies Co., Ltd. * Copyright (C) 2013 Red Hat, Inc. * Copyright (C) Canonical Ltd. 2012 * @@ -23,7 +24,9 @@
#include "viralloc.h" #include "cpu.h" +#include "cpu_arm.h" #include "cpu_map.h" +#include "virlog.h" #include "virstring.h" #include "virxml.h"
@@ -36,6 +39,21 @@ static const virArch archs[] = { VIR_ARCH_AARCH64, };
+typedef struct _virCPUarmVendor virCPUarmVendor; +typedef virCPUarmVendor *virCPUarmVendorPtr; +struct _virCPUarmVendor { + char *name; + unsigned long value; +}; + +typedef struct _virCPUarmModel virCPUarmModel; +typedef virCPUarmModel *virCPUarmModelPtr; +struct _virCPUarmModel { + char *name; + virCPUarmVendorPtr vendor; + virCPUarmData data; +}; + typedef struct _virCPUarmFeature virCPUarmFeature; typedef virCPUarmFeature *virCPUarmFeaturePtr; struct _virCPUarmFeature { @@ -64,6 +82,10 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmFeature, virCPUarmFeatureFree); typedef struct _virCPUarmMap virCPUarmMap; typedef virCPUarmMap *virCPUarmMapPtr; struct _virCPUarmMap { + size_t nvendors; + virCPUarmVendorPtr *vendors; + size_t nmodels; + virCPUarmModelPtr *models; GPtrArray *features; };
@@ -81,12 +103,62 @@ virCPUarmMapNew(void) return map; }
+static void +virCPUarmDataClear(virCPUarmData *data) +{ + if (!data) + return; + + VIR_FREE(data->features); +} + +static void +virCPUarmDataFree(virCPUDataPtr cpuData) +{ + if (!cpuData) + return; + + virCPUarmDataClear(&cpuData->data.arm); + VIR_FREE(cpuData); +} + +static void +virCPUarmModelFree(virCPUarmModelPtr model) +{ + if (!model) + return; + + virCPUarmDataClear(&model->data); + g_free(model->name); + g_free(model); +} + +static void +virCPUarmVendorFree(virCPUarmVendorPtr vendor) +{ + if (!vendor) + return; + + g_free(vendor->name); + g_free(vendor); +} + static void virCPUarmMapFree(virCPUarmMapPtr map) { if (!map) return;
+ size_t i; + + for (i = 0; i < map->nmodels; i++) + virCPUarmModelFree(map->models[i]); + g_free(map->models); + + for (i = 0; i < map->nvendors; i++) + virCPUarmVendorFree(map->vendors[i]); + g_free(map->vendors); + g_ptr_array_free(map->features, TRUE);
g_free(map); @@ -259,6 +331,7 @@ struct cpuArchDriver cpuDriverArm = { .compare = virCPUarmCompare, .decode = NULL, .encode = NULL, + .dataFree = virCPUarmDataFree, .baseline = virCPUarmBaseline, .update = virCPUarmUpdate, .validateFeatures = virCPUarmValidateFeatures, -- 2.26.0.windows.1

On Wed, Apr 22, 2020 at 15:11:20 +0800, ZhengZhenyu wrote:
Introduce vendor and model struct and related cleanup functions for ARM cpu.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index ee5802198f..2009904cc9 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c ... @@ -81,12 +103,62 @@ virCPUarmMapNew(void) return map; }
+static void +virCPUarmDataClear(virCPUarmData *data) +{ + if (!data) + return; + + VIR_FREE(data->features);
virStringListFree(data->features)
+} + +static void +virCPUarmDataFree(virCPUDataPtr cpuData) +{ + if (!cpuData) + return; + + virCPUarmDataClear(&cpuData->data.arm); + VIR_FREE(cpuData);
g_free()
+}
The two functions above should go in one patch with the structure definition. Either you can move them to the previous patch or you can squash the two patches into a single one.
+ +static void +virCPUarmModelFree(virCPUarmModelPtr model) +{ + if (!model) + return; + + virCPUarmDataClear(&model->data); + g_free(model->name); + g_free(model); +}
Please, define the autoptr clean function for both model and vendor structures so that you can later use g_autoptr(virCPUarm...) ... = NULL; declarations: G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmModel, virCPUarmModelFree);
+ +static void +virCPUarmVendorFree(virCPUarmVendorPtr vendor) +{ + if (!vendor) + return; + + g_free(vendor->name); + g_free(vendor); +}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPUarmVendor, virCPUarmVendorFree);
+ static void virCPUarmMapFree(virCPUarmMapPtr map) { if (!map) return;
+ size_t i;
We declare all variables in the beginning of each block, i.e., this should go above the if (!map) check.
+ + for (i = 0; i < map->nmodels; i++) + virCPUarmModelFree(map->models[i]); + g_free(map->models); + + for (i = 0; i < map->nvendors; i++) + virCPUarmVendorFree(map->vendors[i]); + g_free(map->vendors); + g_ptr_array_free(map->features, TRUE);
g_free(map); @@ -259,6 +331,7 @@ struct cpuArchDriver cpuDriverArm = { .compare = virCPUarmCompare, .decode = NULL, .encode = NULL, + .dataFree = virCPUarmDataFree, .baseline = virCPUarmBaseline, .update = virCPUarmUpdate, .validateFeatures = virCPUarmValidateFeatures,
And the same applies for this hunk: it should go into the patch which introduced virCPUarmData. Jirka

Add helper functions to parse vendor and model from xml for ARM arch, and use them as callbacks when load cpu maps. Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 173 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 3 deletions(-) diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 2009904cc9..6e9ff9bf11 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -204,6 +204,174 @@ virCPUarmMapFeatureParse(xmlXPathContextPtr ctxt G_GNUC_UNUSED, return 0; } +static virCPUarmVendorPtr +virCPUarmVendorFindByID(virCPUarmMapPtr map, + unsigned long vendor_id) +{ + size_t i; + + for (i = 0; i < map->nvendors; i++) { + if (map->vendors[i]->value == vendor_id) + return map->vendors[i]; + } + + return NULL; +} + + +static virCPUarmVendorPtr +virCPUarmVendorFindByName(virCPUarmMapPtr 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 int +virCPUarmVendorParse(xmlXPathContextPtr ctxt, + const char *name, + void *data) +{ + virCPUarmMapPtr map = data; + virCPUarmVendorPtr vendor = NULL; + int ret = -1; + + if (VIR_ALLOC(vendor) < 0) + return ret; + + vendor->name = g_strdup(name); + + if (virCPUarmVendorFindByName(map, vendor->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor %s already defined"), + vendor->name); + goto cleanup; + } + + if (virXPathULongHex("string(@value)", ctxt, &vendor->value) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing CPU vendor value")); + goto cleanup; + } + + if (virCPUarmVendorFindByID(map, vendor->value)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor value 0x%2lx already defined"), + vendor->value); + goto cleanup; + } + + if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virCPUarmVendorFree(vendor); + return ret; + +} + +static virCPUarmModelPtr +virCPUarmModelFind(virCPUarmMapPtr 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; +} + +#if defined(__aarch64__) +static virCPUarmModelPtr +virCPUarmModelFindByPVR(virCPUarmMapPtr map, + unsigned long pvr) +{ + size_t i; + + for (i = 0; i < map->nmodels; i++) { + if (map->models[i]->data.pvr == pvr) + return map->models[i]; + } + + return NULL; +} +#endif + +static int +virCPUarmModelParse(xmlXPathContextPtr ctxt, + const char *name, + void *data) +{ + virCPUarmMapPtr map = data; + virCPUarmModel *model; + g_autofree xmlNodePtr *nodes = NULL; + g_autofree char *vendor = NULL; + + if (VIR_ALLOC(model) < 0) + goto error; + + model->name = g_strdup(name); + + if (virCPUarmModelFind(map, model->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU model %s already defined"), + model->name); + goto error; + } + + 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 error; + } + + if (!(model->vendor = virCPUarmVendorFindByName(map, vendor))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown vendor %s referenced by CPU model %s"), + vendor, model->name); + goto error; + } + } + + if (!virXPathBoolean("boolean(./pvr)", ctxt)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing PVR information for CPU model %s"), + model->name); + goto error; + } + + if (virXPathULongHex("string(./pvr/@value)", ctxt, &model->data.pvr) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing or invalid PVR value in CPU model %s"), + model->name); + goto error; + } + + if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0) + goto error; + + return 0; + + error: + virCPUarmModelFree(model); + return -1; +} + static virCPUarmMapPtr virCPUarmLoadMap(void) { @@ -211,8 +379,8 @@ virCPUarmLoadMap(void) map = virCPUarmMapNew(); - if (cpuMapLoad("arm", NULL, virCPUarmMapFeatureParse, NULL, map) < 0) - return NULL; + if (cpuMapLoad("arm", virCPUarmVendorParse, virCPUarmMapFeatureParse, + virCPUarmModelParse, map) < 0) return g_steal_pointer(&map); } @@ -273,7 +441,6 @@ virCPUarmUpdate(virCPUDefPtr guest, return ret; } - static virCPUDefPtr virCPUarmBaseline(virCPUDefPtr *cpus, unsigned int ncpus G_GNUC_UNUSED, -- 2.26.0.windows.1

ping for reviews On Wed, Apr 22, 2020 at 3:12 PM ZhengZhenyu <zheng.zhenyu@foxmail.com> wrote:
Add helper functions to parse vendor and model from xml for ARM arch, and use them as callbacks when load cpu maps.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 173 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 3 deletions(-)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 2009904cc9..6e9ff9bf11 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -204,6 +204,174 @@ virCPUarmMapFeatureParse(xmlXPathContextPtr ctxt G_GNUC_UNUSED, return 0; }
+static virCPUarmVendorPtr +virCPUarmVendorFindByID(virCPUarmMapPtr map, + unsigned long vendor_id) +{ + size_t i; + + for (i = 0; i < map->nvendors; i++) { + if (map->vendors[i]->value == vendor_id) + return map->vendors[i]; + } + + return NULL; +} + + +static virCPUarmVendorPtr +virCPUarmVendorFindByName(virCPUarmMapPtr 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 int +virCPUarmVendorParse(xmlXPathContextPtr ctxt, + const char *name, + void *data) +{ + virCPUarmMapPtr map = data; + virCPUarmVendorPtr vendor = NULL; + int ret = -1; + + if (VIR_ALLOC(vendor) < 0) + return ret; + + vendor->name = g_strdup(name); + + if (virCPUarmVendorFindByName(map, vendor->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor %s already defined"), + vendor->name); + goto cleanup; + } + + if (virXPathULongHex("string(@value)", ctxt, &vendor->value) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing CPU vendor value")); + goto cleanup; + } + + if (virCPUarmVendorFindByID(map, vendor->value)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor value 0x%2lx already defined"), + vendor->value); + goto cleanup; + } + + if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virCPUarmVendorFree(vendor); + return ret; + +} + +static virCPUarmModelPtr +virCPUarmModelFind(virCPUarmMapPtr 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; +} + +#if defined(__aarch64__) +static virCPUarmModelPtr +virCPUarmModelFindByPVR(virCPUarmMapPtr map, + unsigned long pvr) +{ + size_t i; + + for (i = 0; i < map->nmodels; i++) { + if (map->models[i]->data.pvr == pvr) + return map->models[i]; + } + + return NULL; +} +#endif + +static int +virCPUarmModelParse(xmlXPathContextPtr ctxt, + const char *name, + void *data) +{ + virCPUarmMapPtr map = data; + virCPUarmModel *model; + g_autofree xmlNodePtr *nodes = NULL; + g_autofree char *vendor = NULL; + + if (VIR_ALLOC(model) < 0) + goto error; + + model->name = g_strdup(name); + + if (virCPUarmModelFind(map, model->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU model %s already defined"), + model->name); + goto error; + } + + 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 error; + } + + if (!(model->vendor = virCPUarmVendorFindByName(map, vendor))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown vendor %s referenced by CPU model %s"), + vendor, model->name); + goto error; + } + } + + if (!virXPathBoolean("boolean(./pvr)", ctxt)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing PVR information for CPU model %s"), + model->name); + goto error; + } + + if (virXPathULongHex("string(./pvr/@value)", ctxt, &model->data.pvr) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing or invalid PVR value in CPU model %s"), + model->name); + goto error; + } + + if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0) + goto error; + + return 0; + + error: + virCPUarmModelFree(model); + return -1; +} + static virCPUarmMapPtr virCPUarmLoadMap(void) { @@ -211,8 +379,8 @@ virCPUarmLoadMap(void)
map = virCPUarmMapNew();
- if (cpuMapLoad("arm", NULL, virCPUarmMapFeatureParse, NULL, map) < 0) - return NULL; + if (cpuMapLoad("arm", virCPUarmVendorParse, virCPUarmMapFeatureParse, + virCPUarmModelParse, map) < 0)
return g_steal_pointer(&map); } @@ -273,7 +441,6 @@ virCPUarmUpdate(virCPUDefPtr guest, return ret; }
- static virCPUDefPtr virCPUarmBaseline(virCPUDefPtr *cpus, unsigned int ncpus G_GNUC_UNUSED, -- 2.26.0.windows.1

On Wed, Apr 22, 2020 at 15:11:22 +0800, ZhengZhenyu wrote:
Add helper functions to parse vendor and model from xml for ARM arch, and use them as callbacks when load cpu maps.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 173 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 3 deletions(-)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 2009904cc9..6e9ff9bf11 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -204,6 +204,174 @@ virCPUarmMapFeatureParse(xmlXPathContextPtr ctxt G_GNUC_UNUSED, return 0; }
+static virCPUarmVendorPtr +virCPUarmVendorFindByID(virCPUarmMapPtr map, + unsigned long vendor_id) +{ + size_t i; + + for (i = 0; i < map->nvendors; i++) { + if (map->vendors[i]->value == vendor_id) + return map->vendors[i]; + } + + return NULL; +} + + +static virCPUarmVendorPtr +virCPUarmVendorFindByName(virCPUarmMapPtr 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 int +virCPUarmVendorParse(xmlXPathContextPtr ctxt, + const char *name, + void *data)
Wrong indentation.
+{ + virCPUarmMapPtr map = data; + virCPUarmVendorPtr vendor = NULL;
This should be declared as g_autoptr(virCPUarmVendor) vendor = NULL;
+ int ret = -1;
Remove this variable, please.
+ + if (VIR_ALLOC(vendor) < 0) + return ret;
vendor = g_new0(virCPUarmVendor, 1);
+ + vendor->name = g_strdup(name); + + if (virCPUarmVendorFindByName(map, vendor->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor %s already defined"), + vendor->name); + goto cleanup;
return -1;
+ } + + if (virXPathULongHex("string(@value)", ctxt, &vendor->value) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing CPU vendor value")); + goto cleanup;
return -1;
+ } + + if (virCPUarmVendorFindByID(map, vendor->value)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor value 0x%2lx already defined"), + vendor->value); + goto cleanup;
return -1;
+ } + + if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0) + goto cleanup;
return -1;
+ + ret = 0;
return 0;
+ + cleanup: + virCPUarmVendorFree(vendor); + return ret; +
The cleanup section can be dropped.
+} + +static virCPUarmModelPtr +virCPUarmModelFind(virCPUarmMapPtr 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; +} + +#if defined(__aarch64__) +static virCPUarmModelPtr +virCPUarmModelFindByPVR(virCPUarmMapPtr map, + unsigned long pvr) +{ + size_t i; + + for (i = 0; i < map->nmodels; i++) { + if (map->models[i]->data.pvr == pvr) + return map->models[i]; + } + + return NULL; +} +#endif + +static int +virCPUarmModelParse(xmlXPathContextPtr ctxt, + const char *name, + void *data) +{ + virCPUarmMapPtr map = data; + virCPUarmModel *model;
g_autoptr(virCPUArmModel) model = NULL;
+ g_autofree xmlNodePtr *nodes = NULL; + g_autofree char *vendor = NULL; + + if (VIR_ALLOC(model) < 0) + goto error;
model = g_new0(...) And the rest of this function should be modified in similarly to VendorParse, i.e., s/goto error/return -1/ and drop the error section.
+ + model->name = g_strdup(name); + + if (virCPUarmModelFind(map, model->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU model %s already defined"), + model->name); + goto error; + } + + 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 error; + } + + if (!(model->vendor = virCPUarmVendorFindByName(map, vendor))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown vendor %s referenced by CPU model %s"), + vendor, model->name); + goto error; + } + } + + if (!virXPathBoolean("boolean(./pvr)", ctxt)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing PVR information for CPU model %s"), + model->name); + goto error; + } + + if (virXPathULongHex("string(./pvr/@value)", ctxt, &model->data.pvr) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing or invalid PVR value in CPU model %s"), + model->name); + goto error; + } + + if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0) + goto error; + + return 0; + + error: + virCPUarmModelFree(model); + return -1; +} + static virCPUarmMapPtr virCPUarmLoadMap(void) { @@ -211,8 +379,8 @@ virCPUarmLoadMap(void)
map = virCPUarmMapNew();
- if (cpuMapLoad("arm", NULL, virCPUarmMapFeatureParse, NULL, map) < 0) - return NULL; + if (cpuMapLoad("arm", virCPUarmVendorParse, virCPUarmMapFeatureParse, + virCPUarmModelParse, map) < 0)
return NULL;
return g_steal_pointer(&map); } @@ -273,7 +441,6 @@ virCPUarmUpdate(virCPUDefPtr guest, return ret; }
- static virCPUDefPtr virCPUarmBaseline(virCPUDefPtr *cpus, unsigned int ncpus G_GNUC_UNUSED,
This looks like an unintentional change. Jirka

Introduce getHost support for ARM CPU driver, read CPU vendor_id, part_id and flags from registers directly. These codes will only be compiled on aarch64 hardwares. Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 6e9ff9bf11..ec50a5615d 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -21,6 +21,10 @@ */ #include <config.h> +#if defined(__aarch64__) +# include <asm/hwcap.h> +# include <sys/auxv.h> +#endif #include "viralloc.h" #include "cpu.h" @@ -32,6 +36,15 @@ #define VIR_FROM_THIS VIR_FROM_CPU +#if defined(__aarch64__) +/* Shift bit mask for parsing cpu flags */ +# define BIT_SHIFTS(n) (1UL << (n)) +/* The current max number of cpu flags on ARM is 32 */ +# define MAX_CPU_FLAGS 32 +#endif + +VIR_LOG_INIT("cpu.cpu_arm"); + static const virArch archs[] = { VIR_ARCH_ARMV6L, VIR_ARCH_ARMV7B, @@ -491,12 +504,203 @@ virCPUarmValidateFeatures(virCPUDefPtr cpu) return 0; } +#if defined(__aarch64__) +/** + * virCPUarmCpuDataFromRegs: + * + * @data: 64-bit arm CPU specific data + * + * Fetches CPU vendor_id and part_id from MIDR_EL1 register, parse CPU + * flags from AT_HWCAP. There are currently 32 valid flags on ARM arch + * represented by each bit. + */ +static int +virCPUarmCpuDataFromRegs(virCPUarmData *data) +{ + /* Generate human readable flag list according to the order of */ + /* AT_HWCAP bit map */ + const char *flag_list[MAX_CPU_FLAGS] = { + "fp", "asimd", "evtstrm", "aes", "pmull", "sha1", "sha2", + "crc32", "atomics", "fphp", "asimdhp", "cpuid", "asimdrdm", + "jscvt", "fcma", "lrcpc", "dcpop", "sha3", "sm3", "sm4", + "asimddp", "sha512", "sve", "asimdfhm", "dit", "uscat", + "ilrcpc", "flagm", "ssbs", "sb", "paca", "pacg"}; + unsigned long cpuid, hwcaps; + char **features = NULL; + g_autofree char *cpu_feature_str = NULL; + int cpu_feature_index = 0; + size_t i; + + if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("CPUID registers unavailable")); + return -1; + } + + /* read the cpuid data from MIDR_EL1 register */ + asm("mrs %0, MIDR_EL1" : "=r" (cpuid)); + VIR_DEBUG("CPUID read from register: 0x%016lx", cpuid); + + /* parse the coresponding part_id bits */ + data->pvr = cpuid>>4&0xFFF; + /* parse the coresponding vendor_id bits */ + data->vendor_id = cpuid>>24&0xFF; + + hwcaps = getauxval(AT_HWCAP); + VIR_DEBUG("CPU flags read from register: 0x%016lx", hwcaps); + + if (VIR_ALLOC_N(features, MAX_CPU_FLAGS) < 0) + return -1; + + /* shift bit map mask to parse for CPU flags */ + for (i = 0; i< MAX_CPU_FLAGS; i++) { + if (hwcaps & BIT_SHIFTS(i)) { + features[cpu_feature_index] = g_strdup(flag_list[i]); + cpu_feature_index++; + } + } + + if (cpu_feature_index > 1) { + cpu_feature_str = virStringListJoin((const char **)features, " "); + if (!cpu_feature_str) + goto error; + } + data->features = g_strdup(cpu_feature_str); + + return 0; + + error: + virStringListFree(features); + return -1; +} + +static int +virCPUarmDataParseFeatures(virCPUDefPtr cpu, + const virCPUarmData *cpuData) +{ + int ret = -1; + size_t i; + char **features; + + if (!cpu || !cpuData) + return ret; + + if (!(features = virStringSplitCount(cpuData->features, " ", + 0, &cpu->nfeatures))) + return ret; + if (cpu->nfeatures) { + if (VIR_ALLOC_N(cpu->features, cpu->nfeatures) < 0) + goto error; + + for (i = 0; i < cpu->nfeatures; i++) { + cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE; + cpu->features[i].name = g_strdup(features[i]); + } + } + + ret = 0; + + cleanup: + virStringListFree(features); + return ret; + + error: + for (i = 0; i < cpu->nfeatures; i++) + VIR_FREE(cpu->features[i].name); + VIR_FREE(cpu->features); + cpu->nfeatures = 0; + goto cleanup; +} + +static int +virCPUarmDecode(virCPUDefPtr cpu, + const virCPUarmData *cpuData, + virDomainCapsCPUModelsPtr models) +{ + virCPUarmMapPtr map; + virCPUarmModelPtr model; + virCPUarmVendorPtr vendor = NULL; + + if (!cpuData || !(map = virCPUarmGetMap())) + return -1; + + if (!(model = virCPUarmModelFindByPVR(map, cpuData->pvr))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU model with PVR 0x%03lx"), + cpuData->pvr); + return -1; + } + + if (!virCPUModelIsAllowed(model->name, models)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU model %s is not supported by hypervisor"), + model->name); + return -1; + } + + cpu->model = g_strdup(model->name); + + if (cpuData->vendor_id && + !(vendor = virCPUarmVendorFindByID(map, cpuData->vendor_id))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU vendor with vendor id 0x%02lx"), + cpuData->vendor_id); + return -1; + } + + if (vendor) + cpu->vendor = g_strdup(vendor->name); + + if (cpuData->features && + virCPUarmDataParseFeatures(cpu, cpuData) < 0) + return -1; + + return 0; +} + +static int +virCPUarmDecodeCPUData(virCPUDefPtr cpu, + const virCPUData *data, + virDomainCapsCPUModelsPtr models) +{ + return virCPUarmDecode(cpu, &data->data.arm, models); +} + +static int +virCPUarmGetHost(virCPUDefPtr cpu, + virDomainCapsCPUModelsPtr models) +{ + virCPUDataPtr cpuData = NULL; + int ret = -1; + + if (virCPUarmDriverInitialize() < 0) + goto cleanup; + + if (!(cpuData = virCPUDataNew(archs[0]))) + goto cleanup; + + if (virCPUarmCpuDataFromRegs(&cpuData->data.arm) < 0) + goto cleanup; + + ret = virCPUarmDecodeCPUData(cpu, cpuData, models); + + cleanup: + virCPUarmDataFree(cpuData); + return ret; +} +#endif + struct cpuArchDriver cpuDriverArm = { .name = "arm", .arch = archs, .narch = G_N_ELEMENTS(archs), .compare = virCPUarmCompare, +#if defined(__aarch64__) + .getHost = virCPUarmGetHost, + .decode = virCPUarmDecodeCPUData, +#else .decode = NULL, +#endif .encode = NULL, .dataFree = virCPUarmDataFree, .baseline = virCPUarmBaseline, -- 2.26.0.windows.1

gitlab CI testing as suggested: https://gitlab.com/ZhengZhenyu/libvirt/pipelines/134657317 On Wed, Apr 22, 2020 at 3:12 PM ZhengZhenyu <zheng.zhenyu@foxmail.com> wrote:
Introduce getHost support for ARM CPU driver, read CPU vendor_id, part_id and flags from registers directly. These codes will only be compiled on aarch64 hardwares.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 6e9ff9bf11..ec50a5615d 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -21,6 +21,10 @@ */
#include <config.h> +#if defined(__aarch64__) +# include <asm/hwcap.h> +# include <sys/auxv.h> +#endif
#include "viralloc.h" #include "cpu.h" @@ -32,6 +36,15 @@
#define VIR_FROM_THIS VIR_FROM_CPU
+#if defined(__aarch64__) +/* Shift bit mask for parsing cpu flags */ +# define BIT_SHIFTS(n) (1UL << (n)) +/* The current max number of cpu flags on ARM is 32 */ +# define MAX_CPU_FLAGS 32 +#endif + +VIR_LOG_INIT("cpu.cpu_arm"); + static const virArch archs[] = { VIR_ARCH_ARMV6L, VIR_ARCH_ARMV7B, @@ -491,12 +504,203 @@ virCPUarmValidateFeatures(virCPUDefPtr cpu) return 0; }
+#if defined(__aarch64__) +/** + * virCPUarmCpuDataFromRegs: + * + * @data: 64-bit arm CPU specific data + * + * Fetches CPU vendor_id and part_id from MIDR_EL1 register, parse CPU + * flags from AT_HWCAP. There are currently 32 valid flags on ARM arch + * represented by each bit. + */ +static int +virCPUarmCpuDataFromRegs(virCPUarmData *data) +{ + /* Generate human readable flag list according to the order of */ + /* AT_HWCAP bit map */ + const char *flag_list[MAX_CPU_FLAGS] = { + "fp", "asimd", "evtstrm", "aes", "pmull", "sha1", "sha2", + "crc32", "atomics", "fphp", "asimdhp", "cpuid", "asimdrdm", + "jscvt", "fcma", "lrcpc", "dcpop", "sha3", "sm3", "sm4", + "asimddp", "sha512", "sve", "asimdfhm", "dit", "uscat", + "ilrcpc", "flagm", "ssbs", "sb", "paca", "pacg"}; + unsigned long cpuid, hwcaps; + char **features = NULL; + g_autofree char *cpu_feature_str = NULL; + int cpu_feature_index = 0; + size_t i; + + if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("CPUID registers unavailable")); + return -1; + } + + /* read the cpuid data from MIDR_EL1 register */ + asm("mrs %0, MIDR_EL1" : "=r" (cpuid)); + VIR_DEBUG("CPUID read from register: 0x%016lx", cpuid); + + /* parse the coresponding part_id bits */ + data->pvr = cpuid>>4&0xFFF; + /* parse the coresponding vendor_id bits */ + data->vendor_id = cpuid>>24&0xFF; + + hwcaps = getauxval(AT_HWCAP); + VIR_DEBUG("CPU flags read from register: 0x%016lx", hwcaps); + + if (VIR_ALLOC_N(features, MAX_CPU_FLAGS) < 0) + return -1; + + /* shift bit map mask to parse for CPU flags */ + for (i = 0; i< MAX_CPU_FLAGS; i++) { + if (hwcaps & BIT_SHIFTS(i)) { + features[cpu_feature_index] = g_strdup(flag_list[i]); + cpu_feature_index++; + } + } + + if (cpu_feature_index > 1) { + cpu_feature_str = virStringListJoin((const char **)features, " "); + if (!cpu_feature_str) + goto error; + } + data->features = g_strdup(cpu_feature_str); + + return 0; + + error: + virStringListFree(features); + return -1; +} + +static int +virCPUarmDataParseFeatures(virCPUDefPtr cpu, + const virCPUarmData *cpuData) +{ + int ret = -1; + size_t i; + char **features; + + if (!cpu || !cpuData) + return ret; + + if (!(features = virStringSplitCount(cpuData->features, " ", + 0, &cpu->nfeatures))) + return ret; + if (cpu->nfeatures) { + if (VIR_ALLOC_N(cpu->features, cpu->nfeatures) < 0) + goto error; + + for (i = 0; i < cpu->nfeatures; i++) { + cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE; + cpu->features[i].name = g_strdup(features[i]); + } + } + + ret = 0; + + cleanup: + virStringListFree(features); + return ret; + + error: + for (i = 0; i < cpu->nfeatures; i++) + VIR_FREE(cpu->features[i].name); + VIR_FREE(cpu->features); + cpu->nfeatures = 0; + goto cleanup; +} + +static int +virCPUarmDecode(virCPUDefPtr cpu, + const virCPUarmData *cpuData, + virDomainCapsCPUModelsPtr models) +{ + virCPUarmMapPtr map; + virCPUarmModelPtr model; + virCPUarmVendorPtr vendor = NULL; + + if (!cpuData || !(map = virCPUarmGetMap())) + return -1; + + if (!(model = virCPUarmModelFindByPVR(map, cpuData->pvr))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU model with PVR 0x%03lx"), + cpuData->pvr); + return -1; + } + + if (!virCPUModelIsAllowed(model->name, models)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU model %s is not supported by hypervisor"), + model->name); + return -1; + } + + cpu->model = g_strdup(model->name); + + if (cpuData->vendor_id && + !(vendor = virCPUarmVendorFindByID(map, cpuData->vendor_id))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU vendor with vendor id 0x%02lx"), + cpuData->vendor_id); + return -1; + } + + if (vendor) + cpu->vendor = g_strdup(vendor->name); + + if (cpuData->features && + virCPUarmDataParseFeatures(cpu, cpuData) < 0) + return -1; + + return 0; +} + +static int +virCPUarmDecodeCPUData(virCPUDefPtr cpu, + const virCPUData *data, + virDomainCapsCPUModelsPtr models) +{ + return virCPUarmDecode(cpu, &data->data.arm, models); +} + +static int +virCPUarmGetHost(virCPUDefPtr cpu, + virDomainCapsCPUModelsPtr models) +{ + virCPUDataPtr cpuData = NULL; + int ret = -1; + + if (virCPUarmDriverInitialize() < 0) + goto cleanup; + + if (!(cpuData = virCPUDataNew(archs[0]))) + goto cleanup; + + if (virCPUarmCpuDataFromRegs(&cpuData->data.arm) < 0) + goto cleanup; + + ret = virCPUarmDecodeCPUData(cpu, cpuData, models); + + cleanup: + virCPUarmDataFree(cpuData); + return ret; +} +#endif + struct cpuArchDriver cpuDriverArm = { .name = "arm", .arch = archs, .narch = G_N_ELEMENTS(archs), .compare = virCPUarmCompare, +#if defined(__aarch64__) + .getHost = virCPUarmGetHost, + .decode = virCPUarmDecodeCPUData, +#else .decode = NULL, +#endif .encode = NULL, .dataFree = virCPUarmDataFree, .baseline = virCPUarmBaseline, -- 2.26.0.windows.1

On Wed, Apr 22, 2020 at 15:14:01 +0800, Zhenyu Zheng wrote:
gitlab CI testing as suggested: https://gitlab.com/ZhengZhenyu/libvirt/pipelines/134657317
Sending results of CI pipeline makes sense only when the code submitted for CI is exactly the same as submitted for review. You should just push the branch with your local changes to your gitlab repo rather than somehow combining all patches you sent into one or even make additional changes. Apparently the patch pushed to gitlab is a bit different than this series as this series cannot be compiled due to a missing "return NULL;" line in patch 4/5. Anyway, I'm trying to get some ARM hosts and hoping to find at least one where your series would actually detect the host CPU to see how this works in real life and to confirm (or not) my suspicions. No need to resent this series to fix the compilation error yet, I'll fix it myself for testing. Thank you for your patience. Jirka

Thanks alot I will check again about the patch series. On Tue, Apr 28, 2020 at 6:39 PM Jiri Denemark <jdenemar@redhat.com> wrote:
On Wed, Apr 22, 2020 at 15:14:01 +0800, Zhenyu Zheng wrote:
gitlab CI testing as suggested: https://gitlab.com/ZhengZhenyu/libvirt/pipelines/134657317
Sending results of CI pipeline makes sense only when the code submitted for CI is exactly the same as submitted for review. You should just push the branch with your local changes to your gitlab repo rather than somehow combining all patches you sent into one or even make additional changes.
Apparently the patch pushed to gitlab is a bit different than this series as this series cannot be compiled due to a missing "return NULL;" line in patch 4/5.
Anyway, I'm trying to get some ARM hosts and hoping to find at least one where your series would actually detect the host CPU to see how this works in real life and to confirm (or not) my suspicions. No need to resent this series to fix the compilation error yet, I'll fix it myself for testing.
Thank you for your patience.
Jirka

Hi Jiri, Thanks alot for the help, I've updated the series to v4 and also attached pipeline results for each patch as suggested. BR, On Tue, Apr 28, 2020 at 7:11 PM Zhenyu Zheng <zhengzhenyulixi@gmail.com> wrote:
Thanks alot I will check again about the patch series.
On Tue, Apr 28, 2020 at 6:39 PM Jiri Denemark <jdenemar@redhat.com> wrote:
On Wed, Apr 22, 2020 at 15:14:01 +0800, Zhenyu Zheng wrote:
gitlab CI testing as suggested: https://gitlab.com/ZhengZhenyu/libvirt/pipelines/134657317
Sending results of CI pipeline makes sense only when the code submitted for CI is exactly the same as submitted for review. You should just push the branch with your local changes to your gitlab repo rather than somehow combining all patches you sent into one or even make additional changes.
Apparently the patch pushed to gitlab is a bit different than this series as this series cannot be compiled due to a missing "return NULL;" line in patch 4/5.
Anyway, I'm trying to get some ARM hosts and hoping to find at least one where your series would actually detect the host CPU to see how this works in real life and to confirm (or not) my suspicions. No need to resent this series to fix the compilation error yet, I'll fix it myself for testing.
Thank you for your patience.
Jirka

Hi. On Wed, Apr 29, 2020 at 16:03:19 +0800, Zhenyu Zheng wrote:
Hi Jiri,
Thanks alot for the help, I've updated the series to v4 and also attached pipeline results for each patch as suggested.
I explicitly said you don't have to send a new version just for that small issue... And I don't think pipeline results are needed for each patch, one result for the whole series should be enough to assure the code compiles on all tested architectures. Reviewers will usually check themselves whether the series can be compiled after each patch. I just wanted you to take the branch with all the patches and push it to gitlab, which will start a single CI pipeline for all the changes (just like in your v3), but the branch on gitlab will contain each patch of your series as is (while in v3 you squashed all patches into a single commit and pushed that). That said, all this is mainly a guidance for future submission. It's *not* a request for yet another respin of this series. In the meantime I found two AArch64 hosts with CPUs recognized by your changes so I'm playing with them. Jirka

Thanks for the reply, any updates for the review? On Wed, Apr 29, 2020 at 11:45 PM Jiri Denemark <jdenemar@redhat.com> wrote:
Hi.
On Wed, Apr 29, 2020 at 16:03:19 +0800, Zhenyu Zheng wrote:
Hi Jiri,
Thanks alot for the help, I've updated the series to v4 and also attached pipeline results for each patch as suggested.
I explicitly said you don't have to send a new version just for that small issue...
And I don't think pipeline results are needed for each patch, one result for the whole series should be enough to assure the code compiles on all tested architectures. Reviewers will usually check themselves whether the series can be compiled after each patch. I just wanted you to take the branch with all the patches and push it to gitlab, which will start a single CI pipeline for all the changes (just like in your v3), but the branch on gitlab will contain each patch of your series as is (while in v3 you squashed all patches into a single commit and pushed that).
That said, all this is mainly a guidance for future submission. It's *not* a request for yet another respin of this series.
In the meantime I found two AArch64 hosts with CPUs recognized by your changes so I'm playing with them.
Jirka

ping for reviews On Wed, Apr 22, 2020 at 3:12 PM ZhengZhenyu <zheng.zhenyu@foxmail.com> wrote:
Introduce getHost support for ARM CPU driver, read CPU vendor_id, part_id and flags from registers directly. These codes will only be compiled on aarch64 hardwares.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 6e9ff9bf11..ec50a5615d 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -21,6 +21,10 @@ */
#include <config.h> +#if defined(__aarch64__) +# include <asm/hwcap.h> +# include <sys/auxv.h> +#endif
#include "viralloc.h" #include "cpu.h" @@ -32,6 +36,15 @@
#define VIR_FROM_THIS VIR_FROM_CPU
+#if defined(__aarch64__) +/* Shift bit mask for parsing cpu flags */ +# define BIT_SHIFTS(n) (1UL << (n)) +/* The current max number of cpu flags on ARM is 32 */ +# define MAX_CPU_FLAGS 32 +#endif + +VIR_LOG_INIT("cpu.cpu_arm"); + static const virArch archs[] = { VIR_ARCH_ARMV6L, VIR_ARCH_ARMV7B, @@ -491,12 +504,203 @@ virCPUarmValidateFeatures(virCPUDefPtr cpu) return 0; }
+#if defined(__aarch64__) +/** + * virCPUarmCpuDataFromRegs: + * + * @data: 64-bit arm CPU specific data + * + * Fetches CPU vendor_id and part_id from MIDR_EL1 register, parse CPU + * flags from AT_HWCAP. There are currently 32 valid flags on ARM arch + * represented by each bit. + */ +static int +virCPUarmCpuDataFromRegs(virCPUarmData *data) +{ + /* Generate human readable flag list according to the order of */ + /* AT_HWCAP bit map */ + const char *flag_list[MAX_CPU_FLAGS] = { + "fp", "asimd", "evtstrm", "aes", "pmull", "sha1", "sha2", + "crc32", "atomics", "fphp", "asimdhp", "cpuid", "asimdrdm", + "jscvt", "fcma", "lrcpc", "dcpop", "sha3", "sm3", "sm4", + "asimddp", "sha512", "sve", "asimdfhm", "dit", "uscat", + "ilrcpc", "flagm", "ssbs", "sb", "paca", "pacg"}; + unsigned long cpuid, hwcaps; + char **features = NULL; + g_autofree char *cpu_feature_str = NULL; + int cpu_feature_index = 0; + size_t i; + + if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("CPUID registers unavailable")); + return -1; + } + + /* read the cpuid data from MIDR_EL1 register */ + asm("mrs %0, MIDR_EL1" : "=r" (cpuid)); + VIR_DEBUG("CPUID read from register: 0x%016lx", cpuid); + + /* parse the coresponding part_id bits */ + data->pvr = cpuid>>4&0xFFF; + /* parse the coresponding vendor_id bits */ + data->vendor_id = cpuid>>24&0xFF; + + hwcaps = getauxval(AT_HWCAP); + VIR_DEBUG("CPU flags read from register: 0x%016lx", hwcaps); + + if (VIR_ALLOC_N(features, MAX_CPU_FLAGS) < 0) + return -1; + + /* shift bit map mask to parse for CPU flags */ + for (i = 0; i< MAX_CPU_FLAGS; i++) { + if (hwcaps & BIT_SHIFTS(i)) { + features[cpu_feature_index] = g_strdup(flag_list[i]); + cpu_feature_index++; + } + } + + if (cpu_feature_index > 1) { + cpu_feature_str = virStringListJoin((const char **)features, " "); + if (!cpu_feature_str) + goto error; + } + data->features = g_strdup(cpu_feature_str); + + return 0; + + error: + virStringListFree(features); + return -1; +} + +static int +virCPUarmDataParseFeatures(virCPUDefPtr cpu, + const virCPUarmData *cpuData) +{ + int ret = -1; + size_t i; + char **features; + + if (!cpu || !cpuData) + return ret; + + if (!(features = virStringSplitCount(cpuData->features, " ", + 0, &cpu->nfeatures))) + return ret; + if (cpu->nfeatures) { + if (VIR_ALLOC_N(cpu->features, cpu->nfeatures) < 0) + goto error; + + for (i = 0; i < cpu->nfeatures; i++) { + cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE; + cpu->features[i].name = g_strdup(features[i]); + } + } + + ret = 0; + + cleanup: + virStringListFree(features); + return ret; + + error: + for (i = 0; i < cpu->nfeatures; i++) + VIR_FREE(cpu->features[i].name); + VIR_FREE(cpu->features); + cpu->nfeatures = 0; + goto cleanup; +} + +static int +virCPUarmDecode(virCPUDefPtr cpu, + const virCPUarmData *cpuData, + virDomainCapsCPUModelsPtr models) +{ + virCPUarmMapPtr map; + virCPUarmModelPtr model; + virCPUarmVendorPtr vendor = NULL; + + if (!cpuData || !(map = virCPUarmGetMap())) + return -1; + + if (!(model = virCPUarmModelFindByPVR(map, cpuData->pvr))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU model with PVR 0x%03lx"), + cpuData->pvr); + return -1; + } + + if (!virCPUModelIsAllowed(model->name, models)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU model %s is not supported by hypervisor"), + model->name); + return -1; + } + + cpu->model = g_strdup(model->name); + + if (cpuData->vendor_id && + !(vendor = virCPUarmVendorFindByID(map, cpuData->vendor_id))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU vendor with vendor id 0x%02lx"), + cpuData->vendor_id); + return -1; + } + + if (vendor) + cpu->vendor = g_strdup(vendor->name); + + if (cpuData->features && + virCPUarmDataParseFeatures(cpu, cpuData) < 0) + return -1; + + return 0; +} + +static int +virCPUarmDecodeCPUData(virCPUDefPtr cpu, + const virCPUData *data, + virDomainCapsCPUModelsPtr models) +{ + return virCPUarmDecode(cpu, &data->data.arm, models); +} + +static int +virCPUarmGetHost(virCPUDefPtr cpu, + virDomainCapsCPUModelsPtr models) +{ + virCPUDataPtr cpuData = NULL; + int ret = -1; + + if (virCPUarmDriverInitialize() < 0) + goto cleanup; + + if (!(cpuData = virCPUDataNew(archs[0]))) + goto cleanup; + + if (virCPUarmCpuDataFromRegs(&cpuData->data.arm) < 0) + goto cleanup; + + ret = virCPUarmDecodeCPUData(cpu, cpuData, models); + + cleanup: + virCPUarmDataFree(cpuData); + return ret; +} +#endif + struct cpuArchDriver cpuDriverArm = { .name = "arm", .arch = archs, .narch = G_N_ELEMENTS(archs), .compare = virCPUarmCompare, +#if defined(__aarch64__) + .getHost = virCPUarmGetHost, + .decode = virCPUarmDecodeCPUData, +#else .decode = NULL, +#endif .encode = NULL, .dataFree = virCPUarmDataFree, .baseline = virCPUarmBaseline, -- 2.26.0.windows.1

On Wed, Apr 22, 2020 at 15:11:24 +0800, ZhengZhenyu wrote:
Introduce getHost support for ARM CPU driver, read CPU vendor_id, part_id and flags from registers directly. These codes will only be compiled on aarch64 hardwares.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com> --- src/cpu/cpu_arm.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+)
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 6e9ff9bf11..ec50a5615d 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -21,6 +21,10 @@ */
#include <config.h> +#if defined(__aarch64__) +# include <asm/hwcap.h> +# include <sys/auxv.h> +#endif
#include "viralloc.h" #include "cpu.h" @@ -32,6 +36,15 @@
#define VIR_FROM_THIS VIR_FROM_CPU
+#if defined(__aarch64__) +/* Shift bit mask for parsing cpu flags */ +# define BIT_SHIFTS(n) (1UL << (n)) +/* The current max number of cpu flags on ARM is 32 */ +# define MAX_CPU_FLAGS 32 +#endif + +VIR_LOG_INIT("cpu.cpu_arm"); + static const virArch archs[] = { VIR_ARCH_ARMV6L, VIR_ARCH_ARMV7B, @@ -491,12 +504,203 @@ virCPUarmValidateFeatures(virCPUDefPtr cpu) return 0; }
+#if defined(__aarch64__) +/** + * virCPUarmCpuDataFromRegs: + * + * @data: 64-bit arm CPU specific data + * + * Fetches CPU vendor_id and part_id from MIDR_EL1 register, parse CPU + * flags from AT_HWCAP. There are currently 32 valid flags on ARM arch + * represented by each bit. + */ +static int +virCPUarmCpuDataFromRegs(virCPUarmData *data) +{ + /* Generate human readable flag list according to the order of */ + /* AT_HWCAP bit map */ + const char *flag_list[MAX_CPU_FLAGS] = { + "fp", "asimd", "evtstrm", "aes", "pmull", "sha1", "sha2", + "crc32", "atomics", "fphp", "asimdhp", "cpuid", "asimdrdm", + "jscvt", "fcma", "lrcpc", "dcpop", "sha3", "sm3", "sm4", + "asimddp", "sha512", "sve", "asimdfhm", "dit", "uscat", + "ilrcpc", "flagm", "ssbs", "sb", "paca", "pacg"};
I'd move this array out of the function.
+ unsigned long cpuid, hwcaps;
One variable per line, please.
+ char **features = NULL;
VIR_AUTOSTRINGLIST features = NULL;
+ g_autofree char *cpu_feature_str = NULL; + int cpu_feature_index = 0; + size_t i; + + if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("CPUID registers unavailable")); + return -1;
Wrong indentation.
+ } + + /* read the cpuid data from MIDR_EL1 register */ + asm("mrs %0, MIDR_EL1" : "=r" (cpuid)); + VIR_DEBUG("CPUID read from register: 0x%016lx", cpuid); + + /* parse the coresponding part_id bits */ + data->pvr = cpuid>>4&0xFFF;
Please, add spaces around the operators and consider using () for clarity. So, I guess: data->pvr = (cpuid >> 4) & 0xfff;
+ /* parse the coresponding vendor_id bits */ + data->vendor_id = cpuid>>24&0xFF;
data->vendor_id = (cpuid >> 24) & 0xff;
+ + hwcaps = getauxval(AT_HWCAP); + VIR_DEBUG("CPU flags read from register: 0x%016lx", hwcaps); + + if (VIR_ALLOC_N(features, MAX_CPU_FLAGS) < 0) + return -1;
The string list is supposed to be NULL-terminated so you need to allocate space for MAX_CPU_FLAGS + 1: features = g_new0(char *, MAX_CPU_FLAGS + 1);
+ + /* shift bit map mask to parse for CPU flags */ + for (i = 0; i< MAX_CPU_FLAGS; i++) {
i < MAX_CPU_FLAGS
+ if (hwcaps & BIT_SHIFTS(i)) { + features[cpu_feature_index] = g_strdup(flag_list[i]); + cpu_feature_index++; + }
This could also be written as if (hwcaps & BIT_SHIFTS(i)) features[cpu_feature_index++] = g_strdup(flag_list[i]); it doesn't matter that much, though.
+ } + + if (cpu_feature_index > 1) {
This would not work for CPUs with exactly one feature.
+ cpu_feature_str = virStringListJoin((const char **)features, " "); + if (!cpu_feature_str) + goto error; + } + data->features = g_strdup(cpu_feature_str);
Just store the features string list in the data directly: if (cpu_feature_index > 0) data->features = g_steal_pointer(&features);
+ + return 0; + + error: + virStringListFree(features); + return -1;
This can be dropped thanks to VIR_AUTOSTRINGLIST.
+} + +static int +virCPUarmDataParseFeatures(virCPUDefPtr cpu, + const virCPUarmData *cpuData) +{ + int ret = -1; + size_t i; + char **features; + + if (!cpu || !cpuData) + return ret; + + if (!(features = virStringSplitCount(cpuData->features, " ", + 0, &cpu->nfeatures))) + return ret;
Please don't do this. The virCPUarmData can contain the feature list directly.
+ if (cpu->nfeatures) { + if (VIR_ALLOC_N(cpu->features, cpu->nfeatures) < 0) + goto error; + + for (i = 0; i < cpu->nfeatures; i++) { + cpu->features[i].policy = VIR_CPU_FEATURE_REQUIRE; + cpu->features[i].name = g_strdup(features[i]); + } + }
I'd move this loop to virCPUarmDecode as this function name is pretty confusing and there won't be much more than this loop in it when the feature list is stored directly in virCPUarmData.
+ + ret = 0; + + cleanup: + virStringListFree(features); + return ret; + + error: + for (i = 0; i < cpu->nfeatures; i++) + VIR_FREE(cpu->features[i].name); + VIR_FREE(cpu->features); + cpu->nfeatures = 0; + goto cleanup; +} + +static int +virCPUarmDecode(virCPUDefPtr cpu, + const virCPUarmData *cpuData, + virDomainCapsCPUModelsPtr models) +{ + virCPUarmMapPtr map; + virCPUarmModelPtr model; + virCPUarmVendorPtr vendor = NULL; + + if (!cpuData || !(map = virCPUarmGetMap())) + return -1; + + if (!(model = virCPUarmModelFindByPVR(map, cpuData->pvr))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU model with PVR 0x%03lx"), + cpuData->pvr); + return -1; + } + + if (!virCPUModelIsAllowed(model->name, models)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU model %s is not supported by hypervisor"), + model->name); + return -1; + } + + cpu->model = g_strdup(model->name); + + if (cpuData->vendor_id && + !(vendor = virCPUarmVendorFindByID(map, cpuData->vendor_id))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU vendor with vendor id 0x%02lx"), + cpuData->vendor_id); + return -1; + } + + if (vendor) + cpu->vendor = g_strdup(vendor->name); + + if (cpuData->features && + virCPUarmDataParseFeatures(cpu, cpuData) < 0) + return -1;
Hmm, the code seems to be inconsistent with the cpu_map definitions: - Either you define CPU models without any features and add all the detected features to the host CPU definition (this is what your current code does). - Or you define CPU models with features and only add extra features (those not included in the model definition) to the host CPU definition (this is what the cpu_map changes suggest). In this case you also need to implement virCPUExpandFeatures API for the arm driver to make sure one can get both the base and extra features. Personally, I think the first option is both simpler and better for reporting host CPU model and features.
+ + return 0; +} + +static int +virCPUarmDecodeCPUData(virCPUDefPtr cpu, + const virCPUData *data, + virDomainCapsCPUModelsPtr models) +{ + return virCPUarmDecode(cpu, &data->data.arm, models); +}
This function is not needed.
+ +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 (virCPUarmCpuDataFromRegs(&cpuData->data.arm) < 0) + goto cleanup; + + ret = virCPUarmDecodeCPUData(cpu, cpuData, models);
You can call virCPUarmDecode directly here.
+ + cleanup: + virCPUarmDataFree(cpuData); + return ret; +} +#endif + struct cpuArchDriver cpuDriverArm = { .name = "arm", .arch = archs, .narch = G_N_ELEMENTS(archs), .compare = virCPUarmCompare, +#if defined(__aarch64__) + .getHost = virCPUarmGetHost, + .decode = virCPUarmDecodeCPUData, +#else .decode = NULL, +#endif
Just #if defined(__aarch64__) .getHost = virCPUarmGetHost, #endif is enough, there should be no need to initialize .decode to implement host CPU detection.
.encode = NULL, .dataFree = virCPUarmDataFree, .baseline = virCPUarmBaseline,
Jirka

ping for reviews On Wed, Apr 22, 2020 at 3:11 PM ZhengZhenyu <zheng.zhenyu@foxmail.com> wrote:
Introduce getHost support for ARM CPU driver. First add some data about commonly used ARM CPU models, and their vendors into cpu_map, then added some helper methods as callbacks to load them. Read and parse vendor_id, part_id and CPU flags of local CPU from corresponding registers.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com>
ZhengZhenyu (5): cpu_map: Introduce ARM cpu models cpu: Introduce virCPUarmData to virCPUData cpu: Introduce ARM related structs cpu: Add helper funtions to parse vendor and model cpu: Introduce getHost support for ARM CPU driver
src/cpu/Makefile.inc.am | 1 + src/cpu/cpu.h | 2 + src/cpu/cpu_arm.c | 450 +++++++++++++++++++++++++++++- src/cpu/cpu_arm_data.h | 31 ++ src/cpu_map/Makefile.inc.am | 7 + src/cpu_map/arm_Falkor.xml | 16 ++ src/cpu_map/arm_Kunpeng-920.xml | 24 ++ src/cpu_map/arm_ThunderX299xx.xml | 16 ++ src/cpu_map/arm_cortex-a53.xml | 16 ++ src/cpu_map/arm_cortex-a57.xml | 15 + src/cpu_map/arm_cortex-a72.xml | 15 + src/cpu_map/arm_vendors.xml | 14 + src/cpu_map/index.xml | 15 + 13 files changed, 619 insertions(+), 3 deletions(-) create mode 100644 src/cpu/cpu_arm_data.h create mode 100644 src/cpu_map/arm_Falkor.xml create mode 100644 src/cpu_map/arm_Kunpeng-920.xml create mode 100644 src/cpu_map/arm_ThunderX299xx.xml create mode 100644 src/cpu_map/arm_cortex-a53.xml create mode 100644 src/cpu_map/arm_cortex-a57.xml create mode 100644 src/cpu_map/arm_cortex-a72.xml create mode 100644 src/cpu_map/arm_vendors.xml
-- 2.26.0.windows.1

On Wed, Apr 22, 2020 at 15:11:14 +0800, ZhengZhenyu wrote:
Introduce getHost support for ARM CPU driver. First add some data about commonly used ARM CPU models, and their vendors into cpu_map, then added some helper methods as callbacks to load them. Read and parse vendor_id, part_id and CPU flags of local CPU from corresponding registers.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com>
The emails come from ZhengZhenyu <zheng.zhenyu@foxmail.com>, but the signed-off-by line says something else. Could you make them consistent? BTW, I'm intentionally replying to v3 as v4 was only supposed to have a one line diff to v3, but it was sent with both html and plain text parts and git am was unable to apply any of the v4 patches. Jirka

Hi Jirka, Thanks alot for the review and suggestions, I will try to fix them. As for v4, I saw there was a "email patch" button in gitlab, so I used that, so seems it is not correct :) BR On Tue, May 12, 2020 at 11:38 PM Jiri Denemark <jdenemar@redhat.com> wrote:
On Wed, Apr 22, 2020 at 15:11:14 +0800, ZhengZhenyu wrote:
Introduce getHost support for ARM CPU driver. First add some data about commonly used ARM CPU models, and their vendors into cpu_map, then added some helper methods as callbacks to load them. Read and parse vendor_id, part_id and CPU flags of local CPU from corresponding registers.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com>
The emails come from ZhengZhenyu <zheng.zhenyu@foxmail.com>, but the signed-off-by line says something else. Could you make them consistent?
BTW, I'm intentionally replying to v3 as v4 was only supposed to have a one line diff to v3, but it was sent with both html and plain text parts and git am was unable to apply any of the v4 patches.
Jirka

Thanks alot for the review, I've update the patches as suggested as V5 and attached the pipeline CI for the last patch to show build results for the series. On Wed, May 13, 2020 at 9:09 AM Zhenyu Zheng <zhengzhenyulixi@gmail.com> wrote:
Hi Jirka,
Thanks alot for the review and suggestions, I will try to fix them. As for v4, I saw there was a "email patch" button in gitlab, so I used that, so seems it is not correct :)
BR
On Tue, May 12, 2020 at 11:38 PM Jiri Denemark <jdenemar@redhat.com> wrote:
On Wed, Apr 22, 2020 at 15:11:14 +0800, ZhengZhenyu wrote:
Introduce getHost support for ARM CPU driver. First add some data about commonly used ARM CPU models, and their vendors into cpu_map, then added some helper methods as callbacks to load them. Read and parse vendor_id, part_id and CPU flags of local CPU from corresponding registers.
Signed-off-by: Zhenyu Zheng <zhengzhenyulixi@gmail.com>
The emails come from ZhengZhenyu <zheng.zhenyu@foxmail.com>, but the signed-off-by line says something else. Could you make them consistent?
BTW, I'm intentionally replying to v3 as v4 was only supposed to have a one line diff to v3, but it was sent with both html and plain text parts and git am was unable to apply any of the v4 patches.
Jirka
participants (3)
-
Jiri Denemark
-
ZhengZhenyu
-
Zhenyu Zheng