[PATCH] linux-user/alpha: populate AT_HWCAP from env->amask

Matt Turner posted 1 patch 1 week, 5 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260713013610.2691128-1-mattst88@gmail.com
Maintainers: Laurent Vivier <laurent@vivier.eu>, Helge Deller <deller@gmx.de>, Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
linux-user/alpha/elfload.c    | 11 +++++++++++
linux-user/alpha/target_elf.h |  1 +
2 files changed, 12 insertions(+)
[PATCH] linux-user/alpha: populate AT_HWCAP from env->amask
Posted by Matt Turner 1 week, 5 days ago
Alpha has never set AT_HWCAP in linux-user emulation, so getauxval(AT_HWCAP)
always returned 0 regardless of the emulated CPU model.

The Linux kernel computes ELF_HWCAP as ~amask(-1), i.e. the set of ISA
extension bits that the amask instruction reports as supported (cleared in
its output).  env->amask stores exactly those bits with the same layout
(BWX=0x1, FIX=0x2, CIX=0x4, MVI=0x100, TRAP=0x200, PREFETCH=0x1000), so
returning it directly from get_elf_hwcap matches the kernel convention.

Add HAVE_ELF_HWCAP to target_elf.h and implement get_elf_hwcap() in
elfload.c to expose the emulated CPU's capability mask to user-space
programs via the auxiliary vector.

