[PATCH 2/3] arm64: use XPACLRI to strip PAC

Mark Rutland mark.rutland at arm.com
Wed Apr 12 09:01:00 PDT 2023


On Tue, Apr 11, 2023 at 06:12:01PM +0100, Will Deacon wrote:
> On Thu, Apr 06, 2023 at 04:48:23PM +0100, Mark Rutland wrote:
> > On Thu, Apr 06, 2023 at 04:30:36PM +0100, Will Deacon wrote:
> > > On Tue, Mar 14, 2023 at 04:20:43PM +0000, Mark Rutland wrote:
> > > > Currently we strip the PAC from pointers using C code, which requires
> > > > generating bitmasks, and conditionally clearing/setting bits depending
> > > > on bit 55. We can do better by using XPACLRI directly.
> > > > 
> > > > When the logic was originally written to strip PACs from user pointers,
> > > > contemporary toolchains used for the kernel had assemblers which were
> > > > unaware of the PAC instructions. As stripping the PAC from userspace
> > > > pointers required unconditional clearing of a fixed set of bits (which
> > > > could be performed with a single instruction), it was simpler to
> > > > implement the masking in C than it was to make use of XPACI or XPACLRI.
> > > > 
> > > > When support for in-kernel pointer authentication was added, the
> > > > stripping logic was extended to cover TTBR1 pointers, requiring several
> > > > instructions to handle whether to clear/set bits dependent on bit 55 of
> > > > the pointer.
> > > > 
> > > > These days, all supported toolchains have assemblers which are aware of
> > > > the XPACI and XPACLRI instructions, and contemporary compilers use
> > > > XPACLRI to strip the PAC in __builtin_return_address().
> > > 
> > > I'm struggling slightly with the reasoning here... presumably there are
> > > _still_ assemblers out there which don't support XPACLRI, so what happens
> > > if somebody tries to build the kernel with one? Is your argument that
> > > the compiler itself is going to generate XPACLRI in the builtin so we're
> > > no worse rolling it ourselves?
> > 
> > Basically, yes. We only generate these instructions when in-kernel
> > authentication is enabled, at which point the compiler will generate these
> > instructions.
> > 
> > It's expected that GCC is shipped with a suitably up-to-date binutils, and all
> > supported versions for LLVM (11.0.0+) support the instructions in the
> > integrated assembler.
> 
> Is that expectation enforced by e.g. the gcc build system? We'd had plenty
> of cases in the past where people mix and match binutils and the compiler,
> so I'm not sure why this case is different.

AFAIK it is not enforced.

Practically speaking, if someone mixes that up, defconfig (or any config with
CONFIG_ARM64_PTR_AUTH_KERNEL=y) would already be failing to build, and so I
suspect this is unlikely.

Admittedly it is possible that someone is building CONFIG_ARM64_PTR_AUTH=y &&
CONFIG_ARM64_PTR_AUTH_KERNEL=n with such a combination, and that would happen
to work today.

> > > If so, it still feels like a step backwards from where we are today (i.e.
> > > we don't require the assembler support) and failing the build due to a
> > > assembler error rather than a Kconfig version check and a helpful
> > > diagnostic is pretty horrible.
> > 
> > I don't think anyone's using such a mismatched binutils and GCC, but I could
> > use the hint encoding of XPACLRI directly (which all older assemblers support
> > regardless), if you prefer?
> 
> That would work, or add an 'as-instr' check to make the dependency explicit
> in a new AS_HAS_XPACLRI Kconfig option.

It's a bit simpler to use the hint encoding ("hint #7") directly, and that
won't regress the CONFIG_ARM64_PTR_AUTH=y && CONFIG_ARM64_PTR_AUTH_KERNEL=n
case, with such a toolchain, so I'll do that for v2.

Thanks,
Mark.



More information about the linux-arm-kernel mailing list