Generic way to track the landing vma area. As a bonus, after unmapping sigpage, kernel won't try to land on its previous position (due to UNMAPPED_VDSO_BASE check instead of context.vdso ?= 0 check). Cc: Thomas Bogendoerfer <tsbogend@xxxxxxxxxxxxxxxx> Cc: linux-mips@xxxxxxxxxxxxxxx Signed-off-by: Dmitry Safonov <dima@xxxxxxxxxx> --- arch/mips/Kconfig | 1 + arch/mips/include/asm/mmu.h | 2 -- arch/mips/kernel/signal.c | 11 +++++++---- arch/mips/kernel/vdso.c | 2 +- arch/mips/vdso/genvdso.c | 8 -------- 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 81096dd2c1ef..2bab0844f64b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -12,6 +12,7 @@ config MIPS select ARCH_HAS_SETUP_ADDITIONAL_PAGES select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_HAS_VDSO_BASE select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_KEEP_MEMBLOCK select ARCH_SUPPORTS_UPROBES diff --git a/arch/mips/include/asm/mmu.h b/arch/mips/include/asm/mmu.h index 5df0238f639b..928346a44eaf 100644 --- a/arch/mips/include/asm/mmu.h +++ b/arch/mips/include/asm/mmu.h @@ -12,8 +12,6 @@ typedef struct { atomic64_t mmid; }; - void *vdso; - /* lock to be held whilst modifying fp_bd_emupage_allocmap */ spinlock_t bd_emupage_lock; /* bitmap tracking allocation of fp_bd_emupage */ diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index f1e985109da0..e0beaf2cdc0f 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -806,11 +806,13 @@ struct mips_abi mips_abi = { static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { + void *land = (void *)current->mm->vdso_base; sigset_t *oldset = sigmask_to_save(); - int ret; + int ret = 1; struct mips_abi *abi = current->thread.abi; - void *vdso = current->mm->context.vdso; + if (land == (void *)UNMAPPED_VDSO_BASE) + goto err; /* * If we were emulating a delay slot instruction, exit that frame such * that addresses in the sigframe are as expected for userland and we @@ -843,12 +845,13 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) rseq_signal_deliver(ksig, regs); if (sig_uses_siginfo(&ksig->ka, abi)) - ret = abi->setup_rt_frame(vdso + abi->vdso->off_rt_sigreturn, + ret = abi->setup_rt_frame(land + abi->vdso->off_rt_sigreturn, ksig, regs, oldset); else - ret = abi->setup_frame(vdso + abi->vdso->off_sigreturn, + ret = abi->setup_frame(land + abi->vdso->off_sigreturn, ksig, regs, oldset); +err: signal_setup_done(ret, ksig, 0); } diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 9b2e1d2250b4..3f76417e5aed 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c @@ -184,7 +184,7 @@ int arch_setup_additional_pages(unsigned long *sysinfo_ehdr) goto out; } - mm->context.vdso = (void *)vdso_addr; + mm->vdso_base = (void __user *)vdso_addr; *sysinfo_ehdr = vdso_addr; ret = 0; diff --git a/arch/mips/vdso/genvdso.c b/arch/mips/vdso/genvdso.c index 0303d30cde03..8f581a2c8578 100644 --- a/arch/mips/vdso/genvdso.c +++ b/arch/mips/vdso/genvdso.c @@ -259,13 +259,6 @@ int main(int argc, char **argv) fprintf(out_file, "#include <linux/linkage.h>\n"); fprintf(out_file, "#include <linux/mm.h>\n"); fprintf(out_file, "#include <asm/vdso.h>\n"); - fprintf(out_file, "static void vdso_mremap(\n"); - fprintf(out_file, " const struct vm_special_mapping *sm,\n"); - fprintf(out_file, " struct vm_area_struct *new_vma)\n"); - fprintf(out_file, "{\n"); - fprintf(out_file, " current->mm->context.vdso =\n"); - fprintf(out_file, " (void *)(new_vma->vm_start);\n"); - fprintf(out_file, "}\n"); /* Write out the stripped VDSO data. */ fprintf(out_file, @@ -290,7 +283,6 @@ int main(int argc, char **argv) fprintf(out_file, "\t.mapping = {\n"); fprintf(out_file, "\t\t.name = \"[vdso]\",\n"); fprintf(out_file, "\t\t.pages = vdso_pages,\n"); - fprintf(out_file, "\t\t.mremap = vdso_mremap,\n"); fprintf(out_file, "\t},\n"); /* Calculate and write symbol offsets to <output file> */ -- 2.31.1