Skip to content

Commit 693c819

Browse files
H. Peter Anvinhansendc
authored andcommitted
x86/entry/vdso: Refactor the vdso build
- Separate out the vdso sources into common, vdso32, and vdso64 directories. - Build the 32- and 64-bit vdsos in their respective subdirectories; this greatly simplifies the build flags handling. - Unify the mangling of Makefile flags between the 32- and 64-bit vdso code as much as possible; all common rules are put in arch/x86/entry/vdso/common/Makefile.include. The remaining is very simple for 32 bits; the 64-bit one is only slightly more complicated because it contains the x32 generation rule. - Define __DISABLE_EXPORTS when building the vdso. This need seems to have been masked by different ordering compile flags before. - Change CONFIG_X86_64 to BUILD_VDSO32_64 in vdso32/system_call.S, to make it compatible with including fake_32bit_build.h. - The -fcf-protection= option was "leaking" from the kernel build, for reasons that was not clear to me. Furthermore, several distributions ship with it set to a default value other than "-fcf-protection=none". Make it match the configuration options for *user space*. Note that this patch may seem large, but the vast majority of it is simply code movement. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Link: https://patch.msgid.link/20251216212606.1325678-4-hpa@zytor.com
1 parent a76108d commit 693c819

21 files changed

Lines changed: 180 additions & 186 deletions

arch/x86/entry/vdso/Makefile

Lines changed: 6 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -3,159 +3,10 @@
33
# Building vDSO images for x86.
44
#
55

6-
# Include the generic Makefile to check the built vDSO:
7-
include $(srctree)/lib/vdso/Makefile.include
6+
# Regular kernel objects
7+
obj-y := vma.o extable.o
8+
obj-$(CONFIG_COMPAT_32) += vdso32-setup.o
89