Without this fix, programs using getauxval(AT_HWCAP) to detect BWX/FIX/CIX
(such as glibc's memcpy or JIT compilers targeting Alpha) incorrectly
concluded that no extensions were available even when emulating ev56+.
---
 linux-user/alpha/elfload.c    | 11 +++++++++++
 linux-user/alpha/target_elf.h |  1 +
 2 files changed, 12 insertions(+)

diff --git ./linux-user/alpha/elfload.c ./linux-user/alpha/elfload.c
index 1969f620a5..7be9e466b6 100644
--- ./linux-user/alpha/elfload.c
+++ ./linux-user/alpha/elfload.c
@@ -6,6 +6,17 @@
 #include "target_elf.h"
 
 
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+    /*
+     * The Linux kernel computes ELF_HWCAP as ~amask(-1), which clears a bit
+     * for each supported ISA extension.  env->amask stores exactly those bits
+     * set for the extensions supported by the emulated CPU model, matching
+     * the kernel's convention: bit set in AT_HWCAP ↔ extension present.
+     */
+    return cpu_env(cs)->amask;
+}
+
 void elf_core_copy_regs(target_elf_gregset_t *r, const CPUAlphaState *env)
 {
     int i;
diff --git ./linux-user/alpha/target_elf.h ./linux-user/alpha/target_elf.h
index 4987ae3944..dd90c6f783 100644
--- ./linux-user/alpha/target_elf.h
+++ ./linux-user/alpha/target_elf.h
@@ -12,6 +12,7 @@
 #define ELF_MACHINE             EM_ALPHA
 
 #define HAVE_ELF_CORE_DUMP      1
+#define HAVE_ELF_HWCAP          1
 
 /*
  * Matches the kernel's elf_gregset_t (ELF_NGREG = 33):
-- 
2.54.0


Re: [PATCH] linux-user/alpha: populate AT_HWCAP from env->amask
Posted by Michael Tokarev 1 week, 3 days ago
On 7/13/26 04:36, Matt Turner wrote:
> Alpha has never set AT_HWCAP in linux-user emulation, so getauxval(AT_HWCAP)
> always returned 0 regardless of the emulated CPU model.
> 
> The Linux kernel computes ELF_HWCAP as ~amask(-1), i.e. the set of ISA
> extension bits that the amask instruction reports as supported (cleared in
> its output).  env->amask stores exactly those bits with the same layout
> (BWX=0x1, FIX=0x2, CIX=0x4, MVI=0x100, TRAP=0x200, PREFETCH=0x1000), so
> returning it directly from get_elf_hwcap matches the kernel convention.
> 
> Add HAVE_ELF_HWCAP to target_elf.h and implement get_elf_hwcap() in
> elfload.c to expose the emulated CPU's capability mask to user-space
> programs via the auxiliary vector.
> 
> Without this fix, programs using getauxval(AT_HWCAP) to detect BWX/FIX/CIX
> (such as glibc's memcpy or JIT compilers targeting Alpha) incorrectly
> concluded that no extensions were available even when emulating ev56+.

In stable 10.0.x qemu series, things are different from what we have
now, - there, everything is in single linux-user/elfload.c and the
context is a bit different too.

Here's my backport of this change to 10.0.x:
https://gitlab.com/mjt0k/qemu/-/commit/e4c1bf9b1fe030ef1d0d4c74086cccb62c6b0442

I appreciate a quick look at the result, whenever it looks good for
10.0.x or not.

Thanks,

/mjt

>   linux-user/alpha/elfload.c    | 11 +++++++++++
>   linux-user/alpha/target_elf.h |  1 +
>   2 files changed, 12 insertions(+)
> 
> diff --git ./linux-user/alpha/elfload.c ./linux-user/alpha/elfload.c
> index 1969f620a5..7be9e466b6 100644
> --- ./linux-user/alpha/elfload.c
> +++ ./linux-user/alpha/elfload.c
> @@ -6,6 +6,17 @@
>   #include "target_elf.h"
>   
>   
> +abi_ulong get_elf_hwcap(CPUState *cs)
> +{
> +    /*
> +     * The Linux kernel computes ELF_HWCAP as ~amask(-1), which clears a bit
> +     * for each supported ISA extension.  env->amask stores exactly those bits
> +     * set for the extensions supported by the emulated CPU model, matching
> +     * the kernel's convention: bit set in AT_HWCAP ↔ extension present.
> +     */
> +    return cpu_env(cs)->amask;
> +}
> +
>   void elf_core_copy_regs(target_elf_gregset_t *r, const CPUAlphaState *env)
>   {
>       int i;
> diff --git ./linux-user/alpha/target_elf.h ./linux-user/alpha/target_elf.h
> index 4987ae3944..dd90c6f783 100644
> --- ./linux-user/alpha/target_elf.h
> +++ ./linux-user/alpha/target_elf.h
> @@ -12,6 +12,7 @@
>   #define ELF_MACHINE             EM_ALPHA
>   
>   #define HAVE_ELF_CORE_DUMP      1
> +#define HAVE_ELF_HWCAP          1
>   
>   /*
>    * Matches the kernel's elf_gregset_t (ELF_NGREG = 33):


Re: [PATCH] linux-user/alpha: populate AT_HWCAP from env->amask
Posted by Matt Turner 1 week, 2 days ago
On Wed, Jul 15, 2026 at 7:23 AM Michael Tokarev <mjt@tls.msk.ru> wrote:
>
> On 7/13/26 04:36, Matt Turner wrote:
> > Alpha has never set AT_HWCAP in linux-user emulation, so getauxval(AT_HWCAP)
> > always returned 0 regardless of the emulated CPU model.
> >
> > The Linux kernel computes ELF_HWCAP as ~amask(-1), i.e. the set of ISA
> > extension bits that the amask instruction reports as supported (cleared in
> > its output).  env->amask stores exactly those bits with the same layout
> > (BWX=0x1, FIX=0x2, CIX=0x4, MVI=0x100, TRAP=0x200, PREFETCH=0x1000), so
> > returning it directly from get_elf_hwcap matches the kernel convention.
> >
> > Add HAVE_ELF_HWCAP to target_elf.h and implement get_elf_hwcap() in
> > elfload.c to expose the emulated CPU's capability mask to user-space
> > programs via the auxiliary vector.
> >
> > Without this fix, programs using getauxval(AT_HWCAP) to detect BWX/FIX/CIX
> > (such as glibc's memcpy or JIT compilers targeting Alpha) incorrectly
> > concluded that no extensions were available even when emulating ev56+.
>
> In stable 10.0.x qemu series, things are different from what we have
> now, - there, everything is in single linux-user/elfload.c and the
> context is a bit different too.
>
> Here's my backport of this change to 10.0.x:
> https://gitlab.com/mjt0k/qemu/-/commit/e4c1bf9b1fe030ef1d0d4c74086cccb62c6b0442
>
> I appreciate a quick look at the result, whenever it looks good for
> 10.0.x or not.

Looks good to me. Thank you!
Re: [PATCH] linux-user/alpha: populate AT_HWCAP from env->amask
Posted by Helge Deller 1 week, 5 days ago
On 7/13/26 03:36, Matt Turner wrote:
> Alpha has never set AT_HWCAP in linux-user emulation, so getauxval(AT_HWCAP)
> always returned 0 regardless of the emulated CPU model.
> 
> The Linux kernel computes ELF_HWCAP as ~amask(-1), i.e. the set of ISA
> extension bits that the amask instruction reports as supported (cleared in
> its output).  env->amask stores exactly those bits with the same layout
> (BWX=0x1, FIX=0x2, CIX=0x4, MVI=0x100, TRAP=0x200, PREFETCH=0x1000), so
> returning it directly from get_elf_hwcap matches the kernel convention.
> 
> Add HAVE_ELF_HWCAP to target_elf.h and implement get_elf_hwcap() in
> elfload.c to expose the emulated CPU's capability mask to user-space
> programs via the auxiliary vector.
> 
> Without this fix, programs using getauxval(AT_HWCAP) to detect BWX/FIX/CIX
> (such as glibc's memcpy or JIT compilers targeting Alpha) incorrectly
> concluded that no extensions were available even when emulating ev56+.
> ---
>   linux-user/alpha/elfload.c    | 11 +++++++++++
>   linux-user/alpha/target_elf.h |  1 +
>   2 files changed, 12 insertions(+)
Reviewed-by: Helge Deller <deller@gmx.de>

I'll include this patch in the next linux-user pull request.
Helge