lkml.org 
[lkml]   [2020]   [Oct]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRe: [PATCH RFC v2 13/21] arm64: kasan: Add cpu_supports_tags helper
    On Thu, Oct 22, 2020 at 3:19 PM Andrey Konovalov <andreyknvl@google.com> wrote:
    >
    > Add an arm64 helper called cpu_supports_mte() that exposes information
    > about whether the CPU supports memory tagging and that can be called
    > during early boot (unlike system_supports_mte()).
    >
    > Use that helper to implement a generic cpu_supports_tags() helper, that
    > will be used by hardware tag-based KASAN.
    >
    > Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
    > Link: https://linux-review.googlesource.com/id/Ib4b56a42c57c6293df29a0cdfee334c3ca7bdab4

    Reviewed-by: Dmitry Vyukov <dvyukov@google.com>

    > ---
    > arch/arm64/include/asm/memory.h | 1 +
    > arch/arm64/include/asm/mte-kasan.h | 6 ++++++
    > arch/arm64/kernel/mte.c | 20 ++++++++++++++++++++
    > mm/kasan/kasan.h | 4 ++++
    > 4 files changed, 31 insertions(+)
    >
    > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
    > index b5d6b824c21c..f496abfcf7f5 100644
    > --- a/arch/arm64/include/asm/memory.h
    > +++ b/arch/arm64/include/asm/memory.h
    > @@ -232,6 +232,7 @@ static inline const void *__tag_set(const void *addr, u8 tag)
    > }
    >
    > #ifdef CONFIG_KASAN_HW_TAGS
    > +#define arch_cpu_supports_tags() cpu_supports_mte()
    > #define arch_init_tags(max_tag) mte_init_tags(max_tag)
    > #define arch_get_random_tag() mte_get_random_tag()
    > #define arch_get_mem_tag(addr) mte_get_mem_tag(addr)
    > diff --git a/arch/arm64/include/asm/mte-kasan.h b/arch/arm64/include/asm/mte-kasan.h
    > index a4c61b926d4a..4c3f2c6b4fe6 100644
    > --- a/arch/arm64/include/asm/mte-kasan.h
    > +++ b/arch/arm64/include/asm/mte-kasan.h
    > @@ -9,6 +9,7 @@
    >
    > #ifndef __ASSEMBLY__
    >
    > +#include <linux/init.h>
    > #include <linux/types.h>
    >
    > /*
    > @@ -30,6 +31,7 @@ u8 mte_get_random_tag(void);
    > void *mte_set_mem_tag_range(void *addr, size_t size, u8 tag);
    >
    > void mte_init_tags(u64 max_tag);
    > +bool __init cpu_supports_mte(void);
    >
    > #else /* CONFIG_ARM64_MTE */
    >
    > @@ -54,6 +56,10 @@ static inline void *mte_set_mem_tag_range(void *addr, size_t size, u8 tag)
    > static inline void mte_init_tags(u64 max_tag)
    > {
    > }
    > +static inline bool cpu_supports_mte(void)
    > +{
    > + return false;
    > +}
    >
    > #endif /* CONFIG_ARM64_MTE */
    >
    > diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
    > index ca8206b7f9a6..8fcd17408515 100644
    > --- a/arch/arm64/kernel/mte.c
    > +++ b/arch/arm64/kernel/mte.c
    > @@ -134,6 +134,26 @@ void mte_init_tags(u64 max_tag)
    > gcr_kernel_excl = ~incl & SYS_GCR_EL1_EXCL_MASK;
    > }
    >
    > +/*
    > + * This function can be used during early boot to determine whether the CPU
    > + * supports MTE. The alternative that must be used after boot is completed is
    > + * system_supports_mte(), but it only works after the cpufeature framework
    > + * learns about MTE.
    > + */
    > +bool __init cpu_supports_mte(void)
    > +{
    > + u64 pfr1;
    > + u32 val;
    > +
    > + if (!IS_ENABLED(CONFIG_ARM64_MTE))
    > + return false;
    > +
    > + pfr1 = read_cpuid(ID_AA64PFR1_EL1);
    > + val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_MTE_SHIFT);
    > +
    > + return val >= ID_AA64PFR1_MTE;
    > +}
    > +
    > static void update_sctlr_el1_tcf0(u64 tcf0)
    > {
    > /* ISB required for the kernel uaccess routines */
    > diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
    > index da08b2533d73..f7ae0c23f023 100644
    > --- a/mm/kasan/kasan.h
    > +++ b/mm/kasan/kasan.h
    > @@ -240,6 +240,9 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
    > #define set_tag(addr, tag) ((void *)arch_kasan_set_tag((addr), (tag)))
    > #define get_tag(addr) arch_kasan_get_tag(addr)
    >
    > +#ifndef arch_cpu_supports_tags
    > +#define arch_cpu_supports_tags() (false)
    > +#endif
    > #ifndef arch_init_tags
    > #define arch_init_tags(max_tag)
    > #endif
    > @@ -253,6 +256,7 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
    > #define arch_set_mem_tag_range(addr, size, tag) ((void *)(addr))
    > #endif
    >
    > +#define cpu_supports_tags() arch_cpu_supports_tags()
    > #define init_tags(max_tag) arch_init_tags(max_tag)
    > #define get_random_tag() arch_get_random_tag()
    > #define get_mem_tag(addr) arch_get_mem_tag(addr)
    > --
    > 2.29.0.rc1.297.gfa9743e501-goog
    >

    \
     
     \ /
      Last update: 2020-10-29 01:33    [W:4.093 / U:0.204 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site