Index | Thread | Search

From:
Jeremie Courreges-Anglas <jca@wxcvbn.org>
Subject:
Re: Emulate CPU ID register access on arm64
To:
Mark Kettenis <mark.kettenis@xs4all.nl>
Cc:
patrick@openbsd.org, tech@openbsd.org, brad@comstyle.com
Date:
Sun, 14 Jul 2024 12:52:36 +0200

Download raw body.

Thread
On Sun, Jul 14, 2024 at 11:25:27AM +0200, Mark Kettenis wrote:
> As mentioned in the HWCAP discussion, new arm64 bits are typically no
> longer assigned and instead the HWCAP_CPUID bit is used to signal that
> the kernel emulates access to the CPU ID registers.  The diff below
> implements this.
> 
> The architecture is clearly designed to make emulattion possible and
> easy.  There is a special trap for MSR access and it provides all the
> detailt needed to emulate access without the need to read the
> instruction.  The trapping from EL0 is probably done to let the OS
> sanitize the values such that only features relevant to userland and
> common to all CPU cores in the system are advertised.
> 
> There are some open questions though.  The diff is rather strict in
> what access it emulates.  For now this is only the "known" ID_AA64_xxx
> registers, that is the ID_AA64_xxx registers that are currently
> defined by the architectures.  I think the architecture actually says
> that the currently undefined ID_AA64_xxx registers should return zero,
> and Linux allows access to them all.  But I would like to know when
> userland processes actually start accessing those, so for now we'll
> SIGILL.

ack

> I didn't implement emulation for the "32-bit" ID_xxx registers.  We
> don't support excuting 32-bit processes so these registers should be
> irrelevant.  But they can be accessed using arm64 instructions, so for
> now we'll continue to SIGILL these as well.

No idea how often those registers might be used.

> Then ther are the MIDR_EL1 and MPIDR_EL1 registers.  Linux allows
> access to these registers.  The problem with these is that their
> values may depend on what CPU a process is executed on.  So in general
> I don't think userland code should look at these.  However, some
> userland code looks at these since certain optimizations might apply
> only to specific CPU implementations.  On amd64, where the CPUID
> instruction is available to userland, looking at the CPU familiy and
> model bits is accepted practice.

Looks like killing processes for (at least) MIDR_EL1 access would lead
to breakage in a bunch of ports.

For example there is devel/abseil-cpp and the copies of it bundled
into other ports.  The detection is currently done through
getauxval(3) but letting this SIGILL would be an inconvenient trap for
anyone adding detection through elf_aux_info(3).

https://codesearch.debian.net/search?q=%26.*HWCAP_CPUID&literal=0

Granted, as long as we don't advertize HWCAP_CPUID your proposal is
still more lenient/useful than our current policy of always have
userland trap.

> Thoughts?

I won't address all your open questions, I'll just point out that the
refactoring using cpu_identify_cleanup() makes sense on its own and
would be useful to implement the rest of the HWCAP_* bits.  This part
of the changes is ok jca@ FWIW, I don't feel particularly qualified to
look at the MSR code/defines changes.

BTW you're introducing a static function there:

> +static int
> +emulate_msr(struct trapframe *frame, uint64_t esr)
> +{

-- 
jca