diff mbox series

[2/2] arm64: Configure kernel's PTR_AUTH key when it is built with PTR_AUTH.

Message ID 20201207224625.13764-3-daniel.kiss@arm.com (mailing list archive)
State New, archived
Headers show
Series [1/2] arm64: Add ARM64_PTR_AUTH_KERNEL config option | expand

Commit Message

Daniel Kiss Dec. 7, 2020, 10:46 p.m. UTC
If the kernel is not compiled with CONFIG_ARM64_PTR_AUTH_KERNEL,
then the kernel does not need a key and kernel's key could be disabled.

Signed-off-by: Daniel Kiss <daniel.kiss@arm.com>
---
 arch/arm64/include/asm/asm_pointer_auth.h | 68 ++++++++++++++++-------
 arch/arm64/include/asm/processor.h        |  2 +
 arch/arm64/kernel/asm-offsets.c           |  4 ++
 3 files changed, 55 insertions(+), 19 deletions(-)

Comments

Peter Collingbourne Dec. 7, 2020, 11:07 p.m. UTC | #1
On Mon, Dec 7, 2020 at 2:46 PM Daniel Kiss <daniel.kiss@arm.com> wrote:
>
> If the kernel is not compiled with CONFIG_ARM64_PTR_AUTH_KERNEL,
> then the kernel does not need a key and kernel's key could be disabled.
>
> Signed-off-by: Daniel Kiss <daniel.kiss@arm.com>
> ---
>  arch/arm64/include/asm/asm_pointer_auth.h | 68 ++++++++++++++++-------
>  arch/arm64/include/asm/processor.h        |  2 +
>  arch/arm64/kernel/asm-offsets.c           |  4 ++
>  3 files changed, 55 insertions(+), 19 deletions(-)
>
> diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
> index 52dead2a8640..af3d16027e8f 100644
> --- a/arch/arm64/include/asm/asm_pointer_auth.h
> +++ b/arch/arm64/include/asm/asm_pointer_auth.h
> @@ -14,6 +14,12 @@
>   * thread.keys_user.ap*.
>   */
>         .macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
> +#ifndef CONFIG_ARM64_PTR_AUTH_KERNEL
> +       /* Reenable A key */
> +       mrs     \tmp1, sctlr_el1
> +       orr     \tmp1, \tmp1, SCTLR_ELx_ENIA
> +       msr     sctlr_el1, \tmp1
> +#endif

We should avoid an unconditional MSR on exit like this as it is
expensive (for my PR_PAC_SET_ENABLED_KEYS series I measured the cost
of entry/exit MSR as 43.7ns on Cortex-A75 and 33.0ns on Apple M1). In
that series I take care not to touch SCTLR_EL1 unless necessary.
Likewise for the MSRs on entry below.

>         mov     \tmp1, #THREAD_KEYS_USER
>         add     \tmp1, \tsk, \tmp1
>  alternative_if_not ARM64_HAS_ADDRESS_AUTH
> @@ -39,6 +45,36 @@ alternative_if ARM64_HAS_GENERIC_AUTH
>  alternative_else_nop_endif
>         .endm
>
> +       .macro __ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
> +       mrs     \tmp1, id_aa64isar1_el1
> +       ubfx    \tmp1, \tmp1, #ID_AA64ISAR1_APA_SHIFT, #8
> +       cbz     \tmp1, .Lno_addr_auth\@
> +#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
> +       mov_q   \tmp1, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
> +                       SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
> +#else
> +       mov_q   \tmp1, (SCTLR_ELx_ENIB | \
> +                       SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
> +#endif

If you leave IA enabled here then you shouldn't need to MSR on entry
and exit. If no PAC instructions are used in the kernel then it
shouldn't matter if it is left enabled.

Peter

> +       mrs     \tmp2, sctlr_el1
> +       orr     \tmp2, \tmp2, \tmp1
> +       msr     sctlr_el1, \tmp2
> +#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
> +       __ptrauth_keys_install_kernel_nosync \tsk, \tmp1, \tmp2, \tmp3
> +#endif
> +       isb
> +.Lno_addr_auth\@:
> +       .endm
> +
> +       .macro ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
> +alternative_if_not ARM64_HAS_ADDRESS_AUTH
> +       b       .Lno_addr_auth\@
> +alternative_else_nop_endif
> +       __ptrauth_keys_init_cpu \tsk, \tmp1, \tmp2, \tmp3
> +.Lno_addr_auth\@:
> +       .endm
> +
> +#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
>         .macro __ptrauth_keys_install_kernel_nosync tsk, tmp1, tmp2, tmp3
>         mov     \tmp1, #THREAD_KEYS_KERNEL
>         add     \tmp1, \tsk, \tmp1
> @@ -60,29 +96,23 @@ alternative_if ARM64_HAS_ADDRESS_AUTH
>  alternative_else_nop_endif
>         .endm
>
> -       .macro __ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
> -       mrs     \tmp1, id_aa64isar1_el1
> -       ubfx    \tmp1, \tmp1, #ID_AA64ISAR1_APA_SHIFT, #8
> -       cbz     \tmp1, .Lno_addr_auth\@
> -       mov_q   \tmp1, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
> -                       SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
> -       mrs     \tmp2, sctlr_el1
> -       orr     \tmp2, \tmp2, \tmp1
> -       msr     sctlr_el1, \tmp2
> -       __ptrauth_keys_install_kernel_nosync \tsk, \tmp1, \tmp2, \tmp3
> -       isb
> -.Lno_addr_auth\@:
> +#else /* CONFIG_ARM64_PTR_AUTH_KERNEL */
> +
> +       .macro ptrauth_keys_install_kernel_nosync tsk, tmp1, tmp2, tmp3
> +       mrs     \tmp1, sctlr_el1
> +       and     \tmp1, \tmp1, ~SCTLR_ELx_ENIA
> +       msr     sctlr_el1, \tmp1
>         .endm
>
> -       .macro ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
> -alternative_if_not ARM64_HAS_ADDRESS_AUTH
> -       b       .Lno_addr_auth\@
> -alternative_else_nop_endif
> -       __ptrauth_keys_init_cpu \tsk, \tmp1, \tmp2, \tmp3
> -.Lno_addr_auth\@:
> +       .macro ptrauth_keys_install_kernel tsk, tmp1, tmp2, tmp3
> +       mrs     \tmp1, sctlr_el1
> +       and     \tmp1, \tmp1, ~SCTLR_ELx_ENIA
> +       msr     sctlr_el1, \tmp1
>         .endm
>
> -#else /* CONFIG_ARM64_PTR_AUTH */
> +#endif /* CONFIG_ARM64_PTR_AUTH_KERNEL */
> +
> +#else /* !CONFIG_ARM64_PTR_AUTH */
>
>         .macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
>         .endm
> diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> index fce8cbecd6bc..e20888b321e3 100644
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -150,8 +150,10 @@ struct thread_struct {
>         struct debug_info       debug;          /* debugging */
>  #ifdef CONFIG_ARM64_PTR_AUTH
>         struct ptrauth_keys_user        keys_user;
> +#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
>         struct ptrauth_keys_kernel      keys_kernel;
>  #endif
> +#endif
>  #ifdef CONFIG_ARM64_MTE
>         u64                     sctlr_tcf0;
>         u64                     gcr_user_incl;
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index 7d32fc959b1a..cb7965a9f505 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -46,7 +46,9 @@ int main(void)
>    DEFINE(THREAD_CPU_CONTEXT,   offsetof(struct task_struct, thread.cpu_context));
>  #ifdef CONFIG_ARM64_PTR_AUTH
>    DEFINE(THREAD_KEYS_USER,     offsetof(struct task_struct, thread.keys_user));
> +#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
>    DEFINE(THREAD_KEYS_KERNEL,   offsetof(struct task_struct, thread.keys_kernel));
> +#endif
>  #endif
>    BLANK();
>    DEFINE(S_X0,                 offsetof(struct pt_regs, regs[0]));
> @@ -141,7 +143,9 @@ int main(void)
>    DEFINE(PTRAUTH_USER_KEY_APDA,                offsetof(struct ptrauth_keys_user, apda));
>    DEFINE(PTRAUTH_USER_KEY_APDB,                offsetof(struct ptrauth_keys_user, apdb));
>    DEFINE(PTRAUTH_USER_KEY_APGA,                offsetof(struct ptrauth_keys_user, apga));
> +#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
>    DEFINE(PTRAUTH_KERNEL_KEY_APIA,      offsetof(struct ptrauth_keys_kernel, apia));
> +#endif
>    BLANK();
>  #endif
>    return 0;
> --
> 2.17.1
>
Catalin Marinas Dec. 8, 2020, 11 a.m. UTC | #2
On Mon, Dec 07, 2020 at 03:07:07PM -0800, Peter Collingbourne wrote:
> On Mon, Dec 7, 2020 at 2:46 PM Daniel Kiss <daniel.kiss@arm.com> wrote:
> > If the kernel is not compiled with CONFIG_ARM64_PTR_AUTH_KERNEL,
> > then the kernel does not need a key and kernel's key could be disabled.
> >
> > Signed-off-by: Daniel Kiss <daniel.kiss@arm.com>
> > ---
> >  arch/arm64/include/asm/asm_pointer_auth.h | 68 ++++++++++++++++-------
> >  arch/arm64/include/asm/processor.h        |  2 +
> >  arch/arm64/kernel/asm-offsets.c           |  4 ++
> >  3 files changed, 55 insertions(+), 19 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
> > index 52dead2a8640..af3d16027e8f 100644
> > --- a/arch/arm64/include/asm/asm_pointer_auth.h
> > +++ b/arch/arm64/include/asm/asm_pointer_auth.h
> > @@ -14,6 +14,12 @@
> >   * thread.keys_user.ap*.
> >   */
> >         .macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
> > +#ifndef CONFIG_ARM64_PTR_AUTH_KERNEL
> > +       /* Reenable A key */
> > +       mrs     \tmp1, sctlr_el1
> > +       orr     \tmp1, \tmp1, SCTLR_ELx_ENIA
> > +       msr     sctlr_el1, \tmp1
> > +#endif
> 
> We should avoid an unconditional MSR on exit like this as it is
> expensive (for my PR_PAC_SET_ENABLED_KEYS series I measured the cost
> of entry/exit MSR as 43.7ns on Cortex-A75 and 33.0ns on Apple M1). In
> that series I take care not to touch SCTLR_EL1 unless necessary.
> Likewise for the MSRs on entry below.

I think that's how Daniel attempted the first (internal) version of
these patches. In theory you don't need to touch SCTLR_ELx_EN* at all as
long as the kernel does not use any PAC instructions. However, I was
a bit concerned about this and thought it's safer if, when
!CONFIG_ARM64_PTR_AUTH_KERNEL, the EnIA bit is cleared while in the
kernel.

If we can guarantee that the compiler does not generate any PAC
instructions (it may assume they are no-ops) and vendor modules don't
have such instructions either, we may be able to relax this.
Peter Collingbourne Dec. 8, 2020, 7:33 p.m. UTC | #3
On Tue, Dec 8, 2020 at 3:00 AM Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> On Mon, Dec 07, 2020 at 03:07:07PM -0800, Peter Collingbourne wrote:
> > On Mon, Dec 7, 2020 at 2:46 PM Daniel Kiss <daniel.kiss@arm.com> wrote:
> > > If the kernel is not compiled with CONFIG_ARM64_PTR_AUTH_KERNEL,
> > > then the kernel does not need a key and kernel's key could be disabled.
> > >
> > > Signed-off-by: Daniel Kiss <daniel.kiss@arm.com>
> > > ---
> > >  arch/arm64/include/asm/asm_pointer_auth.h | 68 ++++++++++++++++-------
> > >  arch/arm64/include/asm/processor.h        |  2 +
> > >  arch/arm64/kernel/asm-offsets.c           |  4 ++
> > >  3 files changed, 55 insertions(+), 19 deletions(-)
> > >
> > > diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
> > > index 52dead2a8640..af3d16027e8f 100644
> > > --- a/arch/arm64/include/asm/asm_pointer_auth.h
> > > +++ b/arch/arm64/include/asm/asm_pointer_auth.h
> > > @@ -14,6 +14,12 @@
> > >   * thread.keys_user.ap*.
> > >   */
> > >         .macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
> > > +#ifndef CONFIG_ARM64_PTR_AUTH_KERNEL
> > > +       /* Reenable A key */
> > > +       mrs     \tmp1, sctlr_el1
> > > +       orr     \tmp1, \tmp1, SCTLR_ELx_ENIA
> > > +       msr     sctlr_el1, \tmp1
> > > +#endif
> >
> > We should avoid an unconditional MSR on exit like this as it is
> > expensive (for my PR_PAC_SET_ENABLED_KEYS series I measured the cost
> > of entry/exit MSR as 43.7ns on Cortex-A75 and 33.0ns on Apple M1). In
> > that series I take care not to touch SCTLR_EL1 unless necessary.
> > Likewise for the MSRs on entry below.
>
> I think that's how Daniel attempted the first (internal) version of
> these patches. In theory you don't need to touch SCTLR_ELx_EN* at all as
> long as the kernel does not use any PAC instructions. However, I was
> a bit concerned about this and thought it's safer if, when
> !CONFIG_ARM64_PTR_AUTH_KERNEL, the EnIA bit is cleared while in the
> kernel.
>
> If we can guarantee that the compiler does not generate any PAC
> instructions (it may assume they are no-ops) and vendor modules don't
> have such instructions either, we may be able to relax this.

The way I see it it isn't too different from the current prohibition
on using IB in the kernel (and to a lesser extent DA/DB/GA since those
can't be accessed from nop-space as far as I'm aware), or NEON
instructions in most parts of the kernel, or the stack protector
cookie when building with -fno-stack-protector etc. i.e. if you do
that then you're breaking the ABI.

Is your concern that distributions may default to enabling
-mbranch-protection which would result in the PAC instructions being
used? To address that I think it is reasonable to expect the compiler
not to use PAC instructions when passing -mbranch-protection=none, and
if the compiler does so then that is a bug in the compiler.

Peter
Will Deacon Dec. 9, 2020, 10:51 a.m. UTC | #4
On Tue, Dec 08, 2020 at 11:33:33AM -0800, Peter Collingbourne wrote:
> On Tue, Dec 8, 2020 at 3:00 AM Catalin Marinas <catalin.marinas@arm.com> wrote:
> >
> > On Mon, Dec 07, 2020 at 03:07:07PM -0800, Peter Collingbourne wrote:
> > > On Mon, Dec 7, 2020 at 2:46 PM Daniel Kiss <daniel.kiss@arm.com> wrote:
> > > > If the kernel is not compiled with CONFIG_ARM64_PTR_AUTH_KERNEL,
> > > > then the kernel does not need a key and kernel's key could be disabled.
> > > >
> > > > Signed-off-by: Daniel Kiss <daniel.kiss@arm.com>
> > > > ---
> > > >  arch/arm64/include/asm/asm_pointer_auth.h | 68 ++++++++++++++++-------
> > > >  arch/arm64/include/asm/processor.h        |  2 +
> > > >  arch/arm64/kernel/asm-offsets.c           |  4 ++
> > > >  3 files changed, 55 insertions(+), 19 deletions(-)
> > > >
> > > > diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
> > > > index 52dead2a8640..af3d16027e8f 100644
> > > > --- a/arch/arm64/include/asm/asm_pointer_auth.h
> > > > +++ b/arch/arm64/include/asm/asm_pointer_auth.h
> > > > @@ -14,6 +14,12 @@
> > > >   * thread.keys_user.ap*.
> > > >   */
> > > >         .macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
> > > > +#ifndef CONFIG_ARM64_PTR_AUTH_KERNEL
> > > > +       /* Reenable A key */
> > > > +       mrs     \tmp1, sctlr_el1
> > > > +       orr     \tmp1, \tmp1, SCTLR_ELx_ENIA
> > > > +       msr     sctlr_el1, \tmp1
> > > > +#endif
> > >
> > > We should avoid an unconditional MSR on exit like this as it is
> > > expensive (for my PR_PAC_SET_ENABLED_KEYS series I measured the cost
> > > of entry/exit MSR as 43.7ns on Cortex-A75 and 33.0ns on Apple M1). In
> > > that series I take care not to touch SCTLR_EL1 unless necessary.
> > > Likewise for the MSRs on entry below.
> >
> > I think that's how Daniel attempted the first (internal) version of
> > these patches. In theory you don't need to touch SCTLR_ELx_EN* at all as
> > long as the kernel does not use any PAC instructions. However, I was
> > a bit concerned about this and thought it's safer if, when
> > !CONFIG_ARM64_PTR_AUTH_KERNEL, the EnIA bit is cleared while in the
> > kernel.
> >
> > If we can guarantee that the compiler does not generate any PAC
> > instructions (it may assume they are no-ops) and vendor modules don't
> > have such instructions either, we may be able to relax this.
> 
> The way I see it it isn't too different from the current prohibition
> on using IB in the kernel (and to a lesser extent DA/DB/GA since those
> can't be accessed from nop-space as far as I'm aware), or NEON
> instructions in most parts of the kernel, or the stack protector
> cookie when building with -fno-stack-protector etc. i.e. if you do
> that then you're breaking the ABI.
> 
> Is your concern that distributions may default to enabling
> -mbranch-protection which would result in the PAC instructions being
> used? To address that I think it is reasonable to expect the compiler
> not to use PAC instructions when passing -mbranch-protection=none, and
> if the compiler does so then that is a bug in the compiler.

I'm inclined to agree. At the very least, I think we should start from a
position where we assume the compiler doesn't randomly emit these
instructions, and then we can revisit that decision in future if it turns
out to be wrong.

Will
Daniel Kiss Dec. 9, 2020, 11:56 a.m. UTC | #5
> On 9 Dec 2020, at 11:51, Will Deacon <will@kernel.org> wrote:
> 
> On Tue, Dec 08, 2020 at 11:33:33AM -0800, Peter Collingbourne wrote:
>> On Tue, Dec 8, 2020 at 3:00 AM Catalin Marinas <catalin.marinas@arm.com> wrote:
>>> 
>>> On Mon, Dec 07, 2020 at 03:07:07PM -0800, Peter Collingbourne wrote:
>>>> On Mon, Dec 7, 2020 at 2:46 PM Daniel Kiss <daniel.kiss@arm.com> wrote:
>>>>> If the kernel is not compiled with CONFIG_ARM64_PTR_AUTH_KERNEL,
>>>>> then the kernel does not need a key and kernel's key could be disabled.
>>>>> 
>>>>> Signed-off-by: Daniel Kiss <daniel.kiss@arm.com>
>>>>> ---
>>>>> arch/arm64/include/asm/asm_pointer_auth.h | 68 ++++++++++++++++-------
>>>>> arch/arm64/include/asm/processor.h        |  2 +
>>>>> arch/arm64/kernel/asm-offsets.c           |  4 ++
>>>>> 3 files changed, 55 insertions(+), 19 deletions(-)
>>>>> 
>>>>> diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
>>>>> index 52dead2a8640..af3d16027e8f 100644
>>>>> --- a/arch/arm64/include/asm/asm_pointer_auth.h
>>>>> +++ b/arch/arm64/include/asm/asm_pointer_auth.h
>>>>> @@ -14,6 +14,12 @@
>>>>>  * thread.keys_user.ap*.
>>>>>  */
>>>>>        .macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
>>>>> +#ifndef CONFIG_ARM64_PTR_AUTH_KERNEL
>>>>> +       /* Reenable A key */
>>>>> +       mrs     \tmp1, sctlr_el1
>>>>> +       orr     \tmp1, \tmp1, SCTLR_ELx_ENIA
>>>>> +       msr     sctlr_el1, \tmp1
>>>>> +#endif
>>>> 
>>>> We should avoid an unconditional MSR on exit like this as it is
>>>> expensive (for my PR_PAC_SET_ENABLED_KEYS series I measured the cost
>>>> of entry/exit MSR as 43.7ns on Cortex-A75 and 33.0ns on Apple M1). In
>>>> that series I take care not to touch SCTLR_EL1 unless necessary.
>>>> Likewise for the MSRs on entry below.
>>> 
>>> I think that's how Daniel attempted the first (internal) version of
>>> these patches. In theory you don't need to touch SCTLR_ELx_EN* at all as
>>> long as the kernel does not use any PAC instructions. However, I was
>>> a bit concerned about this and thought it's safer if, when
>>> !CONFIG_ARM64_PTR_AUTH_KERNEL, the EnIA bit is cleared while in the
>>> kernel.
>>> 
>>> If we can guarantee that the compiler does not generate any PAC
>>> instructions (it may assume they are no-ops) and vendor modules don't
>>> have such instructions either, we may be able to relax this.
>> 
>> The way I see it it isn't too different from the current prohibition
>> on using IB in the kernel (and to a lesser extent DA/DB/GA since those
>> can't be accessed from nop-space as far as I'm aware), or NEON
>> instructions in most parts of the kernel, or the stack protector
>> cookie when building with -fno-stack-protector etc. i.e. if you do
>> that then you're breaking the ABI.
>> 
>> Is your concern that distributions may default to enabling
>> -mbranch-protection which would result in the PAC instructions being
>> used? To address that I think it is reasonable to expect the compiler
>> not to use PAC instructions when passing -mbranch-protection=none, and
>> if the compiler does so then that is a bug in the compiler.
> 
> I'm inclined to agree. At the very least, I think we should start from a
> position where we assume the compiler doesn't randomly emit these
> instructions, and then we can revisit that decision in future if it turns
> out to be wrong.
> 

I agree the compiler shall not emit these instructions when not requested.
I have two corner cases to consider:
Assembly code may contain pac/aut instructions unconditionally, like:
https://elixir.bootlin.com/linux/v5.10-rc7/source/arch/arm64/crypto/poly1305-armv8.pl#L348

A module may be compiled against a kernel with CONFIG_ARM64_PTR_AUTH_KERNEL=y
but later it is loaded on a kernel which is built with CONFIG_ARM64_PTR_AUTH_KERNEL=n.
If the key is not disabled here, the CONFIG_ARM64_PTR_AUTH_KERNEL is 
part of the KMI otherwise not.

Daniel
Daniel Kiss Dec. 18, 2020, 11:56 a.m. UTC | #6
As discussed the A-key left enabled, this makes the patch simpler too.
arch/arm64/crypto/poly1305-core.S_shipped contains PACISP/AUTISP
instructions but this code is called while the preeption is disabled,
therefore it won't cause any trouble.

v2:
- dropped the keychange/enablement for the kernel keys.
Will Deacon Jan. 26, 2021, 1:17 p.m. UTC | #7
On Fri, Dec 18, 2020 at 12:56:30PM +0100, Daniel Kiss wrote:
> As discussed the A-key left enabled, this makes the patch simpler too.
> arch/arm64/crypto/poly1305-core.S_shipped contains PACISP/AUTISP
> instructions but this code is called while the preeption is disabled,
> therefore it won't cause any trouble.

Please use the --cover-letter option to git format-patch for generating your
cover letter. It's also best to send new versions out as a new series,
rather than replying to the previous one.

Thanks,

Will
diff mbox series

Patch

diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
index 52dead2a8640..af3d16027e8f 100644
--- a/arch/arm64/include/asm/asm_pointer_auth.h
+++ b/arch/arm64/include/asm/asm_pointer_auth.h
@@ -14,6 +14,12 @@ 
  * thread.keys_user.ap*.
  */
 	.macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
+#ifndef CONFIG_ARM64_PTR_AUTH_KERNEL
+	/* Reenable A key */
+	mrs	\tmp1, sctlr_el1
+	orr	\tmp1, \tmp1, SCTLR_ELx_ENIA
+	msr	sctlr_el1, \tmp1
+#endif
 	mov	\tmp1, #THREAD_KEYS_USER
 	add	\tmp1, \tsk, \tmp1
 alternative_if_not ARM64_HAS_ADDRESS_AUTH
@@ -39,6 +45,36 @@  alternative_if ARM64_HAS_GENERIC_AUTH
 alternative_else_nop_endif
 	.endm
 
+	.macro __ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
+	mrs	\tmp1, id_aa64isar1_el1
+	ubfx	\tmp1, \tmp1, #ID_AA64ISAR1_APA_SHIFT, #8
+	cbz	\tmp1, .Lno_addr_auth\@
+#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
+	mov_q	\tmp1, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
+			SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
+#else
+	mov_q	\tmp1, (SCTLR_ELx_ENIB | \
+			SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
+#endif
+	mrs	\tmp2, sctlr_el1
+	orr	\tmp2, \tmp2, \tmp1
+	msr	sctlr_el1, \tmp2
+#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
+	__ptrauth_keys_install_kernel_nosync \tsk, \tmp1, \tmp2, \tmp3
+#endif
+	isb
+.Lno_addr_auth\@:
+	.endm
+
+	.macro ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
+alternative_if_not ARM64_HAS_ADDRESS_AUTH
+	b	.Lno_addr_auth\@
+alternative_else_nop_endif
+	__ptrauth_keys_init_cpu \tsk, \tmp1, \tmp2, \tmp3
+.Lno_addr_auth\@:
+	.endm
+
+#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
 	.macro __ptrauth_keys_install_kernel_nosync tsk, tmp1, tmp2, tmp3
 	mov	\tmp1, #THREAD_KEYS_KERNEL
 	add	\tmp1, \tsk, \tmp1
@@ -60,29 +96,23 @@  alternative_if ARM64_HAS_ADDRESS_AUTH
 alternative_else_nop_endif
 	.endm
 
-	.macro __ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
-	mrs	\tmp1, id_aa64isar1_el1
-	ubfx	\tmp1, \tmp1, #ID_AA64ISAR1_APA_SHIFT, #8
-	cbz	\tmp1, .Lno_addr_auth\@
-	mov_q	\tmp1, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
-			SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
-	mrs	\tmp2, sctlr_el1
-	orr	\tmp2, \tmp2, \tmp1
-	msr	sctlr_el1, \tmp2
-	__ptrauth_keys_install_kernel_nosync \tsk, \tmp1, \tmp2, \tmp3
-	isb
-.Lno_addr_auth\@:
+#else /* CONFIG_ARM64_PTR_AUTH_KERNEL */
+
+	.macro ptrauth_keys_install_kernel_nosync tsk, tmp1, tmp2, tmp3
+	mrs	\tmp1, sctlr_el1
+	and	\tmp1, \tmp1, ~SCTLR_ELx_ENIA
+	msr	sctlr_el1, \tmp1
 	.endm
 
-	.macro ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
-alternative_if_not ARM64_HAS_ADDRESS_AUTH
-	b	.Lno_addr_auth\@
-alternative_else_nop_endif
-	__ptrauth_keys_init_cpu \tsk, \tmp1, \tmp2, \tmp3
-.Lno_addr_auth\@:
+	.macro ptrauth_keys_install_kernel tsk, tmp1, tmp2, tmp3
+	mrs	\tmp1, sctlr_el1
+	and	\tmp1, \tmp1, ~SCTLR_ELx_ENIA
+	msr	sctlr_el1, \tmp1
 	.endm
 
-#else /* CONFIG_ARM64_PTR_AUTH */
+#endif /* CONFIG_ARM64_PTR_AUTH_KERNEL */
+
+#else /* !CONFIG_ARM64_PTR_AUTH */
 
 	.macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3
 	.endm
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index fce8cbecd6bc..e20888b321e3 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -150,8 +150,10 @@  struct thread_struct {
 	struct debug_info	debug;		/* debugging */
 #ifdef CONFIG_ARM64_PTR_AUTH
 	struct ptrauth_keys_user	keys_user;
+#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
 	struct ptrauth_keys_kernel	keys_kernel;
 #endif
+#endif
 #ifdef CONFIG_ARM64_MTE
 	u64			sctlr_tcf0;
 	u64			gcr_user_incl;
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 7d32fc959b1a..cb7965a9f505 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -46,7 +46,9 @@  int main(void)
   DEFINE(THREAD_CPU_CONTEXT,	offsetof(struct task_struct, thread.cpu_context));
 #ifdef CONFIG_ARM64_PTR_AUTH
   DEFINE(THREAD_KEYS_USER,	offsetof(struct task_struct, thread.keys_user));
+#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
   DEFINE(THREAD_KEYS_KERNEL,	offsetof(struct task_struct, thread.keys_kernel));
+#endif
 #endif
   BLANK();
   DEFINE(S_X0,			offsetof(struct pt_regs, regs[0]));
@@ -141,7 +143,9 @@  int main(void)
   DEFINE(PTRAUTH_USER_KEY_APDA,		offsetof(struct ptrauth_keys_user, apda));
   DEFINE(PTRAUTH_USER_KEY_APDB,		offsetof(struct ptrauth_keys_user, apdb));
   DEFINE(PTRAUTH_USER_KEY_APGA,		offsetof(struct ptrauth_keys_user, apga));
+#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
   DEFINE(PTRAUTH_KERNEL_KEY_APIA,	offsetof(struct ptrauth_keys_kernel, apia));
+#endif
   BLANK();
 #endif
   return 0;