Message ID | 20210130165225.54047-3-vincenzo.frascino@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64: ARMv8.5-A: MTE: Add async mode support | expand |
On Sat, Jan 30, 2021 at 5:52 PM Vincenzo Frascino <vincenzo.frascino@arm.com> wrote: > > @@ -45,6 +52,9 @@ static enum kasan_arg_fault kasan_arg_fault __ro_after_init; > DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled); > EXPORT_SYMBOL(kasan_flag_enabled); > > +/* Whether the asynchronous mode is enabled. */ > +bool kasan_flag_async __ro_after_init; Just noticed that we need EXPORT_SYMBOL(kasan_flag_async) here. There are also a few arm64 mte functions that need to be exported, but I've addressed that myself here: https://lore.kernel.org/linux-arm-kernel/cover.1612208222.git.andreyknvl@google.com/T/#m4746d3c410c3f6baddb726fc9ea9dd1496a4a788
On Mon, Feb 1, 2021 at 9:04 PM Andrey Konovalov <andreyknvl@google.com> wrote: > > On Sat, Jan 30, 2021 at 5:52 PM Vincenzo Frascino > <vincenzo.frascino@arm.com> wrote: > > > > @@ -45,6 +52,9 @@ static enum kasan_arg_fault kasan_arg_fault __ro_after_init; > > DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled); > > EXPORT_SYMBOL(kasan_flag_enabled); > > > > +/* Whether the asynchronous mode is enabled. */ > > +bool kasan_flag_async __ro_after_init; > > Just noticed that we need EXPORT_SYMBOL(kasan_flag_async) here. Hi Vincenzo, If you post a new version of this series, please include EXPORT_SYMBOL(kasan_flag_async). Thanks! > > There are also a few arm64 mte functions that need to be exported, but > I've addressed that myself here: > > https://lore.kernel.org/linux-arm-kernel/cover.1612208222.git.andreyknvl@google.com/T/#m4746d3c410c3f6baddb726fc9ea9dd1496a4a788
On 2/5/21 3:49 PM, Andrey Konovalov wrote: > On Mon, Feb 1, 2021 at 9:04 PM Andrey Konovalov <andreyknvl@google.com> wrote: >> >> On Sat, Jan 30, 2021 at 5:52 PM Vincenzo Frascino >> <vincenzo.frascino@arm.com> wrote: >>> >>> @@ -45,6 +52,9 @@ static enum kasan_arg_fault kasan_arg_fault __ro_after_init; >>> DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled); >>> EXPORT_SYMBOL(kasan_flag_enabled); >>> >>> +/* Whether the asynchronous mode is enabled. */ >>> +bool kasan_flag_async __ro_after_init; >> >> Just noticed that we need EXPORT_SYMBOL(kasan_flag_async) here. > > Hi Vincenzo, > > If you post a new version of this series, please include > EXPORT_SYMBOL(kasan_flag_async). > I can do that, no problem. > Thanks! > >> >> There are also a few arm64 mte functions that need to be exported, but >> I've addressed that myself here: >> >> https://lore.kernel.org/linux-arm-kernel/cover.1612208222.git.andreyknvl@google.com/T/#m4746d3c410c3f6baddb726fc9ea9dd1496a4a788
On Fri, Feb 05, 2021 at 04:00:07PM +0000, Vincenzo Frascino wrote: > > > On 2/5/21 3:49 PM, Andrey Konovalov wrote: > > On Mon, Feb 1, 2021 at 9:04 PM Andrey Konovalov <andreyknvl@google.com> wrote: > >> > >> On Sat, Jan 30, 2021 at 5:52 PM Vincenzo Frascino > >> <vincenzo.frascino@arm.com> wrote: > >>> > >>> @@ -45,6 +52,9 @@ static enum kasan_arg_fault kasan_arg_fault __ro_after_init; > >>> DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled); > >>> EXPORT_SYMBOL(kasan_flag_enabled); > >>> > >>> +/* Whether the asynchronous mode is enabled. */ > >>> +bool kasan_flag_async __ro_after_init; > >> > >> Just noticed that we need EXPORT_SYMBOL(kasan_flag_async) here. > > > > Hi Vincenzo, > > > > If you post a new version of this series, please include > > EXPORT_SYMBOL(kasan_flag_async). > > > > I can do that, no problem. EXPORT_SYMBOL_GPL, please :) Will
On 2/5/21 4:48 PM, Will Deacon wrote: > On Fri, Feb 05, 2021 at 04:00:07PM +0000, Vincenzo Frascino wrote: >> >> >> On 2/5/21 3:49 PM, Andrey Konovalov wrote: >>> On Mon, Feb 1, 2021 at 9:04 PM Andrey Konovalov <andreyknvl@google.com> wrote: >>>> >>>> On Sat, Jan 30, 2021 at 5:52 PM Vincenzo Frascino >>>> <vincenzo.frascino@arm.com> wrote: >>>>> >>>>> @@ -45,6 +52,9 @@ static enum kasan_arg_fault kasan_arg_fault __ro_after_init; >>>>> DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled); >>>>> EXPORT_SYMBOL(kasan_flag_enabled); >>>>> >>>>> +/* Whether the asynchronous mode is enabled. */ >>>>> +bool kasan_flag_async __ro_after_init; >>>> >>>> Just noticed that we need EXPORT_SYMBOL(kasan_flag_async) here. >>> >>> Hi Vincenzo, >>> >>> If you post a new version of this series, please include >>> EXPORT_SYMBOL(kasan_flag_async). >>> >> >> I can do that, no problem. > > EXPORT_SYMBOL_GPL, please :) > Thanks Will, I will :) > Will >
diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst index e022b7506e37..e3dca4d1f2a7 100644 --- a/Documentation/dev-tools/kasan.rst +++ b/Documentation/dev-tools/kasan.rst @@ -161,6 +161,15 @@ particular KASAN features. - ``kasan=off`` or ``=on`` controls whether KASAN is enabled (default: ``on``). +- ``kasan.mode=sync`` or ``=async`` controls whether KASAN is configured in + synchronous or asynchronous mode of execution (default: ``sync``). + Synchronous mode: a bad access is detected immediately when a tag + check fault occurs. + Asynchronous mode: a bad access detection is delayed. When a tag check + fault occurs, the information is stored in hardware (in the TFSR_EL1 + register for arm64). The kernel periodically checks the hardware and + only reports tag faults during these checks. + - ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack traces collection (default: ``on`` for ``CONFIG_DEBUG_KERNEL=y``, otherwise ``off``). diff --git a/lib/test_kasan.c b/lib/test_kasan.c index d16ec9e66806..7285dcf9fcc1 100644 --- a/lib/test_kasan.c +++ b/lib/test_kasan.c @@ -97,7 +97,7 @@ static void kasan_test_exit(struct kunit *test) READ_ONCE(fail_data.report_found)); \ if (IS_ENABLED(CONFIG_KASAN_HW_TAGS)) { \ if (READ_ONCE(fail_data.report_found)) \ - hw_enable_tagging(); \ + hw_enable_tagging_sync(); \ migrate_enable(); \ } \ } while (0) diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c index e529428e7a11..e8a5f5da2479 100644 --- a/mm/kasan/hw_tags.c +++ b/mm/kasan/hw_tags.c @@ -25,6 +25,12 @@ enum kasan_arg { KASAN_ARG_ON, }; +enum kasan_arg_mode { + KASAN_ARG_MODE_DEFAULT, + KASAN_ARG_MODE_SYNC, + KASAN_ARG_MODE_ASYNC, +}; + enum kasan_arg_stacktrace { KASAN_ARG_STACKTRACE_DEFAULT, KASAN_ARG_STACKTRACE_OFF, @@ -38,6 +44,7 @@ enum kasan_arg_fault { }; static enum kasan_arg kasan_arg __ro_after_init; +static enum kasan_arg_mode kasan_arg_mode __ro_after_init; static enum kasan_arg_stacktrace kasan_arg_stacktrace __ro_after_init; static enum kasan_arg_fault kasan_arg_fault __ro_after_init; @@ -45,6 +52,9 @@ static enum kasan_arg_fault kasan_arg_fault __ro_after_init; DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled); EXPORT_SYMBOL(kasan_flag_enabled); +/* Whether the asynchronous mode is enabled. */ +bool kasan_flag_async __ro_after_init; + /* Whether to collect alloc/free stack traces. */ DEFINE_STATIC_KEY_FALSE(kasan_flag_stacktrace); @@ -68,6 +78,21 @@ static int __init early_kasan_flag(char *arg) } early_param("kasan", early_kasan_flag); +/* kasan.mode=sync/async */ +static int __init early_kasan_mode(char *arg) +{ + /* If arg is not set the default mode is sync */ + if ((!arg) || !strcmp(arg, "sync")) + kasan_arg_mode = KASAN_ARG_MODE_SYNC; + else if (!strcmp(arg, "async")) + kasan_arg_mode = KASAN_ARG_MODE_ASYNC; + else + return -EINVAL; + + return 0; +} +early_param("kasan.mode", early_kasan_mode); + /* kasan.stacktrace=off/on */ static int __init early_kasan_flag_stacktrace(char *arg) { @@ -115,7 +140,15 @@ void kasan_init_hw_tags_cpu(void) return; hw_init_tags(KASAN_TAG_MAX); - hw_enable_tagging(); + + /* + * Enable async mode only when explicitly requested through + * the command line. + */ + if (kasan_arg_mode == KASAN_ARG_MODE_ASYNC) + hw_enable_tagging_async(); + else + hw_enable_tagging_sync(); } /* kasan_init_hw_tags() is called once on boot CPU. */ @@ -132,6 +165,22 @@ void __init kasan_init_hw_tags(void) /* Enable KASAN. */ static_branch_enable(&kasan_flag_enabled); + switch (kasan_arg_mode) { + case KASAN_ARG_MODE_DEFAULT: + /* + * Default to sync mode. + * Do nothing, kasan_flag_async keeps its default value. + */ + break; + case KASAN_ARG_MODE_SYNC: + /* Do nothing, kasan_flag_async keeps its default value. */ + break; + case KASAN_ARG_MODE_ASYNC: + /* Async mode enabled. */ + kasan_flag_async = true; + break; + } + switch (kasan_arg_stacktrace) { case KASAN_ARG_STACKTRACE_DEFAULT: /* diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index 11c6e3650468..b82f8bae1383 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -21,6 +21,7 @@ static inline bool kasan_stack_collection_enabled(void) #endif extern bool kasan_flag_panic __ro_after_init; +extern bool kasan_flag_async __ro_after_init; #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) #define KASAN_GRANULE_SIZE (1UL << KASAN_SHADOW_SCALE_SHIFT) @@ -294,7 +295,8 @@ 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 hw_enable_tagging() arch_enable_tagging() +#define hw_enable_tagging_sync() arch_enable_tagging_sync() +#define hw_enable_tagging_async() arch_enable_tagging_async() #define hw_init_tags(max_tag) arch_init_tags(max_tag) #define hw_set_tagging_report_once(state) arch_set_tagging_report_once(state) #define hw_get_random_tag() arch_get_random_tag() @@ -303,7 +305,8 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag) #else /* CONFIG_KASAN_HW_TAGS */ -#define hw_enable_tagging() +#define hw_enable_tagging_sync() +#define hw_enable_tagging_async() #define hw_set_tagging_report_once(state) #endif /* CONFIG_KASAN_HW_TAGS */