Commit d9b6f907 authored by Andrey Konovalov's avatar Andrey Konovalov Committed by Linus Torvalds

arm64: kasan: allow to init memory when setting tags

Patch series "kasan: integrate with init_on_alloc/free", v3.

This patch series integrates HW_TAGS KASAN with init_on_alloc/free by
initializing memory via the same arm64 instruction that sets memory tags.

This is expected to improve HW_TAGS KASAN performance when
init_on_alloc/free is enabled.  The exact perfomance numbers are unknown
as MTE-enabled hardware doesn't exist yet.

This patch (of 5):

This change adds an argument to mte_set_mem_tag_range() that allows to
enable memory initialization when settinh the allocation tags.  The
implementation uses stzg instruction instead of stg when this argument
indicates to initialize memory.

Combining setting allocation tags with memory initialization will improve
HW_TAGS KASAN performance when init_on_alloc/free is enabled.

This change doesn't integrate memory initialization with KASAN, this is
done is subsequent patches in this series.

Link: https://lkml.kernel.org/r/cover.1615296150.git.andreyknvl@google.com
Link: https://lkml.kernel.org/r/d04ae90cc36be3fe246ea8025e5085495681c3d7.1615296150.git.andreyknvl@google.comSigned-off-by: default avatarAndrey Konovalov <andreyknvl@google.com>
Acked-by: default avatarMarco Elver <elver@google.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Peter Collingbourne <pcc@google.com>
Cc: Evgenii Stepanov <eugenis@google.com>
Cc: Branislav Rankov <Branislav.Rankov@arm.com>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2c335680
...@@ -250,8 +250,8 @@ static inline const void *__tag_set(const void *addr, u8 tag) ...@@ -250,8 +250,8 @@ static inline const void *__tag_set(const void *addr, u8 tag)
#define arch_init_tags(max_tag) mte_init_tags(max_tag) #define arch_init_tags(max_tag) mte_init_tags(max_tag)
#define arch_get_random_tag() mte_get_random_tag() #define arch_get_random_tag() mte_get_random_tag()
#define arch_get_mem_tag(addr) mte_get_mem_tag(addr) #define arch_get_mem_tag(addr) mte_get_mem_tag(addr)
#define arch_set_mem_tag_range(addr, size, tag) \ #define arch_set_mem_tag_range(addr, size, tag, init) \
mte_set_mem_tag_range((addr), (size), (tag)) mte_set_mem_tag_range((addr), (size), (tag), (init))
#endif /* CONFIG_KASAN_HW_TAGS */ #endif /* CONFIG_KASAN_HW_TAGS */
/* /*
......
...@@ -53,7 +53,8 @@ static inline u8 mte_get_random_tag(void) ...@@ -53,7 +53,8 @@ static inline u8 mte_get_random_tag(void)
* Note: The address must be non-NULL and MTE_GRANULE_SIZE aligned and * Note: The address must be non-NULL and MTE_GRANULE_SIZE aligned and
* size must be non-zero and MTE_GRANULE_SIZE aligned. * size must be non-zero and MTE_GRANULE_SIZE aligned.
*/ */
static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag) static inline void mte_set_mem_tag_range(void *addr, size_t size,
u8 tag, bool init)
{ {
u64 curr, end; u64 curr, end;
...@@ -63,18 +64,27 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag) ...@@ -63,18 +64,27 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag)
curr = (u64)__tag_set(addr, tag); curr = (u64)__tag_set(addr, tag);
end = curr + size; end = curr + size;
do { /*
/* * 'asm volatile' is required to prevent the compiler to move
* 'asm volatile' is required to prevent the compiler to move * the statement outside of the loop.
* the statement outside of the loop. */
*/ if (init) {
asm volatile(__MTE_PREAMBLE "stg %0, [%0]" do {
: asm volatile(__MTE_PREAMBLE "stzg %0, [%0]"
: "r" (curr) :
: "memory"); : "r" (curr)
: "memory");
curr += MTE_GRANULE_SIZE; curr += MTE_GRANULE_SIZE;
} while (curr != end); } while (curr != end);
} else {
do {
asm volatile(__MTE_PREAMBLE "stg %0, [%0]"
:
: "r" (curr)
: "memory");
curr += MTE_GRANULE_SIZE;
} while (curr != end);
}
} }
void mte_enable_kernel_sync(void); void mte_enable_kernel_sync(void);
...@@ -101,7 +111,8 @@ static inline u8 mte_get_random_tag(void) ...@@ -101,7 +111,8 @@ static inline u8 mte_get_random_tag(void)
return 0xFF; return 0xFF;
} }
static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag) static inline void mte_set_mem_tag_range(void *addr, size_t size,
u8 tag, bool init)
{ {
} }
......
...@@ -314,7 +314,7 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag) ...@@ -314,7 +314,7 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
#define arch_get_mem_tag(addr) (0xFF) #define arch_get_mem_tag(addr) (0xFF)
#endif #endif
#ifndef arch_set_mem_tag_range #ifndef arch_set_mem_tag_range
#define arch_set_mem_tag_range(addr, size, tag) ((void *)(addr)) #define arch_set_mem_tag_range(addr, size, tag, init) ((void *)(addr))
#endif #endif
#define hw_enable_tagging_sync() arch_enable_tagging_sync() #define hw_enable_tagging_sync() arch_enable_tagging_sync()
...@@ -324,7 +324,8 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag) ...@@ -324,7 +324,8 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
#define hw_force_async_tag_fault() arch_force_async_tag_fault() #define hw_force_async_tag_fault() arch_force_async_tag_fault()
#define hw_get_random_tag() arch_get_random_tag() #define hw_get_random_tag() arch_get_random_tag()
#define hw_get_mem_tag(addr) arch_get_mem_tag(addr) #define hw_get_mem_tag(addr) arch_get_mem_tag(addr)
#define hw_set_mem_tag_range(addr, size, tag) arch_set_mem_tag_range((addr), (size), (tag)) #define hw_set_mem_tag_range(addr, size, tag, init) \
arch_set_mem_tag_range((addr), (size), (tag), (init))
#else /* CONFIG_KASAN_HW_TAGS */ #else /* CONFIG_KASAN_HW_TAGS */
...@@ -371,7 +372,7 @@ static inline void kasan_poison(const void *addr, size_t size, u8 value) ...@@ -371,7 +372,7 @@ static inline void kasan_poison(const void *addr, size_t size, u8 value)
if (WARN_ON(size & KASAN_GRANULE_MASK)) if (WARN_ON(size & KASAN_GRANULE_MASK))
return; return;
hw_set_mem_tag_range((void *)addr, size, value); hw_set_mem_tag_range((void *)addr, size, value, false);
} }
static inline void kasan_unpoison(const void *addr, size_t size) static inline void kasan_unpoison(const void *addr, size_t size)
...@@ -388,7 +389,7 @@ static inline void kasan_unpoison(const void *addr, size_t size) ...@@ -388,7 +389,7 @@ static inline void kasan_unpoison(const void *addr, size_t size)
return; return;
size = round_up(size, KASAN_GRANULE_SIZE); size = round_up(size, KASAN_GRANULE_SIZE);
hw_set_mem_tag_range((void *)addr, size, tag); hw_set_mem_tag_range((void *)addr, size, tag, false);
} }
static inline bool kasan_byte_accessible(const void *addr) static inline bool kasan_byte_accessible(const void *addr)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment