[libvirt PATCH 0/3] cpu: Fix build on some aarch64 platforms

The current code was written under the assumption that any platform that supports aarch64 will have either getauxval() or elf_aux_info(), but that's not always true. Andrea Bolognani (3): cpu: Only include <sys/auxv.h> if available cpu: Only retrieve AT_HWCAP once cpu: Fix build on some aarch64 platforms meson.build | 1 + src/cpu/cpu_arm.c | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 14 deletions(-) -- 2.26.2

It's glibc-specific, so it's not present on many non-Linux targets that nonetheless support aarch64. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- meson.build | 1 + src/cpu/cpu_arm.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 095d6ca664..766bc06b61 100644 --- a/meson.build +++ b/meson.build @@ -690,6 +690,7 @@ headers = [ 'net/if.h', 'pty.h', 'pwd.h', + 'sys/auxv.h', 'sys/ioctl.h', 'sys/mount.h', 'sys/syscall.h', diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 6ba5bf0724..aa3e5d8980 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -25,7 +25,9 @@ # if defined(WITH_ASM_HWCAP_H) # include <asm/hwcap.h> # endif -# include <sys/auxv.h> +# if defined(WITH_SYS_AUXV_H) +# include <sys/auxv.h> +# endif #endif #include "viralloc.h" -- 2.26.2

On Sun, Feb 07, 2021 at 02:45:57PM +0100, Andrea Bolognani wrote:
It's glibc-specific, so it's not present on many non-Linux targets that nonetheless support aarch64.
Not true that it's glibc specific, it is available on FreeBSD as well but it provides elf_aux_info instead of getauxval.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- meson.build | 1 + src/cpu/cpu_arm.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build index 095d6ca664..766bc06b61 100644 --- a/meson.build +++ b/meson.build @@ -690,6 +690,7 @@ headers = [ 'net/if.h', 'pty.h', 'pwd.h', + 'sys/auxv.h', 'sys/ioctl.h', 'sys/mount.h', 'sys/syscall.h', diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 6ba5bf0724..aa3e5d8980 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -25,7 +25,9 @@ # if defined(WITH_ASM_HWCAP_H) # include <asm/hwcap.h> # endif -# include <sys/auxv.h> +# if defined(WITH_SYS_AUXV_H) +# include <sys/auxv.h> +# endif #endif
#include "viralloc.h" -- 2.26.2

No need to fetch the same information twice. As a side effect, this solves a bug where, on platforms where elf_aux_info() is used instead of getauxval(), we would not make sure the CPUID feature is available before attempting to use it. Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/cpu/cpu_arm.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index aa3e5d8980..71702dbc91 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -557,12 +557,19 @@ virCPUarmCpuDataFromRegs(virCPUarmData *data) size_t i; # if defined(WITH_GETAUXVAL) - if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) { + hwcaps = getauxval(AT_HWCAP); +# elif defined(WITH_ELF_AUX_INFO) + elf_aux_info(AT_HWCAP, &hwcaps, sizeof(u_long)); +# else +# error No routines to retrieve a value from the auxiliary vector +# endif + VIR_DEBUG("CPU flags read from register: 0x%016lx", hwcaps); + + if (!(hwcaps & HWCAP_CPUID)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("CPUID registers unavailable")); return -1; } -# endif /* read the cpuid data from MIDR_EL1 register */ asm("mrs %0, MIDR_EL1" : "=r" (cpuid)); @@ -573,15 +580,6 @@ virCPUarmCpuDataFromRegs(virCPUarmData *data) /* parse the corresponding vendor_id bits */ data->vendor_id = (cpuid >> 24) & 0xff; -# if defined(WITH_GETAUXVAL) - hwcaps = getauxval(AT_HWCAP); -# elif defined(WITH_ELF_AUX_INFO) - elf_aux_info(AT_HWCAP, &hwcaps, sizeof(u_long)); -# else -# error No routines to retrieve a value from the auxiliary vector -# endif - VIR_DEBUG("CPU flags read from register: 0x%016lx", hwcaps); - features = g_new0(char *, MAX_CPU_FLAGS + 1); /* shift bit map mask to parse for CPU flags */ -- 2.26.2

On platforms that lack both getauxval() and elf_aux_info(), such as OpenBSD and macOS, host CPU detection can't work. https://gitlab.com/libvirt/libvirt/-/issues/121 Signed-off-by: Andrea Bolognani <abologna@redhat.com> --- src/cpu/cpu_arm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 71702dbc91..6da84535ba 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -529,7 +529,7 @@ virCPUarmValidateFeatures(virCPUDefPtr cpu) return 0; } -#if defined(__aarch64__) +#if defined(__aarch64__) && (defined(WITH_GETAUXVAL) || defined(WITH_ELF_AUX_INFO)) /* Generate human readable flag list according to the order of */ /* AT_HWCAP bit map */ const char *aarch64_cpu_flags[MAX_CPU_FLAGS] = { @@ -560,8 +560,6 @@ virCPUarmCpuDataFromRegs(virCPUarmData *data) hwcaps = getauxval(AT_HWCAP); # elif defined(WITH_ELF_AUX_INFO) elf_aux_info(AT_HWCAP, &hwcaps, sizeof(u_long)); -# else -# error No routines to retrieve a value from the auxiliary vector # endif VIR_DEBUG("CPU flags read from register: 0x%016lx", hwcaps); @@ -674,7 +672,7 @@ struct cpuArchDriver cpuDriverArm = { .arch = archs, .narch = G_N_ELEMENTS(archs), .compare = virCPUarmCompare, -#if defined(__aarch64__) +#if defined(__aarch64__) && (defined(WITH_GETAUXVAL) || defined(WITH_ELF_AUX_INFO)) .getHost = virCPUarmGetHost, #endif .decode = NULL, -- 2.26.2

On Sun, Feb 07, 2021 at 02:45:56PM +0100, Andrea Bolognani wrote:
The current code was written under the assumption that any platform that supports aarch64 will have either getauxval() or elf_aux_info(), but that's not always true.
Andrea Bolognani (3): cpu: Only include <sys/auxv.h> if available cpu: Only retrieve AT_HWCAP once cpu: Fix build on some aarch64 platforms
With the commit message fixed in first patch Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
participants (2)
-
Andrea Bolognani
-
Pavel Hrdina