From 9f925b293d87a53286adb7341f8140fa709d5809 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Fri, 5 Mar 2021 16:29:21 +0100 Subject: [PATCH] Revert "FROMGIT: kasan, arm64: allow using KUnit tests with HW_TAGS mode" This reverts commit a599a4e3b9439792ce8d9e372c8cf4f8b96b38b6. The upstream version of this patch has been updated. Revert the FROMGIT version before applying the UPSTREAM one. Bug: 172318110 Signed-off-by: Andrey Konovalov Change-Id: I423a68e2a3e55b97b04180fedd7160c704ae0972 --- arch/arm64/include/asm/memory.h | 1 - arch/arm64/include/asm/mte-kasan.h | 12 ------------ arch/arm64/kernel/mte.c | 12 ------------ arch/arm64/mm/fault.c | 20 ++++++-------------- lib/Kconfig.kasan | 4 ++-- lib/test_kasan.c | 18 +----------------- mm/kasan/kasan.h | 9 --------- 7 files changed, 9 insertions(+), 67 deletions(-) diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index 3faa1f607a03..e12acd54d2cb 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -233,7 +233,6 @@ static inline const void *__tag_set(const void *addr, u8 tag) #ifdef CONFIG_KASAN_HW_TAGS #define arch_enable_tagging() mte_enable_kernel() -#define arch_set_tagging_report_once(state) mte_set_report_once(state) #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 7ab500e2ad17..79f9ad22e7dd 100644 --- a/arch/arm64/include/asm/mte-kasan.h +++ b/arch/arm64/include/asm/mte-kasan.h @@ -80,9 +80,6 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag) void mte_enable_kernel(void); void mte_init_tags(u64 max_tag); -void mte_set_report_once(bool state); -bool mte_report_once(void); - #else /* CONFIG_ARM64_MTE */ static inline u8 mte_get_ptr_tag(void *ptr) @@ -112,15 +109,6 @@ static inline void mte_init_tags(u64 max_tag) { } -static inline void mte_set_report_once(bool state) -{ -} - -static inline bool mte_report_once(void) -{ - return false; -} - #endif /* CONFIG_ARM64_MTE */ #endif /* __ASSEMBLY__ */ diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index b3c70a612c7a..a467f3a04a33 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -24,8 +24,6 @@ u64 gcr_kernel_excl __ro_after_init; -static bool report_fault_once = true; - static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_swap) { pte_t old_pte = READ_ONCE(*ptep); @@ -114,16 +112,6 @@ void mte_enable_kernel(void) isb(); } -void mte_set_report_once(bool state) -{ - WRITE_ONCE(report_fault_once, state); -} - -bool mte_report_once(void) -{ - return READ_ONCE(report_fault_once); -} - static void update_sctlr_el1_tcf0(u64 tcf0) { /* ISB required for the kernel uaccess routines */ diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index b50f8b062b8b..f6c07fc0bba7 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -306,24 +306,12 @@ static void die_kernel_fault(const char *msg, unsigned long addr, static void report_tag_fault(unsigned long addr, unsigned int esr, struct pt_regs *regs) { - static bool reported; - bool is_write; - - if (READ_ONCE(reported)) - return; - - /* - * This is used for KASAN tests and assumes that no MTE faults - * happened before running the tests. - */ - if (mte_report_once()) - WRITE_ONCE(reported, true); + bool is_write = ((esr & ESR_ELx_WNR) >> ESR_ELx_WNR_SHIFT) != 0; /* * SAS bits aren't set for all faults reported in EL1, so we can't * find out access size. */ - is_write = !!(esr & ESR_ELx_WNR); kasan_report(addr, 0, is_write, regs->pc); } #else @@ -335,8 +323,12 @@ static inline void report_tag_fault(unsigned long addr, unsigned int esr, static void do_tag_recovery(unsigned long addr, unsigned int esr, struct pt_regs *regs) { + static bool reported; - report_tag_fault(addr, esr, regs); + if (!READ_ONCE(reported)) { + report_tag_fault(addr, esr, regs); + WRITE_ONCE(reported, true); + } /* * Disable MTE Tag Checking on the local CPU for the current EL. diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan index 23cf5d537605..a43340ee8f7f 100644 --- a/lib/Kconfig.kasan +++ b/lib/Kconfig.kasan @@ -199,11 +199,11 @@ config KASAN_KUNIT_TEST kernel debugging features like KASAN. For more information on KUnit and unit tests in general, please refer - to the KUnit documentation in Documentation/dev-tools/kunit. + to the KUnit documentation in Documentation/dev-tools/kunit config KASAN_MODULE_TEST tristate "KUnit-incompatible tests of KASAN bug detection capabilities" - depends on m && KASAN && !KASAN_HW_TAGS + depends on m && KASAN help This is a part of the KASAN test suite that is incompatible with KUnit. Currently includes tests that do bad copy_from/to_user diff --git a/lib/test_kasan.c b/lib/test_kasan.c index 1328c468fdb5..4bfe917acb74 100644 --- a/lib/test_kasan.c +++ b/lib/test_kasan.c @@ -41,9 +41,7 @@ static bool multishot; /* * Temporarily enable multi-shot mode. Otherwise, KASAN would only report the - * first detected bug and panic the kernel if panic_on_warn is enabled. For - * hardware tag-based KASAN also allow tag checking to be reenabled for each - * test, see the comment for KUNIT_EXPECT_KASAN_FAIL(). + * first detected bug and panic the kernel if panic_on_warn is enabled. */ static int kasan_test_init(struct kunit *test) { @@ -53,13 +51,11 @@ static int kasan_test_init(struct kunit *test) } multishot = kasan_save_enable_multi_shot(); - hw_set_tagging_report_once(false); return 0; } static void kasan_test_exit(struct kunit *test) { - hw_set_tagging_report_once(true); kasan_restore_multi_shot(multishot); } @@ -69,19 +65,12 @@ static void kasan_test_exit(struct kunit *test) * resource named "kasan_data". Do not use this name for KUnit resources * outside of KASAN tests. * - * For hardware tag-based KASAN, when a tag fault happens, tag checking is - * normally auto-disabled. When this happens, this test handler reenables - * tag checking. As tag checking can be only disabled or enabled per CPU, this - * handler disables migration (preemption). - * * Since the compiler doesn't see that the expression can change the fail_data * fields, it can reorder or optimize away the accesses to those fields. * Use READ/WRITE_ONCE() for the accesses and compiler barriers around the * expression to prevent that. */ #define KUNIT_EXPECT_KASAN_FAIL(test, expression) do { \ - if (IS_ENABLED(CONFIG_KASAN_HW_TAGS)) \ - migrate_disable(); \ WRITE_ONCE(fail_data.report_expected, true); \ WRITE_ONCE(fail_data.report_found, false); \ kunit_add_named_resource(test, \ @@ -95,11 +84,6 @@ static void kasan_test_exit(struct kunit *test) KUNIT_EXPECT_EQ(test, \ READ_ONCE(fail_data.report_expected), \ READ_ONCE(fail_data.report_found)); \ - if (IS_ENABLED(CONFIG_KASAN_HW_TAGS)) { \ - if (READ_ONCE(fail_data.report_found)) \ - hw_enable_tagging(); \ - migrate_enable(); \ - } \ } while (0) #define KASAN_TEST_NEEDS_CONFIG_ON(test, config) do { \ diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index 8d931f55ba6f..a00e0f8ff8f7 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -281,9 +281,6 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag) #ifndef arch_init_tags #define arch_init_tags(max_tag) #endif -#ifndef arch_set_tagging_report_once -#define arch_set_tagging_report_once(state) -#endif #ifndef arch_get_random_tag #define arch_get_random_tag() (0xFF) #endif @@ -296,16 +293,10 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag) #define hw_enable_tagging() arch_enable_tagging() #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() #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)) -#else /* CONFIG_KASAN_HW_TAGS */ - -#define hw_enable_tagging() -#define hw_set_tagging_report_once(state) - #endif /* CONFIG_KASAN_HW_TAGS */ #ifdef CONFIG_KASAN_SW_TAGS