2005-04-17 02:20:36 +04:00
/ *
* linux/ a r c h / a r m / l i b / g e t u s e r . S
*
* Copyright ( C ) 2 0 0 1 R u s s e l l K i n g
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e v e r s i o n 2 a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n .
*
* Idea f r o m x86 v e r s i o n , ( C ) C o p y r i g h t 1 9 9 8 L i n u s T o r v a l d s
*
* These f u n c t i o n s h a v e a n o n - s t a n d a r d c a l l i n t e r f a c e t o m a k e t h e m m o r e
* efficient, e s p e c i a l l y a s t h e y r e t u r n a n e r r o r v a l u e i n a d d i t i o n t o
* the " r e a l " r e t u r n v a l u e .
*
* _ _ get_ u s e r _ X
*
* Inputs : r0 c o n t a i n s t h e a d d r e s s
2012-09-07 21:22:28 +04:00
* r1 c o n t a i n s t h e a d d r e s s l i m i t , w h i c h m u s t b e p r e s e r v e d
2005-04-17 02:20:36 +04:00
* Outputs : r0 i s t h e e r r o r c o d e
ARM: 8091/2: add get_user() support for 8 byte types
Recent contributions, including to DRM and binder, introduce 64-bit
values in their interfaces. A common motivation for this is to allow
the same ABI for 32- and 64-bit userspaces (and therefore also a shared
ABI for 32/64 hybrid userspaces). Anyhow, the developers would like to
avoid gotchas like having to use copy_from_user().
This feature is already implemented on x86-32 and the majority of other
32-bit architectures. The current list of get_user_8 hold out
architectures are: arm, avr32, blackfin, m32r, metag, microblaze,
mn10300, sh.
Credit:
My name sits rather uneasily at the top of this patch. The v1 and
v2 versions of the patch were written by Rob Clark and to produce v4
I mostly copied code from Russell King and H. Peter Anvin. However I
have mangled the patch sufficiently that *blame* is rightfully mine
even if credit should more widely shared.
Changelog:
v5: updated to use the ret macro (requested by Russell King)
v4: remove an inlined add on big endian systems (spotted by Russell King),
used __ARMEB__ rather than BIG_ENDIAN (to match rest of file),
cleared r3 on EFAULT during __get_user_8.
v3: fix a couple of checkpatch issues
v2: pass correct size to check_uaccess, and better handling of narrowing
double word read with __get_user_xb() (Russell King's suggestion)
v1: original
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-10 23:58:08 +04:00
* r2 , r3 c o n t a i n s t h e z e r o - e x t e n d e d v a l u e
2005-04-17 02:20:36 +04:00
* lr c o r r u p t e d
*
2008-08-02 13:55:55 +04:00
* No o t h e r r e g i s t e r s m u s t b e a l t e r e d . ( s e e < a s m / u a c c e s s . h >
2005-04-17 02:20:36 +04:00
* for s p e c i f i c A S M r e g i s t e r u s a g e ) .
*
* Note t h a t A D D R _ L I M I T i s e i t h e r 0 o r 0 x c00 0 0 0 0 0 .
* Note a l s o t h a t i t i s i n t e n d e d t h a t _ _ g e t _ u s e r _ b a d i s n o t g l o b a l .
* /
2008-08-28 14:22:32 +04:00
# include < l i n u x / l i n k a g e . h >
2012-09-07 21:22:28 +04:00
# include < a s m / a s s e m b l e r . h >
2005-04-17 02:20:36 +04:00
# include < a s m / e r r n o . h >
2010-09-13 19:03:21 +04:00
# include < a s m / d o m a i n . h >
2005-04-17 02:20:36 +04:00
2008-08-28 14:22:32 +04:00
ENTRY( _ _ g e t _ u s e r _ 1 )
2012-09-07 21:22:28 +04:00
check_ u a c c e s s r0 , 1 , r1 , r2 , _ _ g e t _ u s e r _ b a d
2012-01-25 14:38:13 +04:00
1 : TUSER( l d r b ) r2 , [ r0 ]
2005-04-17 02:20:36 +04:00
mov r0 , #0
2014-06-30 19:29:12 +04:00
ret l r
2008-08-28 14:22:32 +04:00
ENDPROC( _ _ g e t _ u s e r _ 1 )
2018-05-13 07:04:29 +03:00
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ 1 )
2005-04-17 02:20:36 +04:00
2008-08-28 14:22:32 +04:00
ENTRY( _ _ g e t _ u s e r _ 2 )
2012-09-07 21:22:28 +04:00
check_ u a c c e s s r0 , 2 , r1 , r2 , _ _ g e t _ u s e r _ b a d
# ifdef C O N F I G _ C P U _ U S E _ D O M A I N S
rb . r e q i p
2 : ldrbt r2 , [ r0 ] , #1
3 : ldrbt r b , [ r0 ] , #0
2009-07-24 15:32:57 +04:00
# else
2012-09-07 21:22:28 +04:00
rb . r e q r0
2 : ldrb r2 , [ r0 ]
3 : ldrb r b , [ r0 , #1 ]
2009-07-24 15:32:57 +04:00
# endif
2005-04-17 02:20:36 +04:00
# ifndef _ _ A R M E B _ _
2012-09-07 21:22:28 +04:00
orr r2 , r2 , r b , l s l #8
2005-04-17 02:20:36 +04:00
# else
2012-09-07 21:22:28 +04:00
orr r2 , r b , r2 , l s l #8
2005-04-17 02:20:36 +04:00
# endif
mov r0 , #0
2014-06-30 19:29:12 +04:00
ret l r
2008-08-28 14:22:32 +04:00
ENDPROC( _ _ g e t _ u s e r _ 2 )
2018-05-13 07:04:29 +03:00
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ 2 )
2005-04-17 02:20:36 +04:00
2008-08-28 14:22:32 +04:00
ENTRY( _ _ g e t _ u s e r _ 4 )
2012-09-07 21:22:28 +04:00
check_ u a c c e s s r0 , 4 , r1 , r2 , _ _ g e t _ u s e r _ b a d
2012-01-25 14:38:13 +04:00
4 : TUSER( l d r ) r2 , [ r0 ]
2005-04-17 02:20:36 +04:00
mov r0 , #0
2014-06-30 19:29:12 +04:00
ret l r
2008-08-28 14:22:32 +04:00
ENDPROC( _ _ g e t _ u s e r _ 4 )
2018-05-13 07:04:29 +03:00
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ 4 )
2005-04-17 02:20:36 +04:00
ARM: 8091/2: add get_user() support for 8 byte types
Recent contributions, including to DRM and binder, introduce 64-bit
values in their interfaces. A common motivation for this is to allow
the same ABI for 32- and 64-bit userspaces (and therefore also a shared
ABI for 32/64 hybrid userspaces). Anyhow, the developers would like to
avoid gotchas like having to use copy_from_user().
This feature is already implemented on x86-32 and the majority of other
32-bit architectures. The current list of get_user_8 hold out
architectures are: arm, avr32, blackfin, m32r, metag, microblaze,
mn10300, sh.
Credit:
My name sits rather uneasily at the top of this patch. The v1 and
v2 versions of the patch were written by Rob Clark and to produce v4
I mostly copied code from Russell King and H. Peter Anvin. However I
have mangled the patch sufficiently that *blame* is rightfully mine
even if credit should more widely shared.
Changelog:
v5: updated to use the ret macro (requested by Russell King)
v4: remove an inlined add on big endian systems (spotted by Russell King),
used __ARMEB__ rather than BIG_ENDIAN (to match rest of file),
cleared r3 on EFAULT during __get_user_8.
v3: fix a couple of checkpatch issues
v2: pass correct size to check_uaccess, and better handling of narrowing
double word read with __get_user_xb() (Russell King's suggestion)
v1: original
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-10 23:58:08 +04:00
ENTRY( _ _ g e t _ u s e r _ 8 )
2017-02-16 03:44:37 +03:00
check_ u a c c e s s r0 , 8 , r1 , r2 , _ _ g e t _ u s e r _ b a d8
ARM: 8091/2: add get_user() support for 8 byte types
Recent contributions, including to DRM and binder, introduce 64-bit
values in their interfaces. A common motivation for this is to allow
the same ABI for 32- and 64-bit userspaces (and therefore also a shared
ABI for 32/64 hybrid userspaces). Anyhow, the developers would like to
avoid gotchas like having to use copy_from_user().
This feature is already implemented on x86-32 and the majority of other
32-bit architectures. The current list of get_user_8 hold out
architectures are: arm, avr32, blackfin, m32r, metag, microblaze,
mn10300, sh.
Credit:
My name sits rather uneasily at the top of this patch. The v1 and
v2 versions of the patch were written by Rob Clark and to produce v4
I mostly copied code from Russell King and H. Peter Anvin. However I
have mangled the patch sufficiently that *blame* is rightfully mine
even if credit should more widely shared.
Changelog:
v5: updated to use the ret macro (requested by Russell King)
v4: remove an inlined add on big endian systems (spotted by Russell King),
used __ARMEB__ rather than BIG_ENDIAN (to match rest of file),
cleared r3 on EFAULT during __get_user_8.
v3: fix a couple of checkpatch issues
v2: pass correct size to check_uaccess, and better handling of narrowing
double word read with __get_user_xb() (Russell King's suggestion)
v1: original
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-10 23:58:08 +04:00
# ifdef C O N F I G _ T H U M B 2 _ K E R N E L
5 : TUSER( l d r ) r2 , [ r0 ]
6 : TUSER( l d r ) r3 , [ r0 , #4 ]
# else
5 : TUSER( l d r ) r2 , [ r0 ] , #4
6 : TUSER( l d r ) r3 , [ r0 ]
# endif
mov r0 , #0
ret l r
ENDPROC( _ _ g e t _ u s e r _ 8 )
2018-05-13 07:04:29 +03:00
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ 8 )
ARM: 8091/2: add get_user() support for 8 byte types
Recent contributions, including to DRM and binder, introduce 64-bit
values in their interfaces. A common motivation for this is to allow
the same ABI for 32- and 64-bit userspaces (and therefore also a shared
ABI for 32/64 hybrid userspaces). Anyhow, the developers would like to
avoid gotchas like having to use copy_from_user().
This feature is already implemented on x86-32 and the majority of other
32-bit architectures. The current list of get_user_8 hold out
architectures are: arm, avr32, blackfin, m32r, metag, microblaze,
mn10300, sh.
Credit:
My name sits rather uneasily at the top of this patch. The v1 and
v2 versions of the patch were written by Rob Clark and to produce v4
I mostly copied code from Russell King and H. Peter Anvin. However I
have mangled the patch sufficiently that *blame* is rightfully mine
even if credit should more widely shared.
Changelog:
v5: updated to use the ret macro (requested by Russell King)
v4: remove an inlined add on big endian systems (spotted by Russell King),
used __ARMEB__ rather than BIG_ENDIAN (to match rest of file),
cleared r3 on EFAULT during __get_user_8.
v3: fix a couple of checkpatch issues
v2: pass correct size to check_uaccess, and better handling of narrowing
double word read with __get_user_xb() (Russell King's suggestion)
v1: original
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-10 23:58:08 +04:00
# ifdef _ _ A R M E B _ _
2014-09-04 09:07:33 +04:00
ENTRY( _ _ g e t _ u s e r _ 3 2 t _ 8 )
ARM: 8091/2: add get_user() support for 8 byte types
Recent contributions, including to DRM and binder, introduce 64-bit
values in their interfaces. A common motivation for this is to allow
the same ABI for 32- and 64-bit userspaces (and therefore also a shared
ABI for 32/64 hybrid userspaces). Anyhow, the developers would like to
avoid gotchas like having to use copy_from_user().
This feature is already implemented on x86-32 and the majority of other
32-bit architectures. The current list of get_user_8 hold out
architectures are: arm, avr32, blackfin, m32r, metag, microblaze,
mn10300, sh.
Credit:
My name sits rather uneasily at the top of this patch. The v1 and
v2 versions of the patch were written by Rob Clark and to produce v4
I mostly copied code from Russell King and H. Peter Anvin. However I
have mangled the patch sufficiently that *blame* is rightfully mine
even if credit should more widely shared.
Changelog:
v5: updated to use the ret macro (requested by Russell King)
v4: remove an inlined add on big endian systems (spotted by Russell King),
used __ARMEB__ rather than BIG_ENDIAN (to match rest of file),
cleared r3 on EFAULT during __get_user_8.
v3: fix a couple of checkpatch issues
v2: pass correct size to check_uaccess, and better handling of narrowing
double word read with __get_user_xb() (Russell King's suggestion)
v1: original
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-10 23:58:08 +04:00
check_ u a c c e s s r0 , 8 , r1 , r2 , _ _ g e t _ u s e r _ b a d
# ifdef C O N F I G _ C P U _ U S E _ D O M A I N S
add r0 , r0 , #4
7 : ldrt r2 , [ r0 ]
# else
7 : ldr r2 , [ r0 , #4 ]
# endif
mov r0 , #0
ret l r
2014-09-04 09:07:33 +04:00
ENDPROC( _ _ g e t _ u s e r _ 3 2 t _ 8 )
2018-05-13 07:04:29 +03:00
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ 3 2 t _ 8 )
2014-09-04 09:07:33 +04:00
ENTRY( _ _ g e t _ u s e r _ 6 4 t _ 1 )
check_ u a c c e s s r0 , 1 , r1 , r2 , _ _ g e t _ u s e r _ b a d8
8 : TUSER( l d r b ) r3 , [ r0 ]
mov r0 , #0
ret l r
ENDPROC( _ _ g e t _ u s e r _ 6 4 t _ 1 )
2018-05-13 07:04:29 +03:00
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ 6 4 t _ 1 )
2014-09-04 09:07:33 +04:00
ENTRY( _ _ g e t _ u s e r _ 6 4 t _ 2 )
check_ u a c c e s s r0 , 2 , r1 , r2 , _ _ g e t _ u s e r _ b a d8
# ifdef C O N F I G _ C P U _ U S E _ D O M A I N S
rb . r e q i p
9 : ldrbt r3 , [ r0 ] , #1
10 : ldrbt r b , [ r0 ] , #0
# else
rb . r e q r0
9 : ldrb r3 , [ r0 ]
10 : ldrb r b , [ r0 , #1 ]
# endif
orr r3 , r b , r3 , l s l #8
mov r0 , #0
ret l r
ENDPROC( _ _ g e t _ u s e r _ 6 4 t _ 2 )
2018-05-13 07:04:29 +03:00
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ 6 4 t _ 2 )
2014-09-04 09:07:33 +04:00
ENTRY( _ _ g e t _ u s e r _ 6 4 t _ 4 )
check_ u a c c e s s r0 , 4 , r1 , r2 , _ _ g e t _ u s e r _ b a d8
11 : TUSER( l d r ) r3 , [ r0 ]
mov r0 , #0
ret l r
ENDPROC( _ _ g e t _ u s e r _ 6 4 t _ 4 )
2018-05-13 07:04:29 +03:00
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ 6 4 t _ 4 )
ARM: 8091/2: add get_user() support for 8 byte types
Recent contributions, including to DRM and binder, introduce 64-bit
values in their interfaces. A common motivation for this is to allow
the same ABI for 32- and 64-bit userspaces (and therefore also a shared
ABI for 32/64 hybrid userspaces). Anyhow, the developers would like to
avoid gotchas like having to use copy_from_user().
This feature is already implemented on x86-32 and the majority of other
32-bit architectures. The current list of get_user_8 hold out
architectures are: arm, avr32, blackfin, m32r, metag, microblaze,
mn10300, sh.
Credit:
My name sits rather uneasily at the top of this patch. The v1 and
v2 versions of the patch were written by Rob Clark and to produce v4
I mostly copied code from Russell King and H. Peter Anvin. However I
have mangled the patch sufficiently that *blame* is rightfully mine
even if credit should more widely shared.
Changelog:
v5: updated to use the ret macro (requested by Russell King)
v4: remove an inlined add on big endian systems (spotted by Russell King),
used __ARMEB__ rather than BIG_ENDIAN (to match rest of file),
cleared r3 on EFAULT during __get_user_8.
v3: fix a couple of checkpatch issues
v2: pass correct size to check_uaccess, and better handling of narrowing
double word read with __get_user_xb() (Russell King's suggestion)
v1: original
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-10 23:58:08 +04:00
# endif
__get_user_bad8 :
mov r3 , #0
2005-04-17 02:20:36 +04:00
__get_user_bad :
mov r2 , #0
mov r0 , #- E F A U L T
2014-06-30 19:29:12 +04:00
ret l r
2008-08-28 14:22:32 +04:00
ENDPROC( _ _ g e t _ u s e r _ b a d )
ARM: 8091/2: add get_user() support for 8 byte types
Recent contributions, including to DRM and binder, introduce 64-bit
values in their interfaces. A common motivation for this is to allow
the same ABI for 32- and 64-bit userspaces (and therefore also a shared
ABI for 32/64 hybrid userspaces). Anyhow, the developers would like to
avoid gotchas like having to use copy_from_user().
This feature is already implemented on x86-32 and the majority of other
32-bit architectures. The current list of get_user_8 hold out
architectures are: arm, avr32, blackfin, m32r, metag, microblaze,
mn10300, sh.
Credit:
My name sits rather uneasily at the top of this patch. The v1 and
v2 versions of the patch were written by Rob Clark and to produce v4
I mostly copied code from Russell King and H. Peter Anvin. However I
have mangled the patch sufficiently that *blame* is rightfully mine
even if credit should more widely shared.
Changelog:
v5: updated to use the ret macro (requested by Russell King)
v4: remove an inlined add on big endian systems (spotted by Russell King),
used __ARMEB__ rather than BIG_ENDIAN (to match rest of file),
cleared r3 on EFAULT during __get_user_8.
v3: fix a couple of checkpatch issues
v2: pass correct size to check_uaccess, and better handling of narrowing
double word read with __get_user_xb() (Russell King's suggestion)
v1: original
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-10 23:58:08 +04:00
ENDPROC( _ _ g e t _ u s e r _ b a d8 )
2018-05-13 07:04:29 +03:00
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ b a d )
_ ASM_ N O K P R O B E ( _ _ g e t _ u s e r _ b a d8 )
2005-04-17 02:20:36 +04:00
2010-04-19 13:15:03 +04:00
.pushsection _ _ ex_ t a b l e , " a "
2005-04-17 02:20:36 +04:00
.long 1 b, _ _ g e t _ u s e r _ b a d
.long 2 b, _ _ g e t _ u s e r _ b a d
.long 3 b, _ _ g e t _ u s e r _ b a d
.long 4 b, _ _ g e t _ u s e r _ b a d
ARM: 8091/2: add get_user() support for 8 byte types
Recent contributions, including to DRM and binder, introduce 64-bit
values in their interfaces. A common motivation for this is to allow
the same ABI for 32- and 64-bit userspaces (and therefore also a shared
ABI for 32/64 hybrid userspaces). Anyhow, the developers would like to
avoid gotchas like having to use copy_from_user().
This feature is already implemented on x86-32 and the majority of other
32-bit architectures. The current list of get_user_8 hold out
architectures are: arm, avr32, blackfin, m32r, metag, microblaze,
mn10300, sh.
Credit:
My name sits rather uneasily at the top of this patch. The v1 and
v2 versions of the patch were written by Rob Clark and to produce v4
I mostly copied code from Russell King and H. Peter Anvin. However I
have mangled the patch sufficiently that *blame* is rightfully mine
even if credit should more widely shared.
Changelog:
v5: updated to use the ret macro (requested by Russell King)
v4: remove an inlined add on big endian systems (spotted by Russell King),
used __ARMEB__ rather than BIG_ENDIAN (to match rest of file),
cleared r3 on EFAULT during __get_user_8.
v3: fix a couple of checkpatch issues
v2: pass correct size to check_uaccess, and better handling of narrowing
double word read with __get_user_xb() (Russell King's suggestion)
v1: original
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-10 23:58:08 +04:00
.long 5 b, _ _ g e t _ u s e r _ b a d8
.long 6 b, _ _ g e t _ u s e r _ b a d8
# ifdef _ _ A R M E B _ _
.long 7 b, _ _ g e t _ u s e r _ b a d
2014-09-04 09:07:33 +04:00
.long 8 b, _ _ g e t _ u s e r _ b a d8
.long 9 b, _ _ g e t _ u s e r _ b a d8
.long 1 0 b, _ _ g e t _ u s e r _ b a d8
.long 1 1 b, _ _ g e t _ u s e r _ b a d8
ARM: 8091/2: add get_user() support for 8 byte types
Recent contributions, including to DRM and binder, introduce 64-bit
values in their interfaces. A common motivation for this is to allow
the same ABI for 32- and 64-bit userspaces (and therefore also a shared
ABI for 32/64 hybrid userspaces). Anyhow, the developers would like to
avoid gotchas like having to use copy_from_user().
This feature is already implemented on x86-32 and the majority of other
32-bit architectures. The current list of get_user_8 hold out
architectures are: arm, avr32, blackfin, m32r, metag, microblaze,
mn10300, sh.
Credit:
My name sits rather uneasily at the top of this patch. The v1 and
v2 versions of the patch were written by Rob Clark and to produce v4
I mostly copied code from Russell King and H. Peter Anvin. However I
have mangled the patch sufficiently that *blame* is rightfully mine
even if credit should more widely shared.
Changelog:
v5: updated to use the ret macro (requested by Russell King)
v4: remove an inlined add on big endian systems (spotted by Russell King),
used __ARMEB__ rather than BIG_ENDIAN (to match rest of file),
cleared r3 on EFAULT during __get_user_8.
v3: fix a couple of checkpatch issues
v2: pass correct size to check_uaccess, and better handling of narrowing
double word read with __get_user_xb() (Russell King's suggestion)
v1: original
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2014-07-10 23:58:08 +04:00
# endif
2010-04-19 13:15:03 +04:00
.popsection