Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

arm64: kasan: simplify and inline MTE functions

This change provides a simpler implementation of mte_get_mem_tag(),
mte_get_random_tag(), and mte_set_mem_tag_range().

Simplifications include removing system_supports_mte() checks as these
functions are onlye called from KASAN runtime that had already checked
system_supports_mte(). Besides that, size and address alignment checks
are removed from mte_set_mem_tag_range(), as KASAN now does those.

This change also moves these functions into the asm/mte-kasan.h header and
implements mte_set_mem_tag_range() via inline assembly to avoid
unnecessary functions calls.

[vincenzo.frascino@arm.com: fix warning in mte_get_random_tag()]
Link: https://lkml.kernel.org/r/20210211152208.23811-1-vincenzo.frascino@arm.com

Link: https://lkml.kernel.org/r/a26121b294fdf76e369cb7a74351d1c03a908930.1612546384.git.andreyknvl@google.com
Co-developed-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Branislav Rankov <Branislav.Rankov@arm.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Evgenii Stepanov <eugenis@google.com>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Cc: Marco Elver <elver@google.com>
Cc: Peter Collingbourne <pcc@google.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Andrey Konovalov and committed by
Linus Torvalds
2cb34276 cde8a7eb

+61 -74
-1
arch/arm64/include/asm/cache.h
··· 6 6 #define __ASM_CACHE_H 7 7 8 8 #include <asm/cputype.h> 9 - #include <asm/mte-kasan.h> 10 9 11 10 #define CTR_L1IP_SHIFT 14 12 11 #define CTR_L1IP_MASK 3
+1
arch/arm64/include/asm/kasan.h
··· 6 6 7 7 #include <linux/linkage.h> 8 8 #include <asm/memory.h> 9 + #include <asm/mte-kasan.h> 9 10 #include <asm/pgtable-types.h> 10 11 11 12 #define arch_kasan_set_tag(addr, tag) __tag_set(addr, tag)
+2
arch/arm64/include/asm/mte-def.h
··· 11 11 #define MTE_TAG_SIZE 4 12 12 #define MTE_TAG_MASK GENMASK((MTE_TAG_SHIFT + (MTE_TAG_SIZE - 1)), MTE_TAG_SHIFT) 13 13 14 + #define __MTE_PREAMBLE ARM64_ASM_PREAMBLE ".arch_extension memtag\n" 15 + 14 16 #endif /* __ASM_MTE_DEF_H */
+58 -9
arch/arm64/include/asm/mte-kasan.h
··· 11 11 12 12 #include <linux/types.h> 13 13 14 - /* 15 - * The functions below are meant to be used only for the 16 - * KASAN_HW_TAGS interface defined in asm/memory.h. 17 - */ 18 14 #ifdef CONFIG_ARM64_MTE 15 + 16 + /* 17 + * These functions are meant to be only used from KASAN runtime through 18 + * the arch_*() interface defined in asm/memory.h. 19 + * These functions don't include system_supports_mte() checks, 20 + * as KASAN only calls them when MTE is supported and enabled. 21 + */ 19 22 20 23 static inline u8 mte_get_ptr_tag(void *ptr) 21 24 { ··· 28 25 return tag; 29 26 } 30 27 31 - u8 mte_get_mem_tag(void *addr); 32 - u8 mte_get_random_tag(void); 33 - void *mte_set_mem_tag_range(void *addr, size_t size, u8 tag); 28 + /* Get allocation tag for the address. */ 29 + static inline u8 mte_get_mem_tag(void *addr) 30 + { 31 + asm(__MTE_PREAMBLE "ldg %0, [%0]" 32 + : "+r" (addr)); 33 + 34 + return mte_get_ptr_tag(addr); 35 + } 36 + 37 + /* Generate a random tag. */ 38 + static inline u8 mte_get_random_tag(void) 39 + { 40 + void *addr; 41 + 42 + asm(__MTE_PREAMBLE "irg %0, %0" 43 + : "=r" (addr)); 44 + 45 + return mte_get_ptr_tag(addr); 46 + } 47 + 48 + /* 49 + * Assign allocation tags for a region of memory based on the pointer tag. 50 + * Note: The address must be non-NULL and MTE_GRANULE_SIZE aligned and 51 + * size must be non-zero and MTE_GRANULE_SIZE aligned. 52 + */ 53 + static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag) 54 + { 55 + u64 curr, end; 56 + 57 + if (!size) 58 + return; 59 + 60 + curr = (u64)__tag_set(addr, tag); 61 + end = curr + size; 62 + 63 + do { 64 + /* 65 + * 'asm volatile' is required to prevent the compiler to move 66 + * the statement outside of the loop. 67 + */ 68 + asm volatile(__MTE_PREAMBLE "stg %0, [%0]" 69 + : 70 + : "r" (curr) 71 + : "memory"); 72 + 73 + curr += MTE_GRANULE_SIZE; 74 + } while (curr != end); 75 + } 34 76 35 77 void mte_enable_kernel(void); 36 78 void mte_init_tags(u64 max_tag); ··· 94 46 { 95 47 return 0xFF; 96 48 } 49 + 97 50 static inline u8 mte_get_random_tag(void) 98 51 { 99 52 return 0xFF; 100 53 } 101 - static inline void *mte_set_mem_tag_range(void *addr, size_t size, u8 tag) 54 + 55 + static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag) 102 56 { 103 - return addr; 104 57 } 105 58 106 59 static inline void mte_enable_kernel(void)
-2
arch/arm64/include/asm/mte.h
··· 8 8 #include <asm/compiler.h> 9 9 #include <asm/mte-def.h> 10 10 11 - #define __MTE_PREAMBLE ARM64_ASM_PREAMBLE ".arch_extension memtag\n" 12 - 13 11 #ifndef __ASSEMBLY__ 14 12 15 13 #include <linux/bitfield.h>
-46
arch/arm64/kernel/mte.c
··· 19 19 #include <asm/barrier.h> 20 20 #include <asm/cpufeature.h> 21 21 #include <asm/mte.h> 22 - #include <asm/mte-kasan.h> 23 22 #include <asm/ptrace.h> 24 23 #include <asm/sysreg.h> 25 24 ··· 85 86 return addr1 != addr2; 86 87 87 88 return ret; 88 - } 89 - 90 - u8 mte_get_mem_tag(void *addr) 91 - { 92 - if (!system_supports_mte()) 93 - return 0xFF; 94 - 95 - asm(__MTE_PREAMBLE "ldg %0, [%0]" 96 - : "+r" (addr)); 97 - 98 - return mte_get_ptr_tag(addr); 99 - } 100 - 101 - u8 mte_get_random_tag(void) 102 - { 103 - void *addr; 104 - 105 - if (!system_supports_mte()) 106 - return 0xFF; 107 - 108 - asm(__MTE_PREAMBLE "irg %0, %0" 109 - : "+r" (addr)); 110 - 111 - return mte_get_ptr_tag(addr); 112 - } 113 - 114 - void *mte_set_mem_tag_range(void *addr, size_t size, u8 tag) 115 - { 116 - void *ptr = addr; 117 - 118 - if ((!system_supports_mte()) || (size == 0)) 119 - return addr; 120 - 121 - /* Make sure that size is MTE granule aligned. */ 122 - WARN_ON(size & (MTE_GRANULE_SIZE - 1)); 123 - 124 - /* Make sure that the address is MTE granule aligned. */ 125 - WARN_ON((u64)addr & (MTE_GRANULE_SIZE - 1)); 126 - 127 - tag = 0xF0 | tag; 128 - ptr = (void *)__tag_set(ptr, tag); 129 - 130 - mte_assign_mem_tag_range(ptr, size); 131 - 132 - return ptr; 133 89 } 134 90 135 91 void mte_init_tags(u64 max_tag)
-16
arch/arm64/lib/mte.S
··· 149 149 150 150 ret 151 151 SYM_FUNC_END(mte_restore_page_tags) 152 - 153 - /* 154 - * Assign allocation tags for a region of memory based on the pointer tag 155 - * x0 - source pointer 156 - * x1 - size 157 - * 158 - * Note: The address must be non-NULL and MTE_GRANULE_SIZE aligned and 159 - * size must be non-zero and MTE_GRANULE_SIZE aligned. 160 - */ 161 - SYM_FUNC_START(mte_assign_mem_tag_range) 162 - 1: stg x0, [x0] 163 - add x0, x0, #MTE_GRANULE_SIZE 164 - subs x1, x1, #MTE_GRANULE_SIZE 165 - b.gt 1b 166 - ret 167 - SYM_FUNC_END(mte_assign_mem_tag_range)