-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
compiler.h: Move instrumentation_begin()/end() to new <linux/instrume…
…ntation.h> header Linus pointed out that compiler.h - which is a key header that gets included in every single one of the 28,000+ kernel files during a kernel build - was bloated in: 6553896: ("vmlinux.lds.h: Create section for protection against instrumentation") Linus noted: > I have pulled this, but do we really want to add this to a header file > that is _so_ core that it gets included for basically every single > file built? > > I don't even see those instrumentation_begin/end() things used > anywhere right now. > > It seems excessive. That 53 lines is maybe not a lot, but it pushed > that header file to over 12kB, and while it's mostly comments, it's > extra IO and parsing basically for _every_ single file compiled in the > kernel. > > For what appears to be absolutely zero upside right now, and I really > don't see why this should be in such a core header file! Move these primitives into a new header: <linux/instrumentation.h>, and include that header in the headers that make use of it. Unfortunately one of these headers is asm-generic/bug.h, which does get included in a lot of places, similarly to compiler.h. So the de-bloating effect isn't as good as we'd like it to be - but at least the interfaces are defined separately. No change to functionality intended. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200604071921.GA1361070@gmail.com Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Borislav Petkov <bp@alien8.de> Cc: Peter Zijlstra <peterz@infradead.org>
- Loading branch information
Ingo Molnar
committed
Jul 24, 2020
1 parent
f37e99a
commit d19e789
Showing
5 changed files
with
61 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef __LINUX_INSTRUMENTATION_H | ||
#define __LINUX_INSTRUMENTATION_H | ||
|
||
#if defined(CONFIG_DEBUG_ENTRY) && defined(CONFIG_STACK_VALIDATION) | ||
|
||
/* Begin/end of an instrumentation safe region */ | ||
#define instrumentation_begin() ({ \ | ||
asm volatile("%c0: nop\n\t" \ | ||
".pushsection .discard.instr_begin\n\t" \ | ||
".long %c0b - .\n\t" \ | ||
".popsection\n\t" : : "i" (__COUNTER__)); \ | ||
}) | ||
|
||
/* | ||
* Because instrumentation_{begin,end}() can nest, objtool validation considers | ||
* _begin() a +1 and _end() a -1 and computes a sum over the instructions. | ||
* When the value is greater than 0, we consider instrumentation allowed. | ||
* | ||
* There is a problem with code like: | ||
* | ||
* noinstr void foo() | ||
* { | ||
* instrumentation_begin(); | ||
* ... | ||
* if (cond) { | ||
* instrumentation_begin(); | ||
* ... | ||
* instrumentation_end(); | ||
* } | ||
* bar(); | ||
* instrumentation_end(); | ||
* } | ||
* | ||
* If instrumentation_end() would be an empty label, like all the other | ||
* annotations, the inner _end(), which is at the end of a conditional block, | ||
* would land on the instruction after the block. | ||
* | ||
* If we then consider the sum of the !cond path, we'll see that the call to | ||
* bar() is with a 0-value, even though, we meant it to happen with a positive | ||
* value. | ||
* | ||
* To avoid this, have _end() be a NOP instruction, this ensures it will be | ||
* part of the condition block and does not escape. | ||
*/ | ||
#define instrumentation_end() ({ \ | ||
asm volatile("%c0: nop\n\t" \ | ||
".pushsection .discard.instr_end\n\t" \ | ||
".long %c0b - .\n\t" \ | ||
".popsection\n\t" : : "i" (__COUNTER__)); \ | ||
}) | ||
#else | ||
# define instrumentation_begin() do { } while(0) | ||
# define instrumentation_end() do { } while(0) | ||
#endif | ||
|
||
#endif /* __LINUX_INSTRUMENTATION_H */ |