Skip to content

Commit d77698d

Browse files
Matthias Kaehlckemasahir0y
Matthias Kaehlcke
authored andcommitted
x86/build: Specify stack alignment for clang
For gcc stack alignment is configured with -mpreferred-stack-boundary=N, clang has the option -mstack-alignment=N for that purpose. Use the same alignment as with gcc. If the alignment is not specified clang assumes an alignment of 16 bytes, as required by the standard ABI. However as mentioned in d9b0cde ("x86-64, gcc: Use -mpreferred-stack-boundary=3 if supported") the standard kernel entry on x86-64 leaves the stack on an 8-byte boundary, as a consequence clang will keep the stack misaligned. Signed-off-by: Matthias Kaehlcke <[email protected]> Acked-by: Ingo Molnar <[email protected]> Signed-off-by: Masahiro Yamada <[email protected]>
1 parent 032a2c4 commit d77698d

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

Diff for: arch/x86/Makefile

+21-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ else
1111
KBUILD_DEFCONFIG := $(ARCH)_defconfig
1212
endif
1313

14+
# For gcc stack alignment is specified with -mpreferred-stack-boundary,
15+
# clang has the option -mstack-alignment for that purpose.
16+
ifneq ($(call cc-option, -mpreferred-stack-boundary=4),)
17+
cc_stack_align_opt := -mpreferred-stack-boundary
18+
else ifneq ($(call cc-option, -mstack-alignment=4),)
19+
cc_stack_align_opt := -mstack-alignment
20+
endif
21+
1422
# How to compile the 16-bit code. Note we always compile for -march=i386;
1523
# that way we can complain to the user if the CPU is insufficient.
1624
#
@@ -28,7 +36,7 @@ REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -D__KERNEL__ \
2836

2937
REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding)
3038
REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector)
31-
REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -mpreferred-stack-boundary=2)
39+
REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align_opt)=2)
3240
export REALMODE_CFLAGS
3341

3442
# BITS is used as extension for files which are available in a 32 bit
@@ -65,8 +73,10 @@ ifeq ($(CONFIG_X86_32),y)
6573
# with nonstandard options
6674
KBUILD_CFLAGS += -fno-pic
6775

68-
# prevent gcc from keeping the stack 16 byte aligned
69-
KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
76+
# Align the stack to the register width instead of using the default
77+
# alignment of 16 bytes. This reduces stack usage and the number of
78+
# alignment instructions.
79+
KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align_opt)=2)
7080

7181
# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
7282
# a lot more stack due to the lack of sharing of stacklots:
@@ -98,8 +108,14 @@ else
98108
KBUILD_CFLAGS += $(call cc-option,-mno-80387)
99109
KBUILD_CFLAGS += $(call cc-option,-mno-fp-ret-in-387)
100110

101-
# Use -mpreferred-stack-boundary=3 if supported.
102-
KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3)
111+
# By default gcc and clang use a stack alignment of 16 bytes for x86.
112+
# However the standard kernel entry on x86-64 leaves the stack on an
113+
# 8-byte boundary. If the compiler isn't informed about the actual
114+
# alignment it will generate extra alignment instructions for the
115+
# default alignment which keep the stack *mis*aligned.
116+
# Furthermore an alignment to the register width reduces stack usage
117+
# and the number of alignment instructions.
118+
KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align_opt)=3)
103119

104120
# Use -mskip-rax-setup if supported.
105121
KBUILD_CFLAGS += $(call cc-option,-mskip-rax-setup)

0 commit comments

Comments
 (0)