| From 975779d227cfda639098044f82bb10f47424d013 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 30 Jun 2021 18:56:49 -0700 |
| Subject: kcov: add __no_sanitize_coverage to fix noinstr for all architectures |
| |
| From: Marco Elver <elver@google.com> |
| |
| [ Upstream commit 540540d06e9d9b3769b46d88def90f7e7c002322 ] |
| |
| Until now no compiler supported an attribute to disable coverage |
| instrumentation as used by KCOV. |
| |
| To work around this limitation on x86, noinstr functions have their |
| coverage instrumentation turned into nops by objtool. However, this |
| solution doesn't scale automatically to other architectures, such as |
| arm64, which are migrating to use the generic entry code. |
| |
| Clang [1] and GCC [2] have added support for the attribute recently. |
| [1] https://github.com/llvm/llvm-project/commit/280333021e9550d80f5c1152a34e33e81df1e178 |
| [2] https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=cec4d4a6782c9bd8d071839c50a239c49caca689 |
| The changes will appear in Clang 13 and GCC 12. |
| |
| Add __no_sanitize_coverage for both compilers, and add it to noinstr. |
| |
| Note: In the Clang case, __has_feature(coverage_sanitizer) is only true if |
| the feature is enabled, and therefore we do not require an additional |
| defined(CONFIG_KCOV) (like in the GCC case where __has_attribute(..) is |
| always true) to avoid adding redundant attributes to functions if KCOV is |
| off. That being said, compilers that support the attribute will not |
| generate errors/warnings if the attribute is redundantly used; however, |
| where possible let's avoid it as it reduces preprocessed code size and |
| associated compile-time overheads. |
| |
| [elver@google.com: Implement __has_feature(coverage_sanitizer) in Clang] |
| Link: https://lkml.kernel.org/r/20210527162655.3246381-1-elver@google.com |
| [elver@google.com: add comment explaining __has_feature() in Clang] |
| Link: https://lkml.kernel.org/r/20210527194448.3470080-1-elver@google.com |
| |
| Link: https://lkml.kernel.org/r/20210525175819.699786-1-elver@google.com |
| Signed-off-by: Marco Elver <elver@google.com> |
| Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> |
| Reviewed-by: Miguel Ojeda <ojeda@kernel.org> |
| Reviewed-by: Nathan Chancellor <nathan@kernel.org> |
| Cc: Nick Desaulniers <ndesaulniers@google.com> |
| Cc: Kees Cook <keescook@chromium.org> |
| Cc: Will Deacon <will@kernel.org> |
| Cc: Ard Biesheuvel <ardb@kernel.org> |
| Cc: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> |
| Cc: Arvind Sankar <nivedita@alum.mit.edu> |
| Cc: Masahiro Yamada <masahiroy@kernel.org> |
| Cc: Sami Tolvanen <samitolvanen@google.com> |
| Cc: Arnd Bergmann <arnd@arndb.de> |
| Cc: Dmitry Vyukov <dvyukov@google.com> |
| Cc: Mark Rutland <mark.rutland@arm.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/linux/compiler-clang.h | 17 +++++++++++++++++ |
| include/linux/compiler-gcc.h | 6 ++++++ |
| include/linux/compiler_types.h | 2 +- |
| 3 files changed, 24 insertions(+), 1 deletion(-) |
| |
| diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h |
| index d217c382b02d..4d87b36dbc8c 100644 |
| --- a/include/linux/compiler-clang.h |
| +++ b/include/linux/compiler-clang.h |
| @@ -13,6 +13,12 @@ |
| /* all clang versions usable with the kernel support KASAN ABI version 5 */ |
| #define KASAN_ABI_VERSION 5 |
| |
| +/* |
| + * Note: Checking __has_feature(*_sanitizer) is only true if the feature is |
| + * enabled. Therefore it is not required to additionally check defined(CONFIG_*) |
| + * to avoid adding redundant attributes in other configurations. |
| + */ |
| + |
| #if __has_feature(address_sanitizer) || __has_feature(hwaddress_sanitizer) |
| /* Emulate GCC's __SANITIZE_ADDRESS__ flag */ |
| #define __SANITIZE_ADDRESS__ |
| @@ -45,6 +51,17 @@ |
| #define __no_sanitize_undefined |
| #endif |
| |
| +/* |
| + * Support for __has_feature(coverage_sanitizer) was added in Clang 13 together |
| + * with no_sanitize("coverage"). Prior versions of Clang support coverage |
| + * instrumentation, but cannot be queried for support by the preprocessor. |
| + */ |
| +#if __has_feature(coverage_sanitizer) |
| +#define __no_sanitize_coverage __attribute__((no_sanitize("coverage"))) |
| +#else |
| +#define __no_sanitize_coverage |
| +#endif |
| + |
| /* |
| * Not all versions of clang implement the type-generic versions |
| * of the builtin overflow checkers. Fortunately, clang implements |
| diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h |
| index 48750243db4c..c6ab0dcb9c0c 100644 |
| --- a/include/linux/compiler-gcc.h |
| +++ b/include/linux/compiler-gcc.h |
| @@ -126,6 +126,12 @@ |
| #define __no_sanitize_undefined |
| #endif |
| |
| +#if defined(CONFIG_KCOV) && __has_attribute(__no_sanitize_coverage__) |
| +#define __no_sanitize_coverage __attribute__((no_sanitize_coverage)) |
| +#else |
| +#define __no_sanitize_coverage |
| +#endif |
| + |
| #if GCC_VERSION >= 50100 |
| #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 |
| #endif |
| diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h |
| index e5dd5a4ae946..652217da3b7c 100644 |
| --- a/include/linux/compiler_types.h |
| +++ b/include/linux/compiler_types.h |
| @@ -210,7 +210,7 @@ struct ftrace_likely_data { |
| /* Section for code which can't be instrumented at all */ |
| #define noinstr \ |
| noinline notrace __attribute((__section__(".noinstr.text"))) \ |
| - __no_kcsan __no_sanitize_address |
| + __no_kcsan __no_sanitize_address __no_sanitize_coverage |
| |
| #endif /* __KERNEL__ */ |
| |
| -- |
| 2.30.2 |
| |