Skip to content

Commit e32683c

Browse files
jpoimboePeter Zijlstra
authored andcommitted
x86/mm: Fix RESERVE_BRK() for older binutils
With binutils 2.26, RESERVE_BRK() causes a build failure: /tmp/ccnGOKZ5.s: Assembler messages: /tmp/ccnGOKZ5.s:98: Error: missing ')' /tmp/ccnGOKZ5.s:98: Error: missing ')' /tmp/ccnGOKZ5.s:98: Error: missing ')' /tmp/ccnGOKZ5.s:98: Error: junk at end of line, first unrecognized character is `U' The problem is this line: RESERVE_BRK(early_pgt_alloc, INIT_PGT_BUF_SIZE) Specifically, the INIT_PGT_BUF_SIZE macro which (via PAGE_SIZE's use _AC()) has a "1UL", which makes older versions of the assembler unhappy. Unfortunately the _AC() macro doesn't work for inline asm. Inline asm was only needed here to convince the toolchain to add the STT_NOBITS flag. However, if a C variable is placed in a section whose name is prefixed with ".bss", GCC and Clang automatically set STT_NOBITS. In fact, ".bss..page_aligned" already relies on this trick. So fix the build failure (and simplify the macro) by allocating the variable in C. Also, add NOLOAD to the ".brk" output section clause in the linker script. This is a failsafe in case the ".bss" prefix magic trick ever stops working somehow. If there's a section type mismatch, the GNU linker will force the ".brk" output section to be STT_NOBITS. The LLVM linker will fail with a "section type mismatch" error. Note this also changes the name of the variable from .brk.##name to __brk_##name. The variable names aren't actually used anywhere, so it's harmless. Fixes: a1e2c03 ("x86/mm: Simplify RESERVE_BRK()") Reported-by: Joe Damato <[email protected]> Reported-by: Byungchul Park <[email protected]> Signed-off-by: Josh Poimboeuf <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Tested-by: Joe Damato <[email protected]> Link: https://lore.kernel.org/r/22d07a44c80d8e8e1e82b9a806ddc8c6bbb2606e.1654759036.git.jpoimboe@kernel.org
1 parent b13bacc commit e32683c

File tree

3 files changed

+23
-24
lines changed

3 files changed

+23
-24
lines changed

arch/x86/include/asm/setup.h

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -108,19 +108,16 @@ extern unsigned long _brk_end;
108108
void *extend_brk(size_t size, size_t align);
109109

110110
/*
111-
* Reserve space in the brk section. The name must be unique within the file,
112-
* and somewhat descriptive. The size is in bytes.
111+
* Reserve space in the .brk section, which is a block of memory from which the
112+
* caller is allowed to allocate very early (before even memblock is available)
113+
* by calling extend_brk(). All allocated memory will be eventually converted
114+
* to memblock. Any leftover unallocated memory will be freed.
113115
*
114-
* The allocation is done using inline asm (rather than using a section
115-
* attribute on a normal variable) in order to allow the use of @nobits, so
116-
* that it doesn't take up any space in the vmlinux file.
116+
* The size is in bytes.
117117
*/
118-
#define RESERVE_BRK(name, size) \
119-
asm(".pushsection .brk_reservation,\"aw\",@nobits\n\t" \
120-
".brk." #name ":\n\t" \
121-
".skip " __stringify(size) "\n\t" \
122-
".size .brk." #name ", " __stringify(size) "\n\t" \
123-
".popsection\n\t")
118+
#define RESERVE_BRK(name, size) \
119+
__section(".bss..brk") __aligned(1) __used \
120+
static char __brk_##name[size]
124121

125122
extern void probe_roms(void);
126123
#ifdef __i386__
@@ -133,12 +130,19 @@ asmlinkage void __init x86_64_start_reservations(char *real_mode_data);
133130

134131
#endif /* __i386__ */
135132
#endif /* _SETUP */
136-
#else
137-
#define RESERVE_BRK(name,sz) \
138-
.pushsection .brk_reservation,"aw",@nobits; \
139-
.brk.name: \
140-
1: .skip sz; \
141-
.size .brk.name,.-1b; \
133+
134+
#else /* __ASSEMBLY */
135+
136+
.macro __RESERVE_BRK name, size
137+
.pushsection .bss..brk, "aw"
138+
SYM_DATA_START(__brk_\name)
139+
.skip \size
140+
SYM_DATA_END(__brk_\name)
142141
.popsection
142+
.endm
143+
144+
#define RESERVE_BRK(name, size) __RESERVE_BRK name, size
145+
143146
#endif /* __ASSEMBLY__ */
147+
144148
#endif /* _ASM_X86_SETUP_H */

arch/x86/kernel/setup.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,6 @@ RESERVE_BRK(dmi_alloc, 65536);
6767
#endif
6868

6969

70-
/*
71-
* Range of the BSS area. The size of the BSS area is determined
72-
* at link time, with RESERVE_BRK() facility reserving additional
73-
* chunks.
74-
*/
7570
unsigned long _brk_start = (unsigned long)__brk_base;
7671
unsigned long _brk_end = (unsigned long)__brk_base;
7772

arch/x86/kernel/vmlinux.lds.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,10 @@ SECTIONS
385385
__end_of_kernel_reserve = .;
386386

387387
. = ALIGN(PAGE_SIZE);
388-
.brk : AT(ADDR(.brk) - LOAD_OFFSET) {
388+
.brk (NOLOAD) : AT(ADDR(.brk) - LOAD_OFFSET) {
389389
__brk_base = .;
390390
. += 64 * 1024; /* 64k alignment slop space */
391-
*(.brk_reservation) /* areas brk users have reserved */
391+
*(.bss..brk) /* areas brk users have reserved */
392392
__brk_limit = .;
393393
}
394394

0 commit comments

Comments
 (0)