Subject: Re: Detecting AArch32 support from a AArch64 process in user space

From: Dave Martin <[email-masked]>
Date: Thu, 8 Aug 2019 10:35:24 +0100

On Thu, Aug 08, 2019 at 09:36:42AM +0200, Stefan Agner wrote:
> [resend this time with the correct mailing list address]
> 
> Hello,
> 
> I am trying to detect whether an ARMv8 system running in AArch64 state
> supports AArch32 state from a user space process. The arm64_features[]
> in

Why?  Is this just for diagnostic purposes, or some programmatic reason?

In the latter case, just try to do what ever it is you want to do that
depends on AArch32: if it fails, you don't have AArch32.

> arch/arm64/kernel/cpufeature.c lists a CPU feature "32-bit EL0 Support".
> However, afaik this CPU feature is not directly exposed to user-space.
> The features do get printed in the kernel log, but that requires
> privileges and only works directly after boot. There is

Please don't scrape dmesg :)

However, detecting AArch32 support is a bit annoying due to the fact
that there's no hwcap or similar.

> system_supports_32bit_el0() which is used in various places in the arm64
> architecture code. One of the instances where I can make sense of from
> user space is through the personality system call. One idea is to call
> personality(PER_LINUX32). It would then return error code 22 in case
> 32-bit is not supported in user space. However, if successful this
> changes the personality of the current process which might have side
> effects which I do not want...?
> 
> I started to ask myself what PER_LINUX32 actually changes. From what I
> can tell it only changes the behavior of /proc/cpuinfo? The personality
> seems not to be applied automatically to 32-bit processes, so this is a
> opt-in backward compatibility feature?

Basically yes.  Nonetheless, this is probably a reasonable way to test
for AArch32 userspace support.

> To be on the safe side, I was thinking about executing the system call
> in a separate process. However, at that point I could also just execute
> a statically linked AArch32 binary and see whether I get a "exec format
> error". I guess this could then be either due to missing AArch32 CPU
> support or the kernel not being compiled with 32-bit compatibility.

personality() returns the old personality, so you providing you don't
have multiple threads you can probably try to set it to PER_LINUX32
and then restore it.

Otherwise, you would need to fork and try personality() from the child.

Or as you suggest, try to exec a 32-bit binary.
		
> At last I was considering reading directly from the CPU. But from what I
> understand the register used in the kernel to determine 32-bit
> compatibility (ID_AA64PFR0_EL1) is not accessible by user space (due to
> the suffix _EL1).
> 
> Any advice/thoughts on this topic?

This register is emulated for userspace, so you can read it.  However,
the relevant field gets masked out, so this is probably not much use to
you.

We could expose the field, but a test that relies on it wouldn't be
backwards compatible.

If you just want to do this test from a script for diagnostic purposes
and the filesystem has util-linux, then something like

	linux32 /bin/true

might also work (this is effectively a scripted version of the
personality(PER_LINUX32) test).

Cheers
---Dave

_______________________________________________
linux-arm-kernel mailing list
[email-masked]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel