Skip to content

Commit c54f90c

Browse files
samitolvanenwilldeacon
authored andcommitted
arm64: fix alternatives with LLVM's integrated assembler
LLVM's integrated assembler fails with the following error when building KVM: <inline asm>:12:6: error: expected absolute expression .if kvm_update_va_mask == 0 ^ <inline asm>:21:6: error: expected absolute expression .if kvm_update_va_mask == 0 ^ <inline asm>:24:2: error: unrecognized instruction mnemonic NOT_AN_INSTRUCTION ^ LLVM ERROR: Error parsing inline asm These errors come from ALTERNATIVE_CB and __ALTERNATIVE_CFG, which test for the existence of the callback parameter in inline assembly using the following expression: " .if " __stringify(cb) " == 0\n" This works with GNU as, but isn't supported by LLVM. This change splits __ALTERNATIVE_CFG and ALTINSTR_ENTRY into separate macros to fix the LLVM build. Link: ClangBuiltLinux#472 Signed-off-by: Sami Tolvanen <[email protected]> Tested-by: Nick Desaulniers <[email protected]> Reviewed-by: Kees Cook <[email protected]> Signed-off-by: Will Deacon <[email protected]>
1 parent e0d5896 commit c54f90c

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

arch/arm64/include/asm/alternative.h

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,16 @@ void apply_alternatives_module(void *start, size_t length);
3535
static inline void apply_alternatives_module(void *start, size_t length) { }
3636
#endif
3737

38-
#define ALTINSTR_ENTRY(feature,cb) \
38+
#define ALTINSTR_ENTRY(feature) \
3939
" .word 661b - .\n" /* label */ \
40-
" .if " __stringify(cb) " == 0\n" \
4140
" .word 663f - .\n" /* new instruction */ \
42-
" .else\n" \
41+
" .hword " __stringify(feature) "\n" /* feature bit */ \
42+
" .byte 662b-661b\n" /* source len */ \
43+
" .byte 664f-663f\n" /* replacement len */
44+
45+
#define ALTINSTR_ENTRY_CB(feature, cb) \
46+
" .word 661b - .\n" /* label */ \
4347
" .word " __stringify(cb) "- .\n" /* callback */ \
44-
" .endif\n" \
4548
" .hword " __stringify(feature) "\n" /* feature bit */ \
4649
" .byte 662b-661b\n" /* source len */ \
4750
" .byte 664f-663f\n" /* replacement len */
@@ -62,33 +65,40 @@ static inline void apply_alternatives_module(void *start, size_t length) { }
6265
*
6366
* Alternatives with callbacks do not generate replacement instructions.
6467
*/
65-
#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled, cb) \
68+
#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled) \
6669
".if "__stringify(cfg_enabled)" == 1\n" \
6770
"661:\n\t" \
6871
oldinstr "\n" \
6972
"662:\n" \
7073
".pushsection .altinstructions,\"a\"\n" \
71-
ALTINSTR_ENTRY(feature,cb) \
74+
ALTINSTR_ENTRY(feature) \
7275
".popsection\n" \
73-
" .if " __stringify(cb) " == 0\n" \
7476
".pushsection .altinstr_replacement, \"a\"\n" \
7577
"663:\n\t" \
7678
newinstr "\n" \
7779
"664:\n\t" \
7880
".popsection\n\t" \
7981
".org . - (664b-663b) + (662b-661b)\n\t" \
8082
".org . - (662b-661b) + (664b-663b)\n" \
81-
".else\n\t" \
83+
".endif\n"
84+
85+
#define __ALTERNATIVE_CFG_CB(oldinstr, feature, cfg_enabled, cb) \
86+
".if "__stringify(cfg_enabled)" == 1\n" \
87+
"661:\n\t" \
88+
oldinstr "\n" \
89+
"662:\n" \
90+
".pushsection .altinstructions,\"a\"\n" \
91+
ALTINSTR_ENTRY_CB(feature, cb) \
92+
".popsection\n" \
8293
"663:\n\t" \
8394
"664:\n\t" \
84-
".endif\n" \
8595
".endif\n"
8696

8797
#define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...) \
88-
__ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg), 0)
98+
__ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg))
8999

90100
#define ALTERNATIVE_CB(oldinstr, cb) \
91-
__ALTERNATIVE_CFG(oldinstr, "NOT_AN_INSTRUCTION", ARM64_CB_PATCH, 1, cb)
101+
__ALTERNATIVE_CFG_CB(oldinstr, ARM64_CB_PATCH, 1, cb)
92102
#else
93103

94104
#include <asm/assembler.h>

0 commit comments

Comments
 (0)