Commit graph

7 commits

Author SHA1 Message Date
Alex Smith a7f4df4e21 MIPS: VDSO: Add implementations of gettimeofday() and clock_gettime()
Add user-mode implementations of gettimeofday() and clock_gettime() to
the VDSO. This is currently usable with 2 clocksources: the CP0 count
register, which is accessible to user-mode via RDHWR on R2 and later
cores, or the MIPS Global Interrupt Controller (GIC) timer, which
provides a "user-mode visible" section containing a mirror of its
counter registers. This section must be mapped into user memory, which
is done below the VDSO data page.

When a supported clocksource is not in use, the VDSO functions will
return -ENOSYS, which causes libc to fall back on the standard syscall
path.

When support for neither of these clocksources is compiled into the
kernel at all, the VDSO still provides clock_gettime(), as the coarse
realtime/monotonic clocks can still be implemented. However,
gettimeofday() is not provided in this case as nothing can be done
without a suitable clocksource. This causes the symbol lookup to fail
in libc and it will then always use the standard syscall path.

This patch includes a workaround for a bug in QEMU which results in
RDHWR on the CP0 count register always returning a constant (incorrect)
value. A fix for this has been submitted, and the workaround can be
removed after the fix has been in stable releases for a reasonable
amount of time.

A simple performance test which calls gettimeofday() 1000 times in a
loop and calculates the average execution time gives the following
results on a Malta + I6400 (running at 20MHz):

 - Syscall:    ~31000 ns
 - VDSO (GIC): ~15000 ns
 - VDSO (CP0): ~9500 ns

[markos.chandras@imgtec.com:
- Minor code re-arrangements in order for mappings to be made
in the order they appear to the process' address space.
- Move do_{monotonic, realtime} outside of the MIPS_CLOCK_VSYSCALL ifdef
- Use gic_get_usm_range so we can do the GIC mapping in the
arch/mips/kernel/vdso instead of the GIC irqchip driver]

Signed-off-by: Alex Smith <alex.smith@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/11338/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2015-11-11 08:36:41 +01:00
Alex Smith ebb5e78cc6 MIPS: Initial implementation of a VDSO
Add an initial implementation of a proper (i.e. an ELF shared library)
VDSO. With this commit it does not export any symbols, it only replaces
the current signal return trampoline page. A later commit will add user
implementations of gettimeofday()/clock_gettime().

To support both new toolchains and old ones which don't generate ABI
flags section, we define its content manually and then use a tool
(genvdso) to patch up the section to have the correct name and type.
genvdso also extracts symbol offsets ({,rt_}sigreturn) needed by the
kernel, and generates a C file containing a "struct mips_vdso_image"
containing both the VDSO data and these offsets. This C file is
compiled into the kernel.

On 64-bit kernels we require a different VDSO for each supported ABI,
so we may build up to 3 different VDSOs. The VDSO to use is selected by
the mips_abi structure.

A kernel/user shared data page is created and mapped below the VDSO
image. This is currently empty, but will be used by the user time
function implementations which are added later.

[markos.chandras@imgtec.com:
- Add more comments
- Move abi detection in genvdso.h since it's the get_symbol function
that needs it.
- Add an R6 specific way to calculate the base address of VDSO in order
to avoid the branch instruction which affects performance.
- Do not patch .gnu.attributes since it's not needed for dynamic linking.
- Simplify Makefile a little bit.
- checkpatch fixes
- Restrict VDSO support for binutils < 2.25 for pre-R6
- Include atomic64.h for O32 variant on MIPS64]

Signed-off-by: Alex Smith <alex.smith@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: Matthew Fortune <matthew.fortune@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/11337/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2015-11-11 08:36:36 +01:00
Prem Karat ccd3988086 MIPS: Enable VDSO randomization
Based on commit 1091458d09 (mmap randomization)

For 32-bit address spaces randomize within a
16MB space, for 64-bit within a 256MB space.

Test Results:
------------
Without Patch (VDSO is not randomized)
---------------------------------------
root@Maleo:~# ./aslr vdso
FAIL: ASLR not functional (vdso always at 0x7fff7000)

root@Maleo:~# ./aslr rekey vdso
pre_val==cur_val
value=0x7fff7000

