Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19f9a34f authored by Paul Mundt's avatar Paul Mundt
Browse files

sh: Initial vsyscall page support.



This implements initial support for the vsyscall page on SH.
At the moment we leave it configurable due to having nommu
to support from the same code base. We hook it up for the
signal trampoline return at present, with more to be added
later, once uClibc catches up.

Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 8c12b5dc
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
	io.o io_generic.o sh_ksyms.o syscalls.o

obj-y				+= cpu/ timers/
obj-$(CONFIG_VSYSCALL)		+= vsyscall/

obj-$(CONFIG_SMP)		+= smp.o
obj-$(CONFIG_CF_ENABLER)	+= cf-enabler.o
+1 −1
Original line number Diff line number Diff line
@@ -355,7 +355,7 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
	else if (next->thread.ubc_pc && next->mm) {
		int asid = 0;
#ifdef CONFIG_MMU
		asid |= next->mm->context & MMU_CONTEXT_ASID_MASK;
		asid |= next->mm->context.id & MMU_CONTEXT_ASID_MASK;
#endif
		ubc_set_tracing(asid, next->thread.ubc_pc);
	} else {
+14 −3
Original line number Diff line number Diff line
@@ -8,7 +8,6 @@
 *  SuperH version:  Copyright (C) 1999, 2000  Niibe Yutaka & Kaz Kojima
 *
 */

#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -21,6 +20,7 @@
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/elf.h>
#include <linux/personality.h>
#include <linux/binfmts.h>

@@ -29,8 +29,6 @@
#include <asm/pgtable.h>
#include <asm/cacheflush.h>

#undef DEBUG

#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))

/*
@@ -312,6 +310,11 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
	return (void __user *)((sp - frame_size) & -8ul);
}

/* These symbols are defined with the addresses in the vsyscall page.
   See vsyscall-trapa.S.  */
extern void __user __kernel_sigreturn;
extern void __user __kernel_rt_sigreturn;

static int setup_frame(int sig, struct k_sigaction *ka,
			sigset_t *set, struct pt_regs *regs)
{
@@ -340,6 +343,10 @@ static int setup_frame(int sig, struct k_sigaction *ka,
	   already in userspace.  */
	if (ka->sa.sa_flags & SA_RESTORER) {
		regs->pr = (unsigned long) ka->sa.sa_restorer;
#ifdef CONFIG_VSYSCALL
	} else if (likely(current->mm->context.vdso)) {
		regs->pr = VDSO_SYM(&__kernel_sigreturn);
#endif
	} else {
		/* Generate return code (system call to sigreturn) */
		err |= __put_user(MOVW(7), &frame->retcode[0]);
@@ -416,6 +423,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
	   already in userspace.  */
	if (ka->sa.sa_flags & SA_RESTORER) {
		regs->pr = (unsigned long) ka->sa.sa_restorer;
#ifdef CONFIG_VSYSCALL
	} else if (likely(current->mm->context.vdso)) {
		regs->pr = VDSO_SYM(&__kernel_rt_sigreturn);
#endif
	} else {
		/* Generate return code (system call to rt_sigreturn) */
		err |= __put_user(MOVW(7), &frame->retcode[0]);
+36 −0
Original line number Diff line number Diff line
obj-y += vsyscall.o vsyscall-syscall.o

$(obj)/vsyscall-syscall.o: \
	$(foreach F,trapa,$(obj)/vsyscall-$F.so)

# Teach kbuild about targets
targets += $(foreach F,trapa,vsyscall-$F.o vsyscall-$F.so)
targets += vsyscall-note.o vsyscall.lds

# The DSO images are built using a special linker script
quiet_cmd_syscall = SYSCALL $@
      cmd_syscall = $(CC) -nostdlib $(SYSCFLAGS_$(@F)) \
			   -Wl,-T,$(filter-out FORCE,$^) -o $@

export CPPFLAGS_vsyscall.lds += -P -C -Ush

vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
		$(call ld-option, -Wl$(comma)--hash-style=sysv)

SYSCFLAGS_vsyscall-trapa.so	= $(vsyscall-flags)

$(obj)/vsyscall-trapa.so: \
$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
	$(call if_changed,syscall)

# We also create a special relocatable object that should mirror the symbol
# table and layout of the linked DSO.  With ld -R we can then refer to
# these symbols in the kernel code rather than hand-coded addresses.
extra-y += vsyscall-syms.o
$(obj)/built-in.o: $(obj)/vsyscall-syms.o
$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o

SYSCFLAGS_vsyscall-syms.o = -r
$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
			$(obj)/vsyscall-trapa.o $(obj)/vsyscall-note.o FORCE
	$(call if_changed,syscall)
+25 −0
Original line number Diff line number Diff line
/*
 * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
 * Here we can supply some information useful to userland.
 */

#include <linux/uts.h>
#include <linux/version.h>

#define ASM_ELF_NOTE_BEGIN(name, flags, vendor, type)			      \
	.section name, flags;						      \
	.balign 4;							      \
	.long 1f - 0f;		/* name length */			      \
	.long 3f - 2f;		/* data length */			      \
	.long type;		/* note type */				      \
0:	.asciz vendor;		/* vendor name */			      \
1:	.balign 4;							      \
2:

#define ASM_ELF_NOTE_END						      \
3:	.balign 4;		/* pad out section */			      \
	.previous

	ASM_ELF_NOTE_BEGIN(".note.kernel-version", "a", UTS_SYSNAME, 0)
	.long LINUX_VERSION_CODE
	ASM_ELF_NOTE_END
Loading