9-
# Files to link into the vDSO:
10-
vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vgetrandom.o vgetrandom-chacha.o
11-
vobjs32-y := vdso32/note.o vdso32/system_call.o vdso32/sigreturn.o
12-
vobjs32-y += vdso32/vclock_gettime.o vdso32/vgetcpu.o
13-
vobjs-$(CONFIG_X86_SGX) += vsgx.o
14-
15-
# Files to link into the kernel:
16-
obj-y += vma.o extable.o
17-
18-
# vDSO images to build:
19-
obj-$(CONFIG_X86_64) += vdso64-image.o
20-
obj-$(CONFIG_X86_X32_ABI) += vdsox32-image.o
21-
obj-$(CONFIG_COMPAT_32) += vdso32-image.o vdso32-setup.o
22-
23-
vobjs := $(addprefix $(obj)/, $(vobjs-y))
24-
vobjs32 := $(addprefix $(obj)/, $(vobjs32-y))
25-
26-
$(obj)/vdso.o: $(obj)/vdso.so
27-
28-
targets += vdso.lds $(vobjs-y)
29-
targets += vdso32/vdso32.lds $(vobjs32-y)
30-
31-
targets += $(foreach x, 64 x32 32, vdso-image-$(x).c vdso$(x).so vdso$(x).so.dbg)
32-
33-
CPPFLAGS_vdso.lds += -P -C
34-
35-
VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -soname linux-vdso.so.1 \
36-
-z max-page-size=4096
37-
38-
$(obj)/vdso64.so.dbg: $(obj)/vdso.lds $(vobjs) FORCE
39-
$(call if_changed,vdso_and_check)
40-
41-
VDSO2C = $(objtree)/arch/x86/tools/vdso2c
42-
43-
quiet_cmd_vdso2c = VDSO2C $@
44-
cmd_vdso2c = $(VDSO2C) $< $(<:%.dbg=%) $@
45-
46-
$(obj)/vdso%-image.c: $(obj)/vdso%.so.dbg $(obj)/vdso%.so $(VDSO2C) FORCE
47-
$(call if_changed,vdso2c)
48-
49-
#
50-
# Don't omit frame pointers for ease of userspace debugging, but do
51-
# optimize sibling calls.
52-
#
53-
CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
54-
$(filter -g%,$(KBUILD_CFLAGS)) -fno-stack-protector \
55-
-fno-omit-frame-pointer -foptimize-sibling-calls \
56-
-DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
57-
58-
ifdef CONFIG_MITIGATION_RETPOLINE
59-
ifneq ($(RETPOLINE_VDSO_CFLAGS),)
60-
CFL += $(RETPOLINE_VDSO_CFLAGS)
61-
endif
62-
endif
63-
64-
$(vobjs): KBUILD_CFLAGS := $(filter-out $(PADDING_CFLAGS) $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) $(RANDSTRUCT_CFLAGS) $(KSTACK_ERASE_CFLAGS) $(GCC_PLUGINS_CFLAGS) $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
65-
$(vobjs): KBUILD_AFLAGS += -DBUILD_VDSO
66-
67-
#
68-
# vDSO code runs in userspace and -pg doesn't help with profiling anyway.
69-
#
70-
CFLAGS_REMOVE_vclock_gettime.o = -pg
71-
CFLAGS_REMOVE_vdso32/vclock_gettime.o = -pg
72-
CFLAGS_REMOVE_vgetcpu.o = -pg
73-
CFLAGS_REMOVE_vdso32/vgetcpu.o = -pg
74-
CFLAGS_REMOVE_vsgx.o = -pg
75-
CFLAGS_REMOVE_vgetrandom.o = -pg
76-
77-
#
78-
# X32 processes use x32 vDSO to access 64bit kernel data.
79-
#
80-
# Build x32 vDSO image:
81-
# 1. Compile x32 vDSO as 64bit.
82-
# 2. Convert object files to x32.
83-
# 3. Build x32 VDSO image with x32 objects, which contains 64bit codes
84-
# so that it can reach 64bit address space with 64bit pointers.
85-
#
86-
87-
CPPFLAGS_vdsox32.lds = $(CPPFLAGS_vdso.lds)
88-
VDSO_LDFLAGS_vdsox32.lds = -m elf32_x86_64 -soname linux-vdso.so.1 \
89-
-z max-page-size=4096
90-
91-
# x32-rebranded versions
92-
vobjx32s-y := $(vobjs-y:.o=-x32.o)
93-
94-
# same thing, but in the output directory
95-
vobjx32s := $(addprefix $(obj)/, $(vobjx32s-y))
96-
97-
# Convert 64bit object file to x32 for x32 vDSO.
98-
quiet_cmd_x32 = X32 $@
99-
cmd_x32 = $(OBJCOPY) -O elf32-x86-64 $< $@
100-
101-
$(obj)/%-x32.o: $(obj)/%.o FORCE
102-
$(call if_changed,x32)
103-
104-
targets += vdsox32.lds $(vobjx32s-y)
105-
106-
$(obj)/%.so: OBJCOPYFLAGS := -S --remove-section __ex_table
107-
$(obj)/%.so: $(obj)/%.so.dbg FORCE
108-
$(call if_changed,objcopy)
109-
110-
$(obj)/vdsox32.so.dbg: $(obj)/vdsox32.lds $(vobjx32s) FORCE
111-
$(call if_changed,vdso_and_check)
112-
113-
CPPFLAGS_vdso32/vdso32.lds = $(CPPFLAGS_vdso.lds)
114-
VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -soname linux-gate.so.1
115-
116-
KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS)) -DBUILD_VDSO
117-
$(obj)/vdso32.so.dbg: KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
118-
$(obj)/vdso32.so.dbg: asflags-$(CONFIG_X86_64) += -m32
119-
120-
KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
121-
KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32))
122-
KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
123-
KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
124-
KBUILD_CFLAGS_32 := $(filter-out $(RANDSTRUCT_CFLAGS),$(KBUILD_CFLAGS_32))
125-
KBUILD_CFLAGS_32 := $(filter-out $(KSTACK_ERASE_CFLAGS),$(KBUILD_CFLAGS_32))
126-
KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
127-
KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32))
128-
KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS_32))
129-
KBUILD_CFLAGS_32 := $(filter-out $(CC_FLAGS_CFI),$(KBUILD_CFLAGS_32))
130-
KBUILD_CFLAGS_32 := $(filter-out $(PADDING_CFLAGS),$(KBUILD_CFLAGS_32))
131-
KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
132-
KBUILD_CFLAGS_32 += -fno-stack-protector
133-
KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
134-
KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
135-
KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING
136-
KBUILD_CFLAGS_32 += -DBUILD_VDSO
137-
138-
ifdef CONFIG_MITIGATION_RETPOLINE
139-
ifneq ($(RETPOLINE_VDSO_CFLAGS),)
140-
KBUILD_CFLAGS_32 += $(RETPOLINE_VDSO_CFLAGS)
141-
endif
142-
endif
143-
144-
$(obj)/vdso32.so.dbg: KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
145-
146-
$(obj)/vdso32.so.dbg: $(obj)/vdso32/vdso32.lds $(vobjs32) FORCE
147-
$(call if_changed,vdso_and_check)
148-
149-
#
150-
# The DSO images are built using a special linker script.
151-
#
152-
quiet_cmd_vdso = VDSO $@
153-
cmd_vdso = $(LD) -o $@ \
154-
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
155-
-T $(filter %.lds,$^) $(filter %.o,$^)
156-
157-
VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 --no-undefined \
158-
$(call ld-option, --eh-frame-hdr) -Bsymbolic -z noexecstack
159-
160-
quiet_cmd_vdso_and_check = VDSO $@
161-
cmd_vdso_and_check = $(cmd_vdso); $(cmd_vdso_check)
10+
# vDSO directories
11+
obj-$(CONFIG_X86_64) += vdso64/
12+
obj-$(CONFIG_COMPAT_32) += vdso32/
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
#
3+
# Building vDSO images for x86.
4+
#
5+
6+
# Include the generic Makefile to check the built vDSO:
7+
include $(srctree)/lib/vdso/Makefile.include
8+
9+
obj-y += $(foreach x,$(vdsos-y),vdso$(x)-image.o)
10+
11+
targets += $(foreach x,$(vdsos-y),vdso$(x)-image.c vdso$(x).so vdso$(x).so.dbg vdso$(x).lds)
12+
targets += $(vobjs-y)
13+
14+
# vobjs-y with $(obj)/ prepended
15+
vobjs := $(addprefix $(obj)/,$(vobjs-y))
16+
17+
# Options for vdso*.lds
18+
CPPFLAGS_VDSO_LDS := -P -C -I$(src)/..
19+
$(obj)/%.lds : KBUILD_CPPFLAGS += $(CPPFLAGS_VDSO_LDS)
20+
21+
#
22+
# Options from KBUILD_[AC]FLAGS that should *NOT* be kept
23+
#
24+
flags-remove-y += \
25+
-D__KERNEL__ -mcmodel=kernel -mregparm=3 \
26+
-fno-pic -fno-PIC -fno-pie fno-PIE \
27+
-mfentry -pg \
28+
$(RANDSTRUCT_CFLAGS) $(GCC_PLUGIN_CFLAGS) $(KSTACK_ERASE_CFLAGS) \
29+
$(RETPOLINE_CFLAGS) $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \
30+
$(PADDING_CFLAGS)
31+
32+
#
33+
# Don't omit frame pointers for ease of userspace debugging, but do
34+
# optimize sibling calls.
35+
#
36+
flags-y += -D__DISABLE_EXPORTS
37+
flags-y += -DDISABLE_BRANCH_PROFILING
38+
flags-y += -DBUILD_VDSO
39+
flags-y += -I$(src)/.. -I$(srctree)
40+
flags-y += -O2 -fpic
41+
flags-y += -fno-stack-protector
42+
flags-y += -fno-omit-frame-pointer
43+
flags-y += -foptimize-sibling-calls
44+
flags-y += -fasynchronous-unwind-tables
45+
46+
# Reset cf protections enabled by compiler default
47+
flags-y += $(call cc-option, -fcf-protection=none)
48+
flags-$(X86_USER_SHADOW_STACK) += $(call cc-option, -fcf-protection=return)
49+
# When user space IBT is supported, enable this.
50+
# flags-$(CONFIG_USER_IBT) += $(call cc-option, -fcf-protection=branch)
51+
52+
flags-$(CONFIG_MITIGATION_RETPOLINE) += $(RETPOLINE_VDSO_CFLAGS)
53+
54+
# These need to be conditional on $(vobjs) as they do not apply to
55+
# the output vdso*-image.o files which are standard kernel objects.
56+
$(vobjs) : KBUILD_AFLAGS := \
57+
$(filter-out $(flags-remove-y),$(KBUILD_AFLAGS)) $(flags-y)
58+
$(vobjs) : KBUILD_CFLAGS := \
59+
$(filter-out $(flags-remove-y),$(KBUILD_CFLAGS)) $(flags-y)
60+
61+
#
62+
# The VDSO images are built using a special linker script.
63+
#
64+
VDSO_LDFLAGS := -shared --hash-style=both --build-id=sha1 --no-undefined \
65+
$(call ld-option, --eh-frame-hdr) -Bsymbolic -z noexecstack
66+
67+
quiet_cmd_vdso = VDSO $@
68+
cmd_vdso = $(LD) -o $@ \
69+
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$*) \
70+
-T $(filter %.lds,$^) $(filter %.o,$^)
71+
quiet_cmd_vdso_and_check = VDSO $@
72+
cmd_vdso_and_check = $(cmd_vdso); $(cmd_vdso_check)
73+
74+
$(obj)/vdso%.so.dbg: $(obj)/vdso%.lds FORCE
75+
$(call if_changed,vdso_and_check)
76+
77+
$(obj)/%.so: OBJCOPYFLAGS := -S --remove-section __ex_table
78+
$(obj)/%.so: $(obj)/%.so.dbg FORCE
79+
$(call if_changed,objcopy)
80+
81+
VDSO2C = $(objtree)/arch/x86/tools/vdso2c
82+
83+
quiet_cmd_vdso2c = VDSO2C $@
84+
cmd_vdso2c = $(VDSO2C) $< $(<:%.dbg=%) $@
85+
86+
$(obj)/%-image.c: $(obj)/%.so.dbg $(obj)/%.so $(VDSO2C) FORCE
87+
$(call if_changed,vdso2c)
88+
89+
$(obj)/%-image.o: $(obj)/%-image.c
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
12
/*
23
* This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
34
* Here we can supply some information useful to userland.
45
*/
56

67
#include <linux/build-salt.h>
7-
#include <linux/uts.h>
88
#include <linux/version.h>
99
#include <linux/elfnote.h>
1010

11+
/* Ideally this would use UTS_NAME, but using a quoted string here
12+
doesn't work. Remember to change this when changing the
13+
kernel's name. */
1114
ELFNOTE_START(Linux, 0, "a")
1215
.long LINUX_VERSION_CODE
1316
ELFNOTE_END
File renamed without changes.
File renamed without changes.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
#
3+
# 32-bit vDSO images for x86.
4+
#
5+
6+
# The vDSOs built in this directory
7+
vdsos-y := 32
8+
9+
# Files to link into the vDSO:
10+
vobjs-y := note.o vclock_gettime.o vgetcpu.o
11+
vobjs-y += system_call.o sigreturn.o
12+
13+
# Compilation flags
14+
flags-y := -DBUILD_VDSO32 -m32 -mregparm=0
15+
flags-$(CONFIG_X86_64) += -include $(src)/fake_32bit_build.h
16+
flags-remove-y := -m64
17+
18+
# The location of this include matters!
19+
include $(src)/../common/Makefile.include
20+
21+
# Linker options for the vdso
22+
VDSO_LDFLAGS_32 := -m elf_i386 -soname linux-gate.so.1
23+
24+
$(obj)/vdso32.so.dbg: $(vobjs)

arch/x86/entry/vdso/vdso32/note.S

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1 @@
1-
/* SPDX-License-Identifier: GPL-2.0 */
2-
/*
3-
* This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
4-
* Here we can supply some information useful to userland.
5-
*/
6-
7-
#include <linux/build-salt.h>
8-
#include <linux/version.h>
9-
#include <linux/elfnote.h>
10-
11-
/* Ideally this would use UTS_NAME, but using a quoted string here
12-
doesn't work. Remember to change this when changing the
13-
kernel's name. */
14-
ELFNOTE_START(Linux, 0, "a")
15-
.long LINUX_VERSION_CODE
16-
ELFNOTE_END
17-
18-
BUILD_SALT
1+
#include "common/note.S"

arch/x86/entry/vdso/vdso32/system_call.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ __kernel_vsyscall:
5252
#define SYSENTER_SEQUENCE "movl %esp, %ebp; sysenter"
5353
#define SYSCALL_SEQUENCE "movl %ecx, %ebp; syscall"
5454

55-
#ifdef CONFIG_X86_64
55+
#ifdef BUILD_VDSO32_64
5656
/* If SYSENTER (Intel) or SYSCALL32 (AMD) is available, use it. */
5757
ALTERNATIVE_2 "", SYSENTER_SEQUENCE, X86_FEATURE_SYSENTER32, \
5858
SYSCALL_SEQUENCE, X86_FEATURE_SYSCALL32
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
// SPDX-License-Identifier: GPL-2.0
2-
#define BUILD_VDSO32
3-
#include "fake_32bit_build.h"
4-
#include "../vclock_gettime.c"
1+
#include "common/vclock_gettime.c"

0 commit comments

Comments
 (0)