2019-05-27 08:55:01 +02:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2015-10-21 09:54:38 +01:00
/ *
* Copyright ( C ) 2 0 1 5 I m a g i n a t i o n T e c h n o l o g i e s
* Author : Alex S m i t h < a l e x . s m i t h @imgtec.com>
* /
# include < a s m / s g i d e f s . h >
# if _ M I P S _ S I M = = _ M I P S _ S I M _ A B I 6 4
OUTPUT_ F O R M A T ( " e l f64 - t r a d l i t t l e m i p s " , " e l f64 - t r a d b i g m i p s " , " e l f64 - t r a d l i t t l e m i p s " )
# elif _ M I P S _ S I M = = _ M I P S _ S I M _ N A B I 3 2
OUTPUT_ F O R M A T ( " e l f32 - n t r a d l i t t l e m i p s " , " e l f32 - n t r a d b i g m i p s " , " e l f32 - n t r a d l i t t l e m i p s " )
# else
OUTPUT_ F O R M A T ( " e l f32 - t r a d l i t t l e m i p s " , " e l f32 - t r a d b i g m i p s " , " e l f32 - t r a d l i t t l e m i p s " )
# endif
OUTPUT_ A R C H ( m i p s )
SECTIONS
{
PROVIDE( _ s t a r t = . ) ;
. = SIZEOF_ H E A D E R S ;
/ *
* In o r d e r t o r e t a i n c o m p a t i b i l i t y w i t h o l d e r t o o l c h a i n s w e p r o v i d e t h e
* ABI f l a g s s e c t i o n o u r s e l f . N e w e r a s s e m b l e r s w i l l a u t o m a t i c a l l y
* generate . M I P S . a b i f l a g s s e c t i o n s s o w e d i s c a r d s u c h i n p u t s e c t i o n s ,
* and t h e n m a n u a l l y d e f i n e o u r o w n s e c t i o n h e r e . g e n v d s o w i l l p a t c h
* this s e c t i o n t o h a v e t h e c o r r e c t n a m e / t y p e .
* /
.mips_abiflags : { * ( .mips_abiflags ) } : text : a b i f l a g s
.reginfo : { * ( .reginfo ) } : text : r e g i n f o
.hash : { * ( .hash ) } : text
.gnu .hash : { * ( .gnu .hash ) }
.dynsym : { * ( .dynsym ) }
.dynstr : { * ( .dynstr ) }
.gnu .version : { * ( .gnu .version ) }
.gnu .version_d : { * ( .gnu .version_d ) }
.gnu .version_r : { * ( .gnu .version_r ) }
.note : { * ( .note . * ) } : text : n o t e
.text : { * ( .text * ) } : text
PROVIDE ( _ _ e t e x t = . ) ;
PROVIDE ( _ e t e x t = . ) ;
PROVIDE ( e t e x t = . ) ;
.eh_frame_hdr : { * ( .eh_frame_hdr ) } : text : e h _ f r a m e _ h d r
.eh_frame : { KEEP ( * ( . e h _ f r a m e ) ) } : t e x t
.dynamic : { * ( .dynamic ) } : text : d y n a m i c
.rodata : { * ( .rodata * ) } : text
_ end = . ;
PROVIDE( e n d = . ) ;
/ DISCARD/ : {
* ( .MIPS .abiflags )
* ( .gnu .attributes )
* ( .note .GNU - stack)
* ( .data .data . * .gnu .linkonce .d . * .sdata * )
* ( .bss .sbss .dynbss .dynsbss )
}
}
PHDRS
{
/ *
* Provide a P T _ M I P S _ A B I F L A G S h e a d e r t o a s s i g n t h e A B I f l a g s s e c t i o n
* to. W e c a n s p e c i f y t h e h e a d e r t y p e d i r e c t l y h e r e s o n o m o d i f i c a t i o n
* is n e e d e d l a t e r o n .
* /
abiflags 0 x70 0 0 0 0 0 3 ;
/ *
* The A B I f l a g s h e a d e r m u s t e x i s t d i r e c t l y a f t e r t h e P T _ I N T E R P h e a d e r ,
* so w e m u s t e x p l i c i t l y p l a c e t h e P T _ M I P S _ R E G I N F O h e a d e r a f t e r i t t o
* stop t h e l i n k e r p u t t i n g o n e i n a t t h e s t a r t .
* /
reginfo 0 x70 0 0 0 0 0 0 ;
text P T _ L O A D F L A G S ( 5 ) F I L E H D R P H D R S ; /* PF_R|PF_X */
dynamic P T _ D Y N A M I C F L A G S ( 4 ) ; /* PF_R */
note P T _ N O T E F L A G S ( 4 ) ; /* PF_R */
eh_ f r a m e _ h d r P T _ G N U _ E H _ F R A M E ;
}
VERSION
{
LINUX_ 2 . 6 {
2020-04-28 15:14:16 -07:00
# ifndef C O N F I G _ M I P S _ D I S A B L E _ V D S O
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-10-21 09:57:44 +01:00
global :
_ _ vdso_ c l o c k _ g e t t i m e ;
_ _ vdso_ g e t t i m e o f d a y ;
2019-06-21 10:52:47 +01:00
_ _ vdso_ c l o c k _ g e t r e s ;
2019-06-21 10:52:48 +01:00
# if _ M I P S _ S I M ! = _ M I P S _ S I M _ A B I 6 4
_ _ vdso_ c l o c k _ g e t t i m e 6 4 ;
# endif
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-10-21 09:57:44 +01:00
# endif
2015-10-21 09:54:38 +01:00
local : * ;
} ;
}