2005-04-17 02:20:36 +04:00
/ *
* Linux/ P A - R I S C P r o j e c t ( h t t p : / / w w w . p a r i s c - l i n u x . o r g / )
*
2013-05-03 01:16:38 +04:00
* System c a l l e n t r y c o d e / L i n u x g a t e w a y p a g e
2018-06-17 00:32:07 +03:00
* Copyright ( c ) M a t t h e w W i l c o x 1 9 9 9 < w i l l y @infradead.org>
2005-04-17 02:20:36 +04:00
* Licensed u n d e r t h e G N U G P L .
* thanks t o P h i l i p p R u m p f , M i k e S h a v e r a n d v a r i o u s o t h e r s
* sorry a b o u t t h e w a l l , p u f f i n . .
* /
2013-05-03 01:16:38 +04:00
/ *
How d o e s t h e L i n u x g a t e w a y p a g e o n P A - R I S C w o r k ?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The L i n u x g a t e w a y p a g e o n P A - R I S C i s " s p e c i a l " .
It a c t u a l l y h a s P A G E _ G A T E W A Y b i t s s e t ( t h i s i s l i n u x t e r m i n o l o g y ; in parisc
terminology i t ' s E x e c u t e , p r o m o t e t o P L 0 ) i n t h e p a g e m a p . S o a n y t h i n g
executing o n t h i s p a g e e x e c u t e s w i t h k e r n e l l e v e l p r i v i l e g e ( t h e r e ' s m o r e t o i t
than t h a t : t o h a v e t h i s h a p p e n , y o u a l s o h a v e t o u s e a b r a n c h w i t h a ,g a t e
completer t o a c t i v a t e t h e p r i v i l e g e p r o m o t i o n ) . T h e u p s h o t i s t h a t e v e r y t h i n g
that r u n s o n t h e g a t e w a y p a g e r u n s a t k e r n e l p r i v i l e g e b u t w i t h t h e c u r r e n t
user p r o c e s s a d d r e s s s p a c e ( a l t h o u g h y o u h a v e a c c e s s t o k e r n e l s p a c e v i a % s r2 ) .
For t h e 0 x10 0 s y s c a l l e n t r y , w e r e d o t h e s p a c e r e g i s t e r s t o p o i n t t o t h e k e r n e l
address s p a c e ( p r e s e r v i n g t h e u s e r a d d r e s s s p a c e i n % s r3 ) , m o v e t o w i d e m o d e i f
required, s a v e t h e u s e r r e g i s t e r s a n d b r a n c h i n t o t h e k e r n e l s y s c a l l e n t r y
point. F o r a l l t h e o t h e r f u n c t i o n s , w e e x e c u t e a t k e r n e l p r i v i l e g e b u t d o n ' t
flip a d d r e s s s p a c e s . T h e b a s i c u p s h o t o f t h i s i s t h a t t h e s e c o d e s n i p p e t s a r e
executed a t o m i c a l l y ( b e c a u s e t h e k e r n e l c a n ' t b e p r e - e m p t e d ) a n d t h e y m a y
perform a r c h i t e c t u r a l l y f o r b i d d e n ( t o P L 3 ) o p e r a t i o n s ( l i k e s e t t i n g c o n t r o l
registers) .
* /
2005-09-09 22:57:26 +04:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-17 02:20:36 +04:00
# include < a s m / u n i s t d . h >
# include < a s m / e r r n o . h >
2007-10-18 11:04:34 +04:00
# include < a s m / p a g e . h >
2005-04-17 02:20:36 +04:00
# include < a s m / p s w . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / a s s e m b l y . h >
# include < a s m / p r o c e s s o r . h >
2013-05-03 00:41:45 +04:00
# include < a s m / c a c h e . h >
2005-04-17 02:20:36 +04:00
2007-01-25 00:36:32 +03:00
# include < l i n u x / l i n k a g e . h >
2005-04-17 02:20:36 +04:00
/ * We f i l l t h e e m p t y p a r t s o f t h e g a t e w a y p a g e w i t h
* something t h a t w i l l k i l l t h e k e r n e l o r a
* userspace a p p l i c a t i o n .
* /
# define K I L L _ I N S N b r e a k 0 ,0
2019-05-06 00:54:34 +03:00
.level PA_ASM_LEVEL
2007-01-25 00:36:32 +03:00
2008-05-22 22:36:31 +04:00
.text
2005-04-17 02:20:36 +04:00
.import syscall_ e x i t ,c o d e
.import syscall_ e x i t _ r f i ,c o d e
/ * Linux g a t e w a y p a g e i s a l i a s e d t o v i r t u a l p a g e 0 i n t h e k e r n e l
* address s p a c e . S i n c e i t i s a g a t e w a y p a g e i t c a n n o t b e
* dereferenced, s o n u l l p o i n t e r s w i l l s t i l l f a u l t . W e s t a r t
* the a c t u a l e n t r y p o i n t a t 0 x10 0 . W e p u t b r e a k i n s t r u c t i o n s
* at t h e b e g i n n i n g o f t h e p a g e t o t r a p n u l l i n d i r e c t f u n c t i o n
* pointers.
* /
2007-10-18 11:04:34 +04:00
.align PAGE_SIZE
2007-01-25 00:36:32 +03:00
ENTRY( l i n u x _ g a t e w a y _ p a g e )
2005-04-17 02:20:36 +04:00
/* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */
.rept 44
KILL_ I N S N
.endr
2010-04-11 21:26:34 +04:00
/* ADDRESS 0xb0 to 0xb8, lws uses two insns for entry */
2005-04-17 02:20:36 +04:00
/* Light-weight-syscall entry must always be located at 0xb0 */
/* WARNING: Keep this number updated with table size changes */
2014-09-12 20:02:34 +04:00
# define _ _ N R _ l w s _ e n t r i e s ( 3 )
2005-04-17 02:20:36 +04:00
lws_entry :
2010-04-11 21:26:34 +04:00
gate l w s _ s t a r t , % r0 / * i n c r e a s e p r i v i l e g e * /
depi 3 , 3 1 , 2 , % r31 / * E n s u r e w e r e t u r n i n t o u s e r m o d e . * /
2005-04-17 02:20:36 +04:00
2010-04-11 21:26:34 +04:00
/* Fill from 0xb8 to 0xe0 */
.rept 10
2005-04-17 02:20:36 +04:00
KILL_ I N S N
.endr
/ * This f u n c t i o n M U S T b e l o c a t e d a t 0 x e 0 f o r g l i b c ' s t h r e a d i n g
mechanism t o w o r k . D O N O T M O V E T H I S C O D E E V E R ! * /
set_thread_pointer :
gate . + 8 , % r0 / * i n c r e a s e p r i v i l e g e * /
depi 3 , 3 1 , 2 , % r31 / * E n s u r e w e r e t u r n i n t o u s e r m o d e . * /
be 0 ( % s r7 ,% r31 ) / * r e t u r n t o u s e r s p a c e * /
mtctl % r26 , % c r27 / * m o v e a r g 0 t o t h e c o n t r o l r e g i s t e r * /
/ * Increase t h e c h a n c e o f t r a p p i n g i f r a n d o m j u m p s o c c u r t o t h i s
address, f i l l f r o m 0 x f0 t o 0 x10 0 * /
.rept 4
KILL_ I N S N
.endr
/* This address must remain fixed at 0x100 for glibc's syscalls to work */
2016-10-30 00:52:43 +03:00
.align LINUX_GATEWAY_ADDR
2005-04-17 02:20:36 +04:00
linux_gateway_entry :
gate . + 8 , % r0 / * b e c o m e p r i v i l e g e d * /
mtsp % r0 ,% s r4 / * g e t k e r n e l s p a c e i n t o s r4 * /
mtsp % r0 ,% s r5 / * g e t k e r n e l s p a c e i n t o s r5 * /
mtsp % r0 ,% s r6 / * g e t k e r n e l s p a c e i n t o s r6 * /
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2018-08-16 23:36:26 +03:00
/ * Store W b i t o n e n t r y t o t h e s y s c a l l i n c a s e i t ' s a w i d e u s e r l a n d
* process. * /
2005-04-17 02:20:36 +04:00
ssm P S W _ S M _ W , % r1
extrd,u % r1 ,P S W _ W _ B I T ,1 ,% r1
/ * sp m u s t b e a l i g n e d o n 4 , s o d e p o s i t t h e W b i t s e t t i n g i n t o
* the b o t t o m o f s p t e m p o r a r i l y * /
or,e v % r1 ,% r30 ,% r30
b,n 1 f
/ * The t o p h a l v e s o f a r g u m e n t r e g i s t e r s m u s t b e c l e a r e d o n s y s c a l l
* entry f r o m n a r r o w e x e c u t a b l e .
* /
depdi 0 , 3 1 , 3 2 , % r26
depdi 0 , 3 1 , 3 2 , % r25
depdi 0 , 3 1 , 3 2 , % r24
depdi 0 , 3 1 , 3 2 , % r23
depdi 0 , 3 1 , 3 2 , % r22
depdi 0 , 3 1 , 3 2 , % r21
1 :
# endif
2016-10-29 06:00:34 +03:00
/ * We u s e a r s m / s s m p a i r t o p r e v e n t s r3 f r o m b e i n g c l o b b e r e d
* by e x t e r n a l i n t e r r u p t s .
* /
mfsp % s r7 ,% r1 / * s a v e u s e r s r7 * /
rsm P S W _ S M _ I , % r0 / * d i s a b l e i n t e r r u p t s * /
mtsp % r1 ,% s r3 / * a n d s t o r e i t i n s r3 * /
2005-04-17 02:20:36 +04:00
mfctl % c r30 ,% r1
xor % r1 ,% r30 ,% r30 / * y e o l d e x o r t r i c k * /
xor % r1 ,% r30 ,% r1
xor % r1 ,% r30 ,% r30
ldo T H R E A D _ S Z _ A L G N + F R A M E _ S I Z E ( % r30 ) ,% r30 / * s e t u p k e r n e l s t a c k * /
/ * N. B . : I t i s c r i t i c a l t h a t w e d o n ' t s e t s r7 t o 0 u n t i l r30
* contains a v a l i d k e r n e l s t a c k p o i n t e r . I t i s a l s o
* critical t h a t w e d o n ' t s t a r t u s i n g t h e k e r n e l s t a c k
* until a f t e r s r7 h a s b e e n s e t t o 0 .
* /
mtsp % r0 ,% s r7 / * g e t k e r n e l s p a c e i n t o s r7 * /
2016-10-29 06:00:34 +03:00
ssm P S W _ S M _ I , % r0 / * e n a b l e i n t e r r u p t s * /
2005-04-17 02:20:36 +04:00
STREGM % r1 ,F R A M E _ S I Z E ( % r30 ) / * s a v e r1 ( u s p ) h e r e f o r n o w * /
mfctl % c r30 ,% r1 / * g e t t a s k p t r i n % r1 * /
LDREG T I _ T A S K ( % r1 ) ,% r1
/ * Save s o m e r e g i s t e r s f o r s i g c o n t e x t a n d p o t e n t i a l t a s k
switch ( s e e e n t r y . S f o r t h e d e t a i l s o f w h i c h o n e s a r e
saved/ r e s t o r e d ) . T A S K _ P T _ P S W i s z e r o e d s o w e c a n s e e w h e t h e r
a p r o c e s s i s o n a s y s c a l l o r n o t . F o r a n i n t e r r u p t t h e r e a l
PSW v a l u e i s s t o r e d . T h i s i s n e e d e d f o r g d b a n d s y s _ p t r a c e . * /
STREG % r0 , T A S K _ P T _ P S W ( % r1 )
STREG % r2 , T A S K _ P T _ G R 2 ( % r1 ) / * p r e s e r v e r p * /
STREG % r19 , T A S K _ P T _ G R 1 9 ( % r1 )
LDREGM - F R A M E _ S I Z E ( % r30 ) , % r2 / * g e t u s e r s s p b a c k * /
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
extrd,u % r2 ,6 3 ,1 ,% r19 / * W h i d d e n i n b o t t o m b i t * /
# if 0
xor % r19 ,% r2 ,% r2 / * c l e a r b o t t o m b i t * /
depd,z % r19 ,1 ,1 ,% r19
std % r19 ,T A S K _ P T _ P S W ( % r1 )
# endif
# endif
STREG % r2 , T A S K _ P T _ G R 3 0 ( % r1 ) / * . . . a n d s a v e i t * /
2005-11-18 00:32:46 +03:00
STREG % r20 , T A S K _ P T _ G R 2 0 ( % r1 ) / * S y s c a l l n u m b e r * /
2005-04-17 02:20:36 +04:00
STREG % r21 , T A S K _ P T _ G R 2 1 ( % r1 )
STREG % r22 , T A S K _ P T _ G R 2 2 ( % r1 )
STREG % r23 , T A S K _ P T _ G R 2 3 ( % r1 ) / * 4 t h a r g u m e n t * /
STREG % r24 , T A S K _ P T _ G R 2 4 ( % r1 ) / * 3 r d a r g u m e n t * /
STREG % r25 , T A S K _ P T _ G R 2 5 ( % r1 ) / * 2 n d a r g u m e n t * /
STREG % r26 , T A S K _ P T _ G R 2 6 ( % r1 ) / * 1 s t a r g u m e n t * /
STREG % r27 , T A S K _ P T _ G R 2 7 ( % r1 ) / * u s e r d p * /
STREG % r28 , T A S K _ P T _ G R 2 8 ( % r1 ) / * r e t u r n v a l u e 0 * /
2012-05-19 08:29:22 +04:00
STREG % r0 , T A S K _ P T _ O R I G _ R 2 8 ( % r1 ) / * d o n ' t p r o h i b i t r e s t a r t s * /
2005-04-17 02:20:36 +04:00
STREG % r29 , T A S K _ P T _ G R 2 9 ( % r1 ) / * r e t u r n v a l u e 1 * /
STREG % r31 , T A S K _ P T _ G R 3 1 ( % r1 ) / * p r e s e r v e s y s c a l l r e t u r n p t r * /
ldo T A S K _ P T _ F R 0 ( % r1 ) , % r27 / * s a v e f p r e g s f r o m t h e k e r n e l * /
save_ f p % r27 / * o r p o t e n t i a l t a s k s w i t c h * /
mfctl % c r11 , % r27 / * i . e . S A R * /
STREG % r27 , T A S K _ P T _ S A R ( % r1 )
loadgp
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ldo - 1 6 ( % r30 ) ,% r29 / * R e f e r e n c e p a r a m s a v e a r e a * /
copy % r19 ,% r2 / * W b i t b a c k t o r2 * /
# else
/ * no n e e d t o s a v e t h e s e o n s t a c k i n w i d e m o d e b e c a u s e t h e f i r s t 8
* args a r e p a s s e d i n r e g i s t e r s * /
stw % r22 , - 5 2 ( % r30 ) / * 5 t h a r g u m e n t * /
stw % r21 , - 5 6 ( % r30 ) / * 6 t h a r g u m e n t * /
# endif
/* Are we being ptraced? */
mfctl % c r30 , % r1
2012-05-20 19:59:03 +04:00
LDREG T I _ F L A G S ( % r1 ) ,% r1
ldi _ T I F _ S Y S C A L L _ T R A C E _ M A S K , % r19
and,C O N D ( = ) % r1 , % r19 , % r0
b,n . L t r a c e s y s
2005-04-17 02:20:36 +04:00
/ * Note! W e c a n n o t u s e t h e s y s c a l l t a b l e t h a t i s m a p p e d
nearby s i n c e t h e g a t e w a y p a g e i s m a p p e d e x e c u t e - o n l y . * /
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ldil L % s y s _ c a l l _ t a b l e , % r1
or,= % r2 ,% r2 ,% r2
addil L % ( s y s _ c a l l _ t a b l e 6 4 - s y s _ c a l l _ t a b l e ) , % r1
ldo R % s y s _ c a l l _ t a b l e ( % r1 ) , % r19
or,= % r2 ,% r2 ,% r2
ldo R % s y s _ c a l l _ t a b l e 6 4 ( % r1 ) , % r19
# else
2018-08-16 23:33:04 +03:00
load3 2 s y s _ c a l l _ t a b l e , % r19
2005-04-17 02:20:36 +04:00
# endif
2007-06-04 01:47:00 +04:00
comiclr,> > _ _ N R _ L i n u x _ s y s c a l l s , % r20 , % r0
2005-04-17 02:20:36 +04:00
b,n . L s y s c a l l _ n o s y s
LDREGX % r20 ( % r19 ) , % r19
/ * If t h i s i s a s y s _ r t _ s i g r e t u r n c a l l , a n d t h e s i g n a l w a s r e c e i v e d
* when n o t i n _ s y s c a l l , t h e n w e w a n t t o r e t u r n v i a s y s c a l l _ e x i t _ r f i ,
* not s y s c a l l _ e x i t . S i g n a l n o . i n r20 , i n _ s y s c a l l i n r25 ( s e e
* trampoline c o d e i n s i g n a l . c ) .
* /
ldi _ _ N R _ r t _ s i g r e t u r n ,% r2
comb,= % r2 ,% r20 ,. L r t _ s i g r e t u r n
.Lin_syscall :
ldil L % s y s c a l l _ e x i t ,% r2
be 0 ( % s r7 ,% r19 )
ldo R % s y s c a l l _ e x i t ( % r2 ) ,% r2
.Lrt_sigreturn :
comib,< > 0 ,% r25 ,. L i n _ s y s c a l l
ldil L % s y s c a l l _ e x i t _ r f i ,% r2
be 0 ( % s r7 ,% r19 )
ldo R % s y s c a l l _ e x i t _ r f i ( % r2 ) ,% r2
/ * Note! B e c a u s e w e a r e n o t r u n n i n g w h e r e w e w e r e l i n k e d , a n y
calls t o f u n c t i o n s e x t e r n a l t o t h i s f i l e m u s t b e i n d i r e c t . T o
be s a f e , w e a p p l y t h e o p p o s i t e r u l e t o f u n c t i o n s w i t h i n t h i s
file, w i t h l o c a l l a b e l s g i v e n t o t h e m t o e n s u r e c o r r e c t n e s s . * /
.Lsyscall_nosys :
syscall_nosys :
ldil L % s y s c a l l _ e x i t ,% r1
be R % s y s c a l l _ e x i t ( % s r7 ,% r1 )
ldo - E N O S Y S ( % r0 ) ,% r28 / * s e t e r r n o * /
/ * Warning! T h i s t r a c e c o d e i s a v i r t u a l d u p l i c a t e o f t h e c o d e a b o v e s o b e
* sure t o m a i n t a i n b o t h ! * /
.Ltracesys :
tracesys :
/ * Need t o s a v e m o r e r e g i s t e r s s o t h e d e b u g g e r c a n s e e w h e r e w e
* are. T h i s s a v e s o n l y t h e l o w e r 8 b i t s o f P S W , s o t h a t t h e C
* bit i s s t i l l c l e a r o n s y s c a l l s , a n d t h e D b i t i s s e t i f t h i s
* full r e g i s t e r s a v e p a t h h a s b e e n e x e c u t e d . W e c h e c k t h e D
* bit o n s y s c a l l _ r e t u r n _ r f i t o d e t e r m i n e w h i c h r e g i s t e r s t o
* restore. A n i n t e r r u p t r e s u l t s i n a f u l l P S W s a v e d w i t h t h e
* C b i t s e t , a n o n - s t r a c e d s y s c a l l e n t r y r e s u l t s i n C a n d D c l e a r
* in t h e s a v e d P S W .
* /
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
LDREG T I _ T A S K ( % r1 ) , % r1
ssm 0 ,% r2
STREG % r2 ,T A S K _ P T _ P S W ( % r1 ) / * L o w e r 8 b i t s o n l y ! ! * /
mfsp % s r0 ,% r2
STREG % r2 ,T A S K _ P T _ S R 0 ( % r1 )
mfsp % s r1 ,% r2
STREG % r2 ,T A S K _ P T _ S R 1 ( % r1 )
mfsp % s r2 ,% r2
STREG % r2 ,T A S K _ P T _ S R 2 ( % r1 )
mfsp % s r3 ,% r2
STREG % r2 ,T A S K _ P T _ S R 3 ( % r1 )
STREG % r2 ,T A S K _ P T _ S R 4 ( % r1 )
STREG % r2 ,T A S K _ P T _ S R 5 ( % r1 )
STREG % r2 ,T A S K _ P T _ S R 6 ( % r1 )
STREG % r2 ,T A S K _ P T _ S R 7 ( % r1 )
STREG % r2 ,T A S K _ P T _ I A S Q 0 ( % r1 )
STREG % r2 ,T A S K _ P T _ I A S Q 1 ( % r1 )
LDREG T A S K _ P T _ G R 3 1 ( % r1 ) ,% r2
STREG % r2 ,T A S K _ P T _ I A O Q 0 ( % r1 )
ldo 4 ( % r2 ) ,% r2
STREG % r2 ,T A S K _ P T _ I A O Q 1 ( % r1 )
ldo T A S K _ R E G S ( % r1 ) ,% r2
/* reg_save %r2 */
STREG % r3 ,P T _ G R 3 ( % r2 )
STREG % r4 ,P T _ G R 4 ( % r2 )
STREG % r5 ,P T _ G R 5 ( % r2 )
STREG % r6 ,P T _ G R 6 ( % r2 )
STREG % r7 ,P T _ G R 7 ( % r2 )
STREG % r8 ,P T _ G R 8 ( % r2 )
STREG % r9 ,P T _ G R 9 ( % r2 )
STREG % r10 ,P T _ G R 1 0 ( % r2 )
STREG % r11 ,P T _ G R 1 1 ( % r2 )
STREG % r12 ,P T _ G R 1 2 ( % r2 )
STREG % r13 ,P T _ G R 1 3 ( % r2 )
STREG % r14 ,P T _ G R 1 4 ( % r2 )
STREG % r15 ,P T _ G R 1 5 ( % r2 )
STREG % r16 ,P T _ G R 1 6 ( % r2 )
STREG % r17 ,P T _ G R 1 7 ( % r2 )
STREG % r18 ,P T _ G R 1 8 ( % r2 )
/* Finished saving things for the debugger */
2009-07-05 22:36:16 +04:00
copy % r2 ,% r26
ldil L % d o _ s y s c a l l _ t r a c e _ e n t e r ,% r1
2005-04-17 02:20:36 +04:00
ldil L % t r a c e s y s _ n e x t ,% r2
2009-07-05 22:36:16 +04:00
be R % d o _ s y s c a l l _ t r a c e _ e n t e r ( % s r7 ,% r1 )
2005-04-17 02:20:36 +04:00
ldo R % t r a c e s y s _ n e x t ( % r2 ) ,% r2
2009-07-05 22:36:16 +04:00
tracesys_next :
/ * do_ s y s c a l l _ t r a c e _ e n t e r e i t h e r r e t u r n e d t h e s y s c a l l n o , o r - 1 L ,
* so w e s k i p r e s t o r i n g t h e P T _ G R 2 0 b e l o w , s i n c e w e p u l l e d i t f r o m
* task- > t h r e a d . r e g s . g r [ 2 0 ] a b o v e .
* /
copy % r e t 0 ,% r20
2005-04-17 02:20:36 +04:00
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
LDREG T I _ T A S K ( % r1 ) , % r1
2016-03-30 15:14:31 +03:00
LDREG T A S K _ P T _ G R 2 8 ( % r1 ) , % r28 / * R e s t o r e r e t u r n v a l u e * /
2005-04-17 02:20:36 +04:00
LDREG T A S K _ P T _ G R 2 6 ( % r1 ) , % r26 / * R e s t o r e t h e u s e r s a r g s * /
LDREG T A S K _ P T _ G R 2 5 ( % r1 ) , % r25
LDREG T A S K _ P T _ G R 2 4 ( % r1 ) , % r24
LDREG T A S K _ P T _ G R 2 3 ( % r1 ) , % r23
LDREG T A S K _ P T _ G R 2 2 ( % r1 ) , % r22
LDREG T A S K _ P T _ G R 2 1 ( % r1 ) , % r21
2012-12-09 10:16:14 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ldo - 1 6 ( % r30 ) ,% r29 / * R e f e r e n c e p a r a m s a v e a r e a * /
2012-12-09 10:16:14 +04:00
# else
stw % r22 , - 5 2 ( % r30 ) / * 5 t h a r g u m e n t * /
stw % r21 , - 5 6 ( % r30 ) / * 6 t h a r g u m e n t * /
2005-04-17 02:20:36 +04:00
# endif
2016-03-30 15:14:31 +03:00
cmpib,C O N D ( = ) ,n - 1 ,% r20 ,t r a c e s y s _ e x i t / * s e c c o m p m a y h a v e r e t u r n e d - 1 * /
2016-04-27 04:56:11 +03:00
comiclr,> > _ _ N R _ L i n u x _ s y s c a l l s , % r20 , % r0
2016-01-19 18:08:49 +03:00
b,n . L t r a c e s y s _ n o s y s
2005-04-17 02:20:36 +04:00
2018-08-16 23:33:04 +03:00
/ * Note! W e c a n n o t u s e t h e s y s c a l l t a b l e t h a t i s m a p p e d
nearby s i n c e t h e g a t e w a y p a g e i s m a p p e d e x e c u t e - o n l y . * /
# ifdef C O N F I G _ 6 4 B I T
LDREG T A S K _ P T _ G R 3 0 ( % r1 ) , % r19 / * g e t u s e r s s p b a c k * /
extrd,u % r19 ,6 3 ,1 ,% r2 / * W h i d d e n i n b o t t o m b i t * /
ldil L % s y s _ c a l l _ t a b l e , % r1
or,= % r2 ,% r2 ,% r2
addil L % ( s y s _ c a l l _ t a b l e 6 4 - s y s _ c a l l _ t a b l e ) , % r1
ldo R % s y s _ c a l l _ t a b l e ( % r1 ) , % r19
or,= % r2 ,% r2 ,% r2
ldo R % s y s _ c a l l _ t a b l e 6 4 ( % r1 ) , % r19
# else
load3 2 s y s _ c a l l _ t a b l e , % r19
# endif
2005-04-17 02:20:36 +04:00
LDREGX % r20 ( % r19 ) , % r19
/ * If t h i s i s a s y s _ r t _ s i g r e t u r n c a l l , a n d t h e s i g n a l w a s r e c e i v e d
* when n o t i n _ s y s c a l l , t h e n w e w a n t t o r e t u r n v i a s y s c a l l _ e x i t _ r f i ,
* not s y s c a l l _ e x i t . S i g n a l n o . i n r20 , i n _ s y s c a l l i n r25 ( s e e
* trampoline c o d e i n s i g n a l . c ) .
* /
ldi _ _ N R _ r t _ s i g r e t u r n ,% r2
comb,= % r2 ,% r20 ,. L t r a c e _ r t _ s i g r e t u r n
.Ltrace_in_syscall :
ldil L % t r a c e s y s _ e x i t ,% r2
be 0 ( % s r7 ,% r19 )
ldo R % t r a c e s y s _ e x i t ( % r2 ) ,% r2
2016-01-19 18:08:49 +03:00
.Ltracesys_nosys :
ldo - E N O S Y S ( % r0 ) ,% r28 / * s e t e r r n o * /
2005-04-17 02:20:36 +04:00
/ * Do * n o t * c a l l t h i s f u n c t i o n o n t h e g a t e w a y p a g e , b e c a u s e i t
makes a d i r e c t c a l l t o s y s c a l l _ t r a c e . * /
tracesys_exit :
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
LDREG T I _ T A S K ( % r1 ) , % r1
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ldo - 1 6 ( % r30 ) ,% r29 / * R e f e r e n c e p a r a m s a v e a r e a * /
# endif
2009-07-05 22:36:16 +04:00
ldo T A S K _ R E G S ( % r1 ) ,% r26
2015-11-20 13:22:32 +03:00
BL d o _ s y s c a l l _ t r a c e _ e x i t ,% r2
2005-04-17 02:20:36 +04:00
STREG % r28 ,T A S K _ P T _ G R 2 8 ( % r1 ) / * s a v e r e t u r n v a l u e n o w * /
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
LDREG T I _ T A S K ( % r1 ) , % r1
LDREG T A S K _ P T _ G R 2 8 ( % r1 ) , % r28 / * R e s t o r e r e t u r n v a l . * /
ldil L % s y s c a l l _ e x i t ,% r1
be,n R % s y s c a l l _ e x i t ( % s r7 ,% r1 )
.Ltrace_rt_sigreturn :
comib,< > 0 ,% r25 ,. L t r a c e _ i n _ s y s c a l l
ldil L % t r a c e s y s _ s i g e x i t ,% r2
be 0 ( % s r7 ,% r19 )
ldo R % t r a c e s y s _ s i g e x i t ( % r2 ) ,% r2
tracesys_sigexit :
ldo - T H R E A D _ S Z _ A L G N - F R A M E _ S I Z E ( % r30 ) ,% r1 / * g e t t a s k p t r * /
2009-07-05 22:39:58 +04:00
LDREG T I _ T A S K ( % r1 ) , % r1
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ldo - 1 6 ( % r30 ) ,% r29 / * R e f e r e n c e p a r a m s a v e a r e a * /
# endif
2015-11-20 13:22:32 +03:00
BL d o _ s y s c a l l _ t r a c e _ e x i t ,% r2
2009-07-05 22:36:16 +04:00
ldo T A S K _ R E G S ( % r1 ) ,% r26
2005-04-17 02:20:36 +04:00
ldil L % s y s c a l l _ e x i t _ r f i ,% r1
be,n R % s y s c a l l _ e x i t _ r f i ( % s r7 ,% r1 )
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2008-12-30 05:47:38 +03:00
3 2 / 6 4 - bit L i g h t - W e i g h t - S y s c a l l A B I
2005-04-17 02:20:36 +04:00
2008-12-30 05:47:38 +03:00
* - Indicates a h i n t f o r u s e r s p a c e i n l i n e a s m
implementations.
2005-04-17 02:20:36 +04:00
2008-12-30 05:47:38 +03:00
Syscall n u m b e r ( c a l l e r - s a v e s )
- % r2 0
* In a s m c l o b b e r .
2005-04-17 02:20:36 +04:00
2008-12-30 05:47:38 +03:00
Argument r e g i s t e r s ( c a l l e r - s a v e s )
- % r2 6 , % r25 , % r24 , % r23 , % r22
* In a s m i n p u t .
Return r e g i s t e r s ( c a l l e r - s a v e s )
- % r2 8 ( r e t u r n ) , % r21 ( e r r n o )
* In a s m o u t p u t .
Caller- s a v e s r e g i s t e r s
- % r1 , % r27 , % r29
- % r2 ( r e t u r n p o i n t e r )
- % r3 1 ( b l e l i n k r e g i s t e r )
* In a s m c l o b b e r .
Callee- s a v e s r e g i s t e r s
- % r3 - % r18
- % r3 0 ( s t a c k p o i n t e r )
* Not i n a s m c l o b b e r .
If u s e r s p a c e i s 3 2 - b i t :
Callee- s a v e s r e g i s t e r s
- % r1 9 ( 3 2 - b i t P I C r e g i s t e r )
Differences f r o m 3 2 - b i t c a l l i n g c o n v e n t i o n :
- Syscall n u m b e r i n % r20
- Additional a r g u m e n t r e g i s t e r % r22 ( a r g 4 )
- Callee- s a v e s % r19 .
If u s e r s p a c e i s 6 4 - b i t :
Callee- s a v e s r e g i s t e r s
- % r2 7 ( 6 4 - b i t P I C r e g i s t e r )
Differences f r o m 6 4 - b i t c a l l i n g c o n v e n t i o n :
- Syscall n u m b e r i n % r20
- Additional a r g u m e n t r e g i s t e r % r22 ( a r g 4 )
- Callee- s a v e s % r27 .
2005-04-17 02:20:36 +04:00
Error c o d e s r e t u r n e d b y e n t r y p a t h :
ENOSYS - r20 w a s a n i n v a l i d L W S n u m b e r .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
lws_start :
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
ssm P S W _ S M _ W , % r1
extrd,u % r1 ,P S W _ W _ B I T ,1 ,% r1
/ * sp m u s t b e a l i g n e d o n 4 , s o d e p o s i t t h e W b i t s e t t i n g i n t o
* the b o t t o m o f s p t e m p o r a r i l y * /
or,e v % r1 ,% r30 ,% r30
2018-08-16 23:36:26 +03:00
/* Clip LWS number to a 32-bit value for 32-bit processes */
2005-04-17 02:20:36 +04:00
depdi 0 , 3 1 , 3 2 , % r20
# endif
/* Is the lws entry number valid? */
2010-04-11 21:26:34 +04:00
comiclr,> > _ _ N R _ l w s _ e n t r i e s , % r20 , % r0
2005-04-17 02:20:36 +04:00
b,n l w s _ e x i t _ n o s y s
/* Load table start */
ldil L % l w s _ t a b l e , % r1
ldo R % l w s _ t a b l e ( % r1 ) , % r28 / * S c r a t c h u s e o f r28 * /
LDREGX % r20 ( % s r2 ,r28 ) , % r21 / * S c r a t c h u s e o f r21 * /
/* Jump to lws, lws table pointers already relocated */
be,n 0 ( % s r2 ,% r21 )
lws_exit_nosys :
ldo - E N O S Y S ( % r0 ) ,% r21 / * s e t e r r n o * /
/* Fall through: Return to userspace */
lws_exit :
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
/ * decide w h e t h e r t o r e s e t t h e w i d e m o d e b i t
*
* For a s y s c a l l , t h e W b i t i s s t o r e d i n t h e l o w e s t b i t
* of s p . E x t r a c t i t a n d r e s e t W i f i t i s z e r o * /
extrd,u ,* < > % r30 ,6 3 ,1 ,% r1
rsm P S W _ S M _ W , % r0
/* now reset the lowest bit of sp if it was set */
xor % r30 ,% r1 ,% r30
# endif
2010-04-11 21:26:34 +04:00
be,n 0 ( % s r7 , % r31 )
2005-04-17 02:20:36 +04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2014-09-12 20:02:34 +04:00
Implementing 3 2 b i t C A S a s a n a t o m i c o p e r a t i o n :
2005-04-17 02:20:36 +04:00
% r2 6 - A d d r e s s t o e x a m i n e
% r2 5 - O l d v a l u e t o c h e c k ( o l d )
% r2 4 - N e w v a l u e t o s e t ( n e w )
% r2 8 - R e t u r n p r e v t h r o u g h t h i s r e g i s t e r .
% r2 1 - K e r n e l e r r o r c o d e
If d e b u g g i n g i s D I S a b l e d :
% r2 1 h a s t h e f o l l o w i n g m e a n i n g s :
EAGAIN - C A S i s b u s y , l d c w f a i l e d , t r y a g a i n .
EFAULT - R e a d o r w r i t e f a i l e d .
If d e b u g g i n g i s e n a b l e d :
EDEADLOCK - C A S c a l l e d r e c u r s i v e l y .
EAGAIN & & r28 = = 1 - C A S i s b u s y . L o c k c o n t e n d e d .
EAGAIN & & r28 = = 2 - C A S i s b u s y . l d c w f a i l e d .
EFAULT - R e a d o r w r i t e f a i l e d .
Scratch : r2 0 , r28 , r1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* Do not enable LWS debugging */
# define E N A B L E _ L W S _ D E B U G 0
/* ELF64 Process entry path */
lws_compare_and_swap64 :
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
b,n l w s _ c o m p a r e _ a n d _ s w a p
# else
/ * If w e a r e n o t a 6 4 - b i t k e r n e l , t h e n w e d o n ' t
2008-12-30 05:47:38 +03:00
* have 6 4 - b i t i n p u t r e g i s t e r s , a n d c a l l i n g
* the 6 4 - b i t L W S C A S r e t u r n s E N O S Y S .
2005-04-17 02:20:36 +04:00
* /
b,n l w s _ e x i t _ n o s y s
# endif
/* ELF32 Process entry path */
lws_compare_and_swap32 :
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-17 02:20:36 +04:00
/* Clip all the input registers */
depdi 0 , 3 1 , 3 2 , % r26
depdi 0 , 3 1 , 3 2 , % r25
depdi 0 , 3 1 , 3 2 , % r24
# endif
lws_compare_and_swap :
/* Load start of lock table */
ldil L % l w s _ l o c k _ s t a r t , % r20
ldo R % l w s _ l o c k _ s t a r t ( % r20 ) , % r28
2020-10-02 22:21:41 +03:00
/* Extract eight bits from r26 and hash lock (Bits 3-11) */
extru % r26 , 2 8 , 8 , % r20
2005-04-17 02:20:36 +04:00
/ * Find l o c k t o u s e , t h e h a s h i s e i t h e r o n e o f 0 t o
1 5 , multiplied b y 1 6 ( k e e p i t 1 6 - b y t e a l i g n e d )
and a d d t o t h e l o c k t a b l e o f f s e t . * /
shlw % r20 , 4 , % r20
add % r20 , % r28 , % r20
2007-05-22 19:38:26 +04:00
# if E N A B L E _ L W S _ D E B U G
2005-04-17 02:20:36 +04:00
/ *
DEBUG, c h e c k f o r d e a d l o c k !
If t h e t h r e a d r e g i s t e r v a l u e s a r e t h e s a m e
then w e w e r e t h e o n e t h a t l o c k e d i t l a s t a n d
this i s a r e c u r i s v e c a l l t h a t w i l l d e a d l o c k .
We * m u s t * g i v e u p t h i s c a l l a n d f a i l .
* /
ldw 4 ( % s r2 ,% r20 ) , % r28 / * L o a d t h r e a d r e g i s t e r * /
2005-11-18 00:32:46 +03:00
/* WARNING: If cr27 cycles to the same value we have problems */
2005-04-17 02:20:36 +04:00
mfctl % c r27 , % r21 / * G e t c u r r e n t t h r e a d r e g i s t e r * /
cmpb,< > ,n % r21 , % r28 , c a s _ l o c k / * C a l l e d r e c u r s i v e ? * /
b l w s _ e x i t / * R e t u r n e r r o r ! * /
ldo - E D E A D L O C K ( % r0 ) , % r21
cas_lock :
cmpb,= ,n % r0 , % r28 , c a s _ n o c o n t e n d / * I s n o b o d y u s i n g i t ? * /
ldo 1 ( % r0 ) , % r28 / * 1 s t c a s e * /
b l w s _ e x i t / * C o n t e n d e d . . . * /
ldo - E A G A I N ( % r0 ) , % r21 / * S p i n i n u s e r s p a c e * /
cas_nocontend :
# endif
/* ENABLE_LWS_DEBUG */
parisc: Improve LWS-CAS performance
The attached change significantly improves the performance of the LWS-CAS code
in syscall.S.
This allows a number of packages to build (e.g., zeromq3, gtest and libxs)
that previously failed because slow LWS-CAS performance under contention. In
particular, interrupts taken while the lock was taken degraded performance
significantly.
The change does the following:
1) Disables interrupts around the CAS operation, and
2) Changes the loads and stores to use the ordered completer, "o", on
PA 2.0. "o" and "ma" with a zero offset are equivalent. The latter is
accepted on both PA 1.X and 2.0.
The use of ordered loads and stores probably makes no difference on all
existing hardware, but it seemed pedantically correct. In particular, the CAS
operation must complete before LDCW lock is released. As written before, a
processor could reorder the operations.
I don't believe the period interrupts are disabled is long enough to
significantly increase interrupt latency. For example, the TLB insert code is
longer. Worst case is a memory fault in the CAS operation.
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Cc: stable@vger.kernel.org # 3.13+
Signed-off-by: Helge Deller <deller@gmx.de>
2014-05-12 02:40:50 +04:00
rsm P S W _ S M _ I , % r0 / * D i s a b l e i n t e r r u p t s * /
/* COW breaks can cause contention on UP systems */
2006-04-22 10:48:22 +04:00
LDCW 0 ( % s r2 ,% r20 ) , % r28 / * T r y t o a c q u i r e t h e l o c k * /
2005-04-17 02:20:36 +04:00
cmpb,< > ,n % r0 , % r28 , c a s _ a c t i o n / * D i d w e g e t i t ? * /
cas_wouldblock :
ldo 2 ( % r0 ) , % r28 / * 2 n d c a s e * /
parisc: Improve LWS-CAS performance
The attached change significantly improves the performance of the LWS-CAS code
in syscall.S.
This allows a number of packages to build (e.g., zeromq3, gtest and libxs)
that previously failed because slow LWS-CAS performance under contention. In
particular, interrupts taken while the lock was taken degraded performance
significantly.
The change does the following:
1) Disables interrupts around the CAS operation, and
2) Changes the loads and stores to use the ordered completer, "o", on
PA 2.0. "o" and "ma" with a zero offset are equivalent. The latter is
accepted on both PA 1.X and 2.0.
The use of ordered loads and stores probably makes no difference on all
existing hardware, but it seemed pedantically correct. In particular, the CAS
operation must complete before LDCW lock is released. As written before, a
processor could reorder the operations.
I don't believe the period interrupts are disabled is long enough to
significantly increase interrupt latency. For example, the TLB insert code is
longer. Worst case is a memory fault in the CAS operation.
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Cc: stable@vger.kernel.org # 3.13+
Signed-off-by: Helge Deller <deller@gmx.de>
2014-05-12 02:40:50 +04:00
ssm P S W _ S M _ I , % r0
2005-04-17 02:20:36 +04:00
b l w s _ e x i t / * C o n t e n d e d . . . * /
ldo - E A G A I N ( % r0 ) , % r21 / * S p i n i n u s e r s p a c e * /
/ *
prev = * a d d r ;
if ( p r e v = = o l d )
* addr = n e w ;
return p r e v ;
* /
/ * NOTES :
This a l l w o r k s b e c u s e i n t r _ d o _ s i g n a l
and s c h e d u l e b o t h c h e c k t h e r e t u r n i a s q
and s e e t h a t w e a r e o n t h e k e r n e l p a g e
so t h i s p r o c e s s i s n e v e r s c h e d u l e d o f f
or i s e v e r s e n t a n y s i g n a l o f a n y s o r t ,
thus i t i s w h o l l y a t o m i c f r o m u s r s p a c e s
perspective
* /
cas_action :
2007-05-22 19:38:26 +04:00
# if d e f i n e d C O N F I G _ S M P & & E N A B L E _ L W S _ D E B U G
2005-04-17 02:20:36 +04:00
/* DEBUG */
mfctl % c r27 , % r1
stw % r1 , 4 ( % s r2 ,% r20 )
# endif
/* The load and store could fail */
2018-08-12 23:38:03 +03:00
1 : ldw 0 ( % r26 ) , % r28
2005-04-17 02:20:36 +04:00
sub,< > % r28 , % r25 , % r0
2018-08-12 23:38:03 +03:00
2 : stw % r24 , 0 ( % r26 )
2005-04-17 02:20:36 +04:00
/* Free lock */
2020-07-28 19:56:14 +03:00
stw,m a % r20 , 0 ( % s r2 ,% r20 )
2010-04-11 21:26:34 +04:00
# if E N A B L E _ L W S _ D E B U G
2005-04-17 02:20:36 +04:00
/* Clear thread register indicator */
stw % r0 , 4 ( % s r2 ,% r20 )
# endif
parisc: Improve LWS-CAS performance
The attached change significantly improves the performance of the LWS-CAS code
in syscall.S.
This allows a number of packages to build (e.g., zeromq3, gtest and libxs)
that previously failed because slow LWS-CAS performance under contention. In
particular, interrupts taken while the lock was taken degraded performance
significantly.
The change does the following:
1) Disables interrupts around the CAS operation, and
2) Changes the loads and stores to use the ordered completer, "o", on
PA 2.0. "o" and "ma" with a zero offset are equivalent. The latter is
accepted on both PA 1.X and 2.0.
The use of ordered loads and stores probably makes no difference on all
existing hardware, but it seemed pedantically correct. In particular, the CAS
operation must complete before LDCW lock is released. As written before, a
processor could reorder the operations.
I don't believe the period interrupts are disabled is long enough to
significantly increase interrupt latency. For example, the TLB insert code is
longer. Worst case is a memory fault in the CAS operation.
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Cc: stable@vger.kernel.org # 3.13+
Signed-off-by: Helge Deller <deller@gmx.de>
2014-05-12 02:40:50 +04:00
/* Enable interrupts */
ssm P S W _ S M _ I , % r0
2005-04-17 02:20:36 +04:00
/* Return to userspace, set no error */
b l w s _ e x i t
copy % r0 , % r21
3 :
2011-03-31 05:57:33 +04:00
/* Error occurred on load or store */
2005-04-17 02:20:36 +04:00
/* Free lock */
2020-07-28 19:56:14 +03:00
stw,m a % r20 , 0 ( % s r2 ,% r20 )
2010-04-11 21:26:34 +04:00
# if E N A B L E _ L W S _ D E B U G
2005-04-17 02:20:36 +04:00
stw % r0 , 4 ( % s r2 ,% r20 )
# endif
parisc: Improve LWS-CAS performance
The attached change significantly improves the performance of the LWS-CAS code
in syscall.S.
This allows a number of packages to build (e.g., zeromq3, gtest and libxs)
that previously failed because slow LWS-CAS performance under contention. In
particular, interrupts taken while the lock was taken degraded performance
significantly.
The change does the following:
1) Disables interrupts around the CAS operation, and
2) Changes the loads and stores to use the ordered completer, "o", on
PA 2.0. "o" and "ma" with a zero offset are equivalent. The latter is
accepted on both PA 1.X and 2.0.
The use of ordered loads and stores probably makes no difference on all
existing hardware, but it seemed pedantically correct. In particular, the CAS
operation must complete before LDCW lock is released. As written before, a
processor could reorder the operations.
I don't believe the period interrupts are disabled is long enough to
significantly increase interrupt latency. For example, the TLB insert code is
longer. Worst case is a memory fault in the CAS operation.
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Cc: stable@vger.kernel.org # 3.13+
Signed-off-by: Helge Deller <deller@gmx.de>
2014-05-12 02:40:50 +04:00
ssm P S W _ S M _ I , % r0
2005-04-17 02:20:36 +04:00
b l w s _ e x i t
ldo - E F A U L T ( % r0 ) ,% r21 / * s e t e r r n o * /
nop
nop
nop
nop
/ * Two e x c e p t i o n t a b l e e n t r i e s , o n e f o r t h e l o a d ,
the o t h e r f o r t h e s t o r e . E i t h e r r e t u r n - E F A U L T .
Each o f t h e e n t r i e s m u s t b e r e l o c a t e d . * /
2013-10-13 23:11:30 +04:00
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 b - l i n u x _ g a t e w a y _ p a g e , 3 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 2 b - l i n u x _ g a t e w a y _ p a g e , 3 b - l i n u x _ g a t e w a y _ p a g e )
2005-04-17 02:20:36 +04:00
2014-09-12 20:02:34 +04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
New C A S i m p l e m e n t a t i o n w h i c h u s e s p o i n t e r s a n d v a r i a b l e s i z e
information. T h e v a l u e p o i n t e d b y o l d a n d n e w M U S T N O T c h a n g e
while p e r f o r m i n g C A S . T h e l o c k o n l y p r o t e c t t h e v a l u e a t % r26 .
% r2 6 - A d d r e s s t o e x a m i n e
% r2 5 - P o i n t e r t o t h e v a l u e t o c h e c k ( o l d )
% r2 4 - P o i n t e r t o t h e v a l u e t o s e t ( n e w )
% r2 3 - S i z e o f t h e v a r i a b l e ( 0 / 1 / 2 / 3 f o r 8 / 1 6 / 3 2 / 6 4 b i t )
% r2 8 - R e t u r n n o n - z e r o o n f a i l u r e
% r2 1 - K e r n e l e r r o r c o d e
% r2 1 h a s t h e f o l l o w i n g m e a n i n g s :
EAGAIN - C A S i s b u s y , l d c w f a i l e d , t r y a g a i n .
EFAULT - R e a d o r w r i t e f a i l e d .
Scratch : r2 0 , r22 , r28 , r29 , r1 , f r4 ( 3 2 b i t f o r 6 4 b i t C A S o n l y )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/* ELF32 Process entry path */
lws_compare_and_swap_2 :
# ifdef C O N F I G _ 6 4 B I T
2017-11-12 01:11:16 +03:00
/ * Clip t h e i n p u t r e g i s t e r s . W e d o n ' t n e e d t o c l i p % r23 a s w e
only u s e i t f o r w o r d o p e r a t i o n s * /
2014-09-12 20:02:34 +04:00
depdi 0 , 3 1 , 3 2 , % r26
depdi 0 , 3 1 , 3 2 , % r25
depdi 0 , 3 1 , 3 2 , % r24
# endif
/* Check the validity of the size pointer */
2017-11-12 01:11:16 +03:00
subi,> > = 3 , % r23 , % r0
2014-09-12 20:02:34 +04:00
b,n l w s _ e x i t _ n o s y s
/ * Jump t o t h e f u n c t i o n s w h i c h w i l l l o a d t h e o l d a n d n e w v a l u e s i n t o
registers d e p e n d i n g o n t h e t h e i r s i z e * /
shlw % r23 , 2 , % r29
blr % r29 , % r0
nop
/* 8bit load */
2016-10-28 23:13:42 +03:00
4 : ldb 0 ( % r25 ) , % r25
2014-09-12 20:02:34 +04:00
b c a s2 _ l o c k _ s t a r t
2016-10-28 23:13:42 +03:00
5 : ldb 0 ( % r24 ) , % r24
2014-09-12 20:02:34 +04:00
nop
nop
nop
nop
nop
/* 16bit load */
2016-10-28 23:13:42 +03:00
6 : ldh 0 ( % r25 ) , % r25
2014-09-12 20:02:34 +04:00
b c a s2 _ l o c k _ s t a r t
2016-10-28 23:13:42 +03:00
7 : ldh 0 ( % r24 ) , % r24
2014-09-12 20:02:34 +04:00
nop
nop
nop
nop
nop
/* 32bit load */
2016-10-28 23:13:42 +03:00
8 : ldw 0 ( % r25 ) , % r25
2014-09-12 20:02:34 +04:00
b c a s2 _ l o c k _ s t a r t
2016-10-28 23:13:42 +03:00
9 : ldw 0 ( % r24 ) , % r24
2014-09-12 20:02:34 +04:00
nop
nop
nop
nop
nop
/* 64bit load */
# ifdef C O N F I G _ 6 4 B I T
2016-10-28 23:13:42 +03:00
10 : ldd 0 ( % r25 ) , % r25
11 : ldd 0 ( % r24 ) , % r24
2014-09-12 20:02:34 +04:00
# else
2017-10-01 00:24:23 +03:00
/* Load old value into r22/r23 - high/low */
2016-10-28 23:13:42 +03:00
10 : ldw 0 ( % r25 ) , % r22
11 : ldw 4 ( % r25 ) , % r23
2014-09-12 20:02:34 +04:00
/* Load new value into fr4 for atomic store later */
2016-10-28 23:13:42 +03:00
12 : flddx 0 ( % r24 ) , % f r4
2014-09-12 20:02:34 +04:00
# endif
cas2_lock_start :
/* Load start of lock table */
ldil L % l w s _ l o c k _ s t a r t , % r20
ldo R % l w s _ l o c k _ s t a r t ( % r20 ) , % r28
2020-10-02 22:21:41 +03:00
/* Extract eight bits from r26 and hash lock (Bits 3-11) */
extru % r26 , 2 8 , 8 , % r20
2014-09-12 20:02:34 +04:00
/ * Find l o c k t o u s e , t h e h a s h i s e i t h e r o n e o f 0 t o
1 5 , multiplied b y 1 6 ( k e e p i t 1 6 - b y t e a l i g n e d )
and a d d t o t h e l o c k t a b l e o f f s e t . * /
shlw % r20 , 4 , % r20
add % r20 , % r28 , % r20
rsm P S W _ S M _ I , % r0 / * D i s a b l e i n t e r r u p t s * /
/* COW breaks can cause contention on UP systems */
LDCW 0 ( % s r2 ,% r20 ) , % r28 / * T r y t o a c q u i r e t h e l o c k * /
cmpb,< > ,n % r0 , % r28 , c a s2 _ a c t i o n / * D i d w e g e t i t ? * /
cas2_wouldblock :
ldo 2 ( % r0 ) , % r28 / * 2 n d c a s e * /
ssm P S W _ S M _ I , % r0
b l w s _ e x i t / * C o n t e n d e d . . . * /
ldo - E A G A I N ( % r0 ) , % r21 / * S p i n i n u s e r s p a c e * /
/ *
prev = * a d d r ;
if ( p r e v = = o l d )
* addr = n e w ;
return p r e v ;
* /
/ * NOTES :
This a l l w o r k s b e c u s e i n t r _ d o _ s i g n a l
and s c h e d u l e b o t h c h e c k t h e r e t u r n i a s q
and s e e t h a t w e a r e o n t h e k e r n e l p a g e
so t h i s p r o c e s s i s n e v e r s c h e d u l e d o f f
or i s e v e r s e n t a n y s i g n a l o f a n y s o r t ,
thus i t i s w h o l l y a t o m i c f r o m u s r s p a c e s
perspective
* /
cas2_action :
/* Jump to the correct function */
blr % r29 , % r0
/* Set %r28 as non-zero for now */
ldo 1 ( % r0 ) ,% r28
/* 8bit CAS */
2018-08-12 23:38:03 +03:00
13 : ldb 0 ( % r26 ) , % r29
2014-09-12 20:02:34 +04:00
sub,= % r29 , % r25 , % r0
b,n c a s2 _ e n d
2018-08-12 23:38:03 +03:00
14 : stb % r24 , 0 ( % r26 )
2014-09-12 20:02:34 +04:00
b c a s2 _ e n d
copy % r0 , % r28
nop
nop
/* 16bit CAS */
2018-08-12 23:38:03 +03:00
15 : ldh 0 ( % r26 ) , % r29
2014-09-12 20:02:34 +04:00
sub,= % r29 , % r25 , % r0
b,n c a s2 _ e n d
2018-08-12 23:38:03 +03:00
16 : sth % r24 , 0 ( % r26 )
2014-09-12 20:02:34 +04:00
b c a s2 _ e n d
copy % r0 , % r28
nop
nop
/* 32bit CAS */
2018-08-12 23:38:03 +03:00
17 : ldw 0 ( % r26 ) , % r29
2014-09-12 20:02:34 +04:00
sub,= % r29 , % r25 , % r0
b,n c a s2 _ e n d
2018-08-12 23:38:03 +03:00
18 : stw % r24 , 0 ( % r26 )
2014-09-12 20:02:34 +04:00
b c a s2 _ e n d
copy % r0 , % r28
nop
nop
/* 64bit CAS */
# ifdef C O N F I G _ 6 4 B I T
2018-08-12 23:38:03 +03:00
19 : ldd 0 ( % r26 ) , % r29
2015-09-08 03:13:28 +03:00
sub,* = % r29 , % r25 , % r0
2014-09-12 20:02:34 +04:00
b,n c a s2 _ e n d
2018-08-12 23:38:03 +03:00
20 : std % r24 , 0 ( % r26 )
2014-09-12 20:02:34 +04:00
copy % r0 , % r28
# else
/* Compare first word */
2017-10-01 00:24:23 +03:00
19 : ldw 0 ( % r26 ) , % r29
2014-09-12 20:02:34 +04:00
sub,= % r29 , % r22 , % r0
b,n c a s2 _ e n d
/* Compare second word */
2017-10-01 00:24:23 +03:00
20 : ldw 4 ( % r26 ) , % r29
2014-09-12 20:02:34 +04:00
sub,= % r29 , % r23 , % r0
b,n c a s2 _ e n d
/* Perform the store */
2016-10-28 23:13:42 +03:00
21 : fstdx % f r4 , 0 ( % r26 )
2014-09-12 20:02:34 +04:00
copy % r0 , % r28
# endif
cas2_end :
/* Free lock */
2020-07-28 19:56:14 +03:00
stw,m a % r20 , 0 ( % s r2 ,% r20 )
2014-09-12 20:02:34 +04:00
/* Enable interrupts */
ssm P S W _ S M _ I , % r0
/* Return to userspace, set no error */
b l w s _ e x i t
copy % r0 , % r21
22 :
/* Error occurred on load or store */
/* Free lock */
2020-07-28 19:56:14 +03:00
stw,m a % r20 , 0 ( % s r2 ,% r20 )
2014-09-12 20:02:34 +04:00
ssm P S W _ S M _ I , % r0
ldo 1 ( % r0 ) ,% r28
b l w s _ e x i t
ldo - E F A U L T ( % r0 ) ,% r21 / * s e t e r r n o * /
nop
nop
nop
/ * Exception t a b l e e n t r i e s , f o r t h e l o a d a n d s t o r e , r e t u r n E F A U L T .
Each o f t h e e n t r i e s m u s t b e r e l o c a t e d . * /
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 4 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 5 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 6 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 7 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 8 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 9 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 0 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 1 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 3 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 4 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 5 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 6 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 7 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 8 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 9 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 2 0 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
# ifndef C O N F I G _ 6 4 B I T
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 1 2 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
ASM_ E X C E P T I O N T A B L E _ E N T R Y ( 2 1 b - l i n u x _ g a t e w a y _ p a g e , 2 2 b - l i n u x _ g a t e w a y _ p a g e )
# endif
2005-04-17 02:20:36 +04:00
/* Make sure nothing else is placed on this page */
2007-10-18 11:04:34 +04:00
.align PAGE_SIZE
2007-01-25 00:36:32 +03:00
END( l i n u x _ g a t e w a y _ p a g e )
ENTRY( e n d _ l i n u x _ g a t e w a y _ p a g e )
2005-04-17 02:20:36 +04:00
/ * Relocate s y m b o l s a s s u m i n g l i n u x _ g a t e w a y _ p a g e i s m a p p e d
to v i r t u a l a d d r e s s 0 x0 * /
2007-01-25 00:36:32 +03:00
2007-01-28 16:52:57 +03:00
# define L W S _ E N T R Y ( _ n a m e _ ) A S M _ U L O N G _ I N S N ( l w s _ ## _ n a m e _ - l i n u x _ g a t e w a y _ p a g e )
2005-04-17 02:20:36 +04:00
2006-01-13 23:21:06 +03:00
.section .rodata , " a"
2013-05-03 00:41:45 +04:00
.align 8
2005-04-17 02:20:36 +04:00
/* Light-weight-syscall table */
/* Start of lws table. */
2007-01-25 00:36:32 +03:00
ENTRY( l w s _ t a b l e )
2014-09-12 20:02:34 +04:00
LWS_ E N T R Y ( c o m p a r e _ a n d _ s w a p32 ) / * 0 - E L F 3 2 A t o m i c 3 2 b i t C A S * /
LWS_ E N T R Y ( c o m p a r e _ a n d _ s w a p64 ) / * 1 - E L F 6 4 A t o m i c 3 2 b i t C A S * /
LWS_ E N T R Y ( c o m p a r e _ a n d _ s w a p _ 2 ) / * 2 - E L F 3 2 A t o m i c 6 4 b i t C A S * /
2007-01-25 00:36:32 +03:00
END( l w s _ t a b l e )
2005-04-17 02:20:36 +04:00
/* End of lws table */
2021-03-01 17:58:22 +03:00
# ifdef C O N F I G _ 6 4 B I T
# define _ _ S Y S C A L L _ W I T H _ C O M P A T ( n r , n a t i v e , c o m p a t ) _ _ S Y S C A L L ( n r , c o m p a t )
# else
# define _ _ S Y S C A L L _ W I T H _ C O M P A T ( n r , n a t i v e , c o m p a t ) _ _ S Y S C A L L ( n r , n a t i v e )
# endif
2019-01-02 19:02:32 +03:00
# define _ _ S Y S C A L L ( n r , e n t r y ) A S M _ U L O N G _ I N S N e n t r y
2013-05-03 00:41:45 +04:00
.align 8
2007-01-25 00:36:32 +03:00
ENTRY( s y s _ c a l l _ t a b l e )
2016-04-13 23:44:54 +03:00
.export sys_ c a l l _ t a b l e ,d a t a
2021-03-01 17:58:22 +03:00
# include < a s m / s y s c a l l _ t a b l e _ 3 2 . h > / * 3 2 - b i t s y s c a l l s * /
2007-01-25 00:36:32 +03:00
END( s y s _ c a l l _ t a b l e )
2005-04-17 02:20:36 +04:00
2005-10-22 06:46:48 +04:00
# ifdef C O N F I G _ 6 4 B I T
2013-05-03 00:41:45 +04:00
.align 8
2007-01-25 00:36:32 +03:00
ENTRY( s y s _ c a l l _ t a b l e 6 4 )
2021-03-01 17:58:22 +03:00
# include < a s m / s y s c a l l _ t a b l e _ 6 4 . h > / * 6 4 - b i t s y s c a l l s * /
2007-01-25 00:36:32 +03:00
END( s y s _ c a l l _ t a b l e 6 4 )
2005-04-17 02:20:36 +04:00
# endif
/ *
All l i g h t - w e i g h t - s y s c a l l a t o m i c o p e r a t i o n s
will u s e t h i s s e t o f l o c k s
2008-12-30 05:47:38 +03:00
NOTE : The l w s _ l o c k _ s t a r t s y m b o l m u s t b e
at l e a s t 1 6 - b y t e a l i g n e d f o r s a f e u s e
with l d c w .
2005-04-17 02:20:36 +04:00
* /
2008-05-22 22:36:31 +04:00
.section .data
2013-05-03 00:41:45 +04:00
.align L1_CACHE_BYTES
2007-01-25 00:36:32 +03:00
ENTRY( l w s _ l o c k _ s t a r t )
2005-04-17 02:20:36 +04:00
/* lws locks */
2020-10-02 22:21:41 +03:00
.rept 256
2005-04-17 02:20:36 +04:00
/* Keep locks aligned at 16-bytes */
.word 1
.word 0
.word 0
.word 0
.endr
2007-01-25 00:36:32 +03:00
END( l w s _ l o c k _ s t a r t )
2005-04-17 02:20:36 +04:00
.previous
.end