With patch:(VDSO is randmoized and doesn't interfere with stack)
----------------------------------------------------------------
root@cavium-octeon2:~# ./aslr rekey vdso
pre_val!=cur_val
previous_value=0x7f830ea2
current_value=0x776e2000
root@cavium-octeon2:~# ./aslr rekey vdso
pre_val!=cur_val
previous_value=0x7fb0cea2
current_value=0x77209000
root@cavium-octeon2:~# ./aslr rekey vdso
pre_val!=cur_val
previous_value=0x7f985ea2
current_value=0x7770c000
root@cavium-octeon2:~# ./aslr rekey vdso
pre_val!=cur_val
previous_value=0x7fbc6ea2
current_value=0x7fe25000

Maps file output:
-------------------------
root@cavium-octeon2:~# ./aslr rekey maps
78584000-785a5000 rwxp 00000000 00:00 0                                  [heap]
7f9d0000-7f9f1000 rw-p 00000000 00:00 0                                  [stack]
7ffa5000-7ffa6000 r-xp 00000000 00:00 0                                  [vdso]

root@cavium-octeon2:~# ./aslr rekey maps
77de0000-77e01000 rwxp 00000000 00:00 0                                  [heap]
7f91b000-7f93c000 rw-p 00000000 00:00 0                                  [stack]
7ff99000-7ff9a000 r-xp 00000000 00:00 0                                  [vdso]

root@cavium-octeon2:~# ./aslr rekey maps
77d7f000-77da0000 rwxp 00000000 00:00 0                                  [heap]
7fc2a000-7fc4b000 rw-p 00000000 00:00 0                                  [stack]
7fe09000-7fe0a000 r-xp 00000000 00:00 0                                  [vdso]

root@cavium-octeon2:~# ./aslr rekey maps
7794c000-7794d000 r-xp 00000000 00:00 0                                  [vdso]
77e4b000-77e6c000 rwxp 00000000 00:00 0                                  [heap]
7f6e7000-7f708000 rw-p 00000000 00:00 0                                  [stack]
root@cavium-octeon2:~#

Signed-off-by: Prem Karat <pkarat@mvista.com>
Cc: linux-mips@linux-mips.org
Cc: sergei.shtylyov@cogentembedded.com
Cc: ddaney.cavm@gmail.com
Patchwork: https://patchwork.linux-mips.org/patch/6812
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2014-11-24 07:45:38 +01:00
Jason Baron 909af768e8 coredump: remove VM_ALWAYSDUMP flag
The motivation for this patchset was that I was looking at a way for a
qemu-kvm process, to exclude the guest memory from its core dump, which
can be quite large.  There are already a number of filter flags in
/proc/<pid>/coredump_filter, however, these allow one to specify 'types'
of kernel memory, not specific address ranges (which is needed in this
case).

Since there are no more vma flags available, the first patch eliminates
the need for the 'VM_ALWAYSDUMP' flag.  The flag is used internally by
the kernel to mark vdso and vsyscall pages.  However, it is simple
enough to check if a vma covers a vdso or vsyscall page without the need
for this flag.

The second patch then replaces the 'VM_ALWAYSDUMP' flag with a new
'VM_NODUMP' flag, which can be set by userspace using new madvise flags:
'MADV_DONTDUMP', and unset via 'MADV_DODUMP'.  The core dump filters
continue to work the same as before unless 'MADV_DONTDUMP' is set on the
region.

The qemu code which implements this features is at:

  http://people.redhat.com/~jbaron/qemu-dump/qemu-dump.patch

In my testing the qemu core dump shrunk from 383MB -> 13MB with this
patch.

I also believe that the 'MADV_DONTDUMP' flag might be useful for
security sensitive apps, which might want to select which areas are
dumped.

This patch:

The VM_ALWAYSDUMP flag is currently used by the coredump code to
indicate that a vma is part of a vsyscall or vdso section.  However, we
can determine if a vma is in one these sections by checking it against
the gate_vma and checking for a non-NULL return value from
arch_vma_name().  Thus, freeing a valuable vma bit.

Signed-off-by: Jason Baron <jbaron@redhat.com>
Acked-by: Roland McGrath <roland@hack.frob.com>
Cc: Chris Metcalf <cmetcalf@tilera.com>
Cc: Avi Kivity <avi@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2012-03-23 16:58:42 -07:00
David Daney 1ed845375b MIPS: Make init_vdso a subsys_initcall.
Quoting from Jiri Slaby's patch of a similar nature for x86:

    When initrd is in use and a driver does request_module() in its
    module_init (i.e. __initcall or device_initcall), a modprobe
    process is created with VDSO mapping. But VDSO is inited even in
    __initcall, i.e. on the same level (at the same time), so it may
    not be inited yet (link order matters).

Move init_vdso up to subsys_initcall to avoid the issue.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
Cc: David Daney <ddaney@caviumnetworks.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Patchwork: http://patchwork.linux-mips.org/patch/1386/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-07-26 19:08:16 +01:00
David Daney 57d15018aa MIPS: "Fix" useless 'init_vdso successfully' message.
In addition to being useless, it was mis-spelled.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
Cc: David Daney <ddaney@caviumnetworks.com>
Patchwork: http://patchwork.linux-mips.org/patch/1385/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-07-26 19:08:16 +01:00
David Daney c52d0d30ae MIPS: Preliminary VDSO
This is a preliminary patch to add a vdso to all user processes.  Still
missing are ELF headers and .eh_frame information.  But it is enough to
allow us to move signal trampolines off of the stack.  Note that emulation
of branch delay slots in the FPU emulator still requires the stack.

We allocate a single page (the vdso) and write all possible signal
trampolines into it.  The stack is moved down by one page and the vdso is
mapped into this space.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
Patchwork: http://patchwork.linux-mips.org/patch/975/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-04-12 17:26:14 +01:00