mirror of https://gitee.com/openkylin/linux.git
powerpc/vdso: Retrieve sigtramp offsets at buildtime
This is copied from arm64. Instead of using runtime generated signal trampoline offsets, get offsets at buildtime. If the said trampoline doesn't exist, build will fail. So no need to check whether the trampoline exists or not in the VDSO. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/f8bfd6812c3e3678b1cdb4d55a52f9eb022b40d3.1601197618.git.christophe.leroy@csgroup.eu
This commit is contained in:
parent
550e6074c1
commit
91bf695596
|
@ -409,6 +409,21 @@ install:
|
|||
archclean:
|
||||
$(Q)$(MAKE) $(clean)=$(boot)
|
||||
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
# We need to generate vdso-offsets.h before compiling certain files in kernel/.
|
||||
# In order to do that, we should use the archprepare target, but we can't since
|
||||
# asm-offsets.h is included in some files used to generate vdso-offsets.h, and
|
||||
# asm-offsets.h is built in prepare0, for which archprepare is a dependency.
|
||||
# Therefore we need to generate the header after prepare0 has been made, hence
|
||||
# this hack.
|
||||
prepare: vdso_prepare
|
||||
vdso_prepare: prepare0
|
||||
$(if $(CONFIG_VDSO32),$(Q)$(MAKE) \
|
||||
$(build)=arch/powerpc/kernel/vdso32 include/generated/vdso32-offsets.h)
|
||||
$(if $(CONFIG_PPC64),$(Q)$(MAKE) \
|
||||
$(build)=arch/powerpc/kernel/vdso64 include/generated/vdso64-offsets.h)
|
||||
endif
|
||||
|
||||
archprepare: checkbin
|
||||
|
||||
archheaders:
|
||||
|
|
|
@ -15,6 +15,18 @@
|
|||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#include <generated/vdso64-offsets.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VDSO32
|
||||
#include <generated/vdso32-offsets.h>
|
||||
#endif
|
||||
|
||||
#define VDSO64_SYMBOL(base, name) ((unsigned long)(base) + (vdso64_offset_##name))
|
||||
|
||||
#define VDSO32_SYMBOL(base, name) ((unsigned long)(base) + (vdso32_offset_##name))
|
||||
|
||||
/* Offsets relative to thread->vdso_base */
|
||||
extern unsigned long vdso64_rt_sigtramp;
|
||||
extern unsigned long vdso32_sigtramp;
|
||||
|
|
|
@ -801,8 +801,8 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
}
|
||||
|
||||
/* Save user registers on the stack */
|
||||
if (vdso32_rt_sigtramp && tsk->mm->context.vdso) {
|
||||
tramp = (unsigned long)tsk->mm->context.vdso + vdso32_rt_sigtramp;
|
||||
if (tsk->mm->context.vdso) {
|
||||
tramp = VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp_rt32);
|
||||
} else {
|
||||
tramp = (unsigned long)mctx->mc_pad;
|
||||
/* Set up the sigreturn trampoline: li r0,sigret; sc */
|
||||
|
@ -901,8 +901,8 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
else
|
||||
unsafe_save_user_regs(regs, mctx, tm_mctx, 1, failed);
|
||||
|
||||
if (vdso32_sigtramp && tsk->mm->context.vdso) {
|
||||
tramp = (unsigned long)tsk->mm->context.vdso + vdso32_sigtramp;
|
||||
if (tsk->mm->context.vdso) {
|
||||
tramp = VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp32);
|
||||
} else {
|
||||
tramp = (unsigned long)mctx->mc_pad;
|
||||
/* Set up the sigreturn trampoline: li r0,sigret; sc */
|
||||
|
|
|
@ -854,8 +854,8 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
|
|||
tsk->thread.fp_state.fpscr = 0;
|
||||
|
||||
/* Set up to return from userspace. */
|
||||
if (vdso64_rt_sigtramp && tsk->mm->context.vdso) {
|
||||
regs->nip = (unsigned long)tsk->mm->context.vdso + vdso64_rt_sigtramp;
|
||||
if (tsk->mm->context.vdso) {
|
||||
regs->nip = VDSO64_SYMBOL(tsk->mm->context.vdso, sigtramp_rt64);
|
||||
} else {
|
||||
err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
|
||||
if (err)
|
||||
|
|
|
@ -59,6 +59,14 @@ $(obj-vdso32): %.o: %.S FORCE
|
|||
$(obj)/vgettimeofday.o: %.o: %.c FORCE
|
||||
$(call if_changed_dep,vdso32cc)
|
||||
|
||||
# Generate VDSO offsets using helper script
|
||||
gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
|
||||
quiet_cmd_vdsosym = VDSOSYM $@
|
||||
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
|
||||
|
||||
include/generated/vdso32-offsets.h: $(obj)/vdso32.so.dbg FORCE
|
||||
$(call if_changed,vdsosym)
|
||||
|
||||
# actual build commands
|
||||
quiet_cmd_vdso32ld_and_check = VDSO32L $@
|
||||
cmd_vdso32ld_and_check = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) ; $(cmd_vdso_check)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#
|
||||
# Match symbols in the DSO that look like VDSO_*; produce a header file
|
||||
# of constant offsets into the shared object.
|
||||
#
|
||||
# Doing this inside the Makefile will break the $(filter-out) function,
|
||||
# causing Kbuild to rebuild the vdso-offsets header file every time.
|
||||
#
|
||||
# Author: Will Deacon <will.deacon@arm.com
|
||||
#
|
||||
|
||||
LC_ALL=C
|
||||
sed -n -e 's/^00*/0/' -e \
|
||||
's/^\([0-9a-fA-F]*\) . VDSO_\([a-zA-Z0-9_]*\)$/\#define vdso32_offset_\2\t0x\1/p'
|
|
@ -164,3 +164,9 @@ VERSION
|
|||
local: *;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the sigreturn code visible to the kernel.
|
||||
*/
|
||||
VDSO_sigtramp32 = __kernel_sigtramp32;
|
||||
VDSO_sigtramp_rt32 = __kernel_sigtramp_rt32;
|
||||
|
|
|
@ -42,6 +42,14 @@ $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so.dbg
|
|||
$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday.o FORCE
|
||||
$(call if_changed,vdso64ld_and_check)
|
||||
|
||||
# Generate VDSO offsets using helper script
|
||||
gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
|
||||
quiet_cmd_vdsosym = VDSOSYM $@
|
||||
cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
|
||||
|
||||
include/generated/vdso64-offsets.h: $(obj)/vdso64.so.dbg FORCE
|
||||
$(call if_changed,vdsosym)
|
||||
|
||||
# actual build commands
|
||||
quiet_cmd_vdso64ld_and_check = VDSO64L $@
|
||||
cmd_vdso64ld_and_check = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^); $(cmd_vdso_check)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#
|
||||
# Match symbols in the DSO that look like VDSO_*; produce a header file
|
||||
# of constant offsets into the shared object.
|
||||
#
|
||||
# Doing this inside the Makefile will break the $(filter-out) function,
|
||||
# causing Kbuild to rebuild the vdso-offsets header file every time.
|
||||
#
|
||||
# Author: Will Deacon <will.deacon@arm.com
|
||||
#
|
||||
|
||||
LC_ALL=C
|
||||
sed -n -e 's/^00*/0/' -e \
|
||||
's/^\([0-9a-fA-F]*\) . VDSO_\([a-zA-Z0-9_]*\)$/\#define vdso64_offset_\2\t0x\1/p'
|
|
@ -159,3 +159,8 @@ VERSION
|
|||
local: *;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the sigreturn code visible to the kernel.
|
||||
*/
|
||||
VDSO_sigtramp_rt64 = __kernel_sigtramp_rt64;
|
||||
|
|
|
@ -59,8 +59,8 @@ static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
|
|||
{
|
||||
if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
|
||||
return 1;
|
||||
if (vdso32_sigtramp && current->mm->context.vdso &&
|
||||
nip == (unsigned long)current->mm->context.vdso + vdso32_sigtramp)
|
||||
if (current->mm->context.vdso &&
|
||||
nip == VDSO32_SYMBOL(current->mm->context.vdso, sigtramp32))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp)
|
|||
if (nip == fp + offsetof(struct rt_signal_frame_32,
|
||||
uc.uc_mcontext.mc_pad))
|
||||
return 1;
|
||||
if (vdso32_rt_sigtramp && current->mm->context.vdso &&
|
||||
nip == (unsigned long)current->mm->context.vdso + vdso32_rt_sigtramp)
|
||||
if (current->mm->context.vdso &&
|
||||
nip == VDSO32_SYMBOL(current->mm->context.vdso, sigtramp_rt32))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -68,8 +68,8 @@ static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
|
|||
{
|
||||
if (nip == fp + offsetof(struct signal_frame_64, tramp))
|
||||
return 1;
|
||||
if (vdso64_rt_sigtramp && current->mm->context.vdso &&
|
||||
nip == (unsigned long)current->mm->context.vdso + vdso64_rt_sigtramp)
|
||||
if (current->mm->context.vdso &&
|
||||
nip == VDSO64_SYMBOL(current->mm->context.vdso, sigtramp_rt64))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue