Skip to content

Commit

Permalink
arm64: kernel: Add optional CONFIG_ parameter to ALTERNATIVE()
Browse files Browse the repository at this point in the history
Some uses of ALTERNATIVE() may depend on a feature that is disabled at
compile time by a Kconfig option. In this case the unused alternative
instructions waste space, and if the original instruction is a nop, it
wastes time and space.

This patch adds an optional 'config' option to ALTERNATIVE() and
alternative_insn that allows the compiler to remove both the original
and alternative instructions if the config option is not defined.

Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
  • Loading branch information
James Morse authored and Will Deacon committed Jul 27, 2015
1 parent 18ffa04 commit 91a5cef
Showing 1 changed file with 25 additions and 3 deletions.
28 changes: 25 additions & 3 deletions arch/arm64/include/asm/alternative.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#ifndef __ASSEMBLY__

#include <linux/kconfig.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/stringify.h>
Expand Down Expand Up @@ -40,7 +41,8 @@ void free_alternatives_memory(void);
* be fixed in a binutils release posterior to 2.25.51.0.2 (anything
* containing commit 4e4d08cf7399b606 or c1baaddf8861).
*/
#define ALTERNATIVE(oldinstr, newinstr, feature) \
#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled) \
".if "__stringify(cfg_enabled)" == 1\n" \
"661:\n\t" \
oldinstr "\n" \
"662:\n" \
Expand All @@ -53,7 +55,11 @@ void free_alternatives_memory(void);
"664:\n\t" \
".popsection\n\t" \
".org . - (664b-663b) + (662b-661b)\n\t" \
".org . - (662b-661b) + (664b-663b)\n"
".org . - (662b-661b) + (664b-663b)\n" \
".endif\n"

#define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...) \
__ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg))

#else

Expand All @@ -65,7 +71,8 @@ void free_alternatives_memory(void);
.byte \alt_len
.endm

.macro alternative_insn insn1 insn2 cap
.macro alternative_insn insn1, insn2, cap, enable = 1
.if \enable
661: \insn1
662: .pushsection .altinstructions, "a"
altinstruction_entry 661b, 663f, \cap, 662b-661b, 664f-663f
Expand All @@ -75,6 +82,7 @@ void free_alternatives_memory(void);
664: .popsection
.org . - (664b-663b) + (662b-661b)
.org . - (662b-661b) + (664b-663b)
.endif
.endm

/*
Expand Down Expand Up @@ -118,6 +126,20 @@ void free_alternatives_memory(void);
.org . - (662b-661b) + (664b-663b)
.endm

#define _ALTERNATIVE_CFG(insn1, insn2, cap, cfg, ...) \
alternative_insn insn1, insn2, cap, IS_ENABLED(cfg)


#endif /* __ASSEMBLY__ */

/*
* Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature));
*
* Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature, CONFIG_FOO));
* N.B. If CONFIG_FOO is specified, but not selected, the whole block
* will be omitted, including oldinstr.
*/
#define ALTERNATIVE(oldinstr, newinstr, ...) \
_ALTERNATIVE_CFG(oldinstr, newinstr, __VA_ARGS__, 1)

#endif /* __ASM_ALTERNATIVE_H */

0 comments on commit 91a5cef

Please sign in to comment.