2005-04-16 15:20:36 -07:00
/ *
* Compatibility m o d e s y s t e m c a l l e n t r y p o i n t f o r x86 - 6 4 .
*
* Copyright 2 0 0 0 - 2 0 0 2 A n d i K l e e n , S u S E L a b s .
* /
# include < a s m / d w a r f2 . h >
# include < a s m / c a l l i n g . h >
2005-09-09 21:28:48 +02:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-16 15:20:36 -07:00
# include < a s m / c u r r e n t . h >
# include < a s m / e r r n o . h >
# include < a s m / i a32 _ u n i s t d . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / s e g m e n t . h >
2006-07-03 00:24:45 -07:00
# include < a s m / i r q f l a g s . h >
2005-04-16 15:20:36 -07:00
# include < l i n u x / l i n k a g e . h >
2012-01-03 14:23:06 -05:00
# include < l i n u x / e r r . h >
2005-04-16 15:20:36 -07:00
2008-06-24 01:13:31 -07:00
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
# include < l i n u x / e l f - e m . h >
# define A U D I T _ A R C H _ I 3 8 6 ( E M _ 3 8 6 | _ _ A U D I T _ A R C H _ L E )
# define _ _ A U D I T _ A R C H _ L E 0 x40 0 0 0 0 0 0
# ifndef C O N F I G _ A U D I T S Y S C A L L
2009-09-30 11:22:11 +01:00
# define s y s e x i t _ a u d i t i a32 _ r e t _ f r o m _ s y s _ c a l l
# define s y s r e t l _ a u d i t i a32 _ r e t _ f r o m _ s y s _ c a l l
2008-06-24 01:13:31 -07:00
# endif
2011-03-07 19:10:39 +01:00
.section .entry .text , " ax"
2005-04-16 15:20:36 -07:00
.macro IA32_ARG_FIXUP noebp=0
movl % e d i ,% r8 d
.if \ noebp
.else
movl % e b p ,% r9 d
.endif
xchg % e c x ,% e s i
movl % e b x ,% e d i
movl % e d x ,% e d x / * z e r o e x t e n s i o n * /
.endm
/* clobbers %eax */
2009-09-30 11:22:11 +01:00
.macro CLEAR_RREGS offset=0 , _ r9 =rax
2005-04-16 15:20:36 -07:00
xorl % e a x ,% e a x
2009-09-30 11:22:11 +01:00
movq % r a x ,\ o f f s e t + R 1 1 ( % r s p )
movq % r a x ,\ o f f s e t + R 1 0 ( % r s p )
movq % \ _ r9 ,\ o f f s e t + R 9 ( % r s p )
movq % r a x ,\ o f f s e t + R 8 ( % r s p )
2005-04-16 15:20:36 -07:00
.endm
2008-07-09 02:38:07 -07:00
/ *
* Reload a r g r e g i s t e r s f r o m s t a c k i n c a s e p t r a c e c h a n g e d t h e m .
* We d o n ' t r e l o a d % e a x b e c a u s e s y s c a l l _ t r a c e _ e n t e r ( ) r e t u r n e d
2010-09-14 12:22:58 -07:00
* the % r a x v a l u e w e s h o u l d s e e . I n s t e a d , w e j u s t t r u n c a t e t h a t
* value t o 3 2 b i t s a g a i n a s w e d i d o n e n t r y f r o m u s e r m o d e .
* If i t ' s a n e w v a l u e s e t b y u s e r _ r e g s e t d u r i n g e n t r y t r a c i n g ,
* this m a t c h e s t h e n o r m a l t r u n c a t i o n o f t h e u s e r - m o d e v a l u e .
* If i t ' s - 1 t o m a k e u s p u n t t h e s y s c a l l , t h e n ( u 3 2 ) - 1 i s s t i l l
* an a p p r o p r i a t e l y i n v a l i d v a l u e .
2008-07-09 02:38:07 -07:00
* /
2008-08-29 13:21:11 +01:00
.macro LOAD_ARGS32 offset, _ r9 =0
.if \ _ r9
2007-09-21 16:16:18 +02:00
movl \ o f f s e t + 1 6 ( % r s p ) ,% r9 d
2008-08-29 13:21:11 +01:00
.endif
2007-09-21 16:16:18 +02:00
movl \ o f f s e t + 4 0 ( % r s p ) ,% e c x
movl \ o f f s e t + 4 8 ( % r s p ) ,% e d x
movl \ o f f s e t + 5 6 ( % r s p ) ,% e s i
movl \ o f f s e t + 6 4 ( % r s p ) ,% e d i
2010-09-14 12:22:58 -07:00
movl % e a x ,% e a x / * z e r o e x t e n s i o n * /
2007-09-21 16:16:18 +02:00
.endm
2006-01-11 22:41:59 +01:00
.macro CFI_STARTPROC32 simple
CFI_ S T A R T P R O C \ s i m p l e
CFI_ U N D E F I N E D r8
CFI_ U N D E F I N E D r9
CFI_ U N D E F I N E D r10
CFI_ U N D E F I N E D r11
CFI_ U N D E F I N E D r12
CFI_ U N D E F I N E D r13
CFI_ U N D E F I N E D r14
CFI_ U N D E F I N E D r15
.endm
2008-06-25 00:19:28 -04:00
# ifdef C O N F I G _ P A R A V I R T
ENTRY( n a t i v e _ u s e r g s _ s y s r e t 3 2 )
swapgs
sysretl
ENDPROC( n a t i v e _ u s e r g s _ s y s r e t 3 2 )
ENTRY( n a t i v e _ i r q _ e n a b l e _ s y s e x i t )
swapgs
sti
sysexit
ENDPROC( n a t i v e _ i r q _ e n a b l e _ s y s e x i t )
# endif
2005-04-16 15:20:36 -07:00
/ *
* 3 2 bit S Y S E N T E R i n s t r u c t i o n e n t r y .
*
* Arguments :
* % eax S y s t e m c a l l n u m b e r .
* % ebx A r g 1
* % ecx A r g 2
* % edx A r g 3
* % esi A r g 4
* % edi A r g 5
* % ebp u s e r s t a c k
* 0 ( % ebp) A r g 6
*
* Interrupts o f f .
*
* This i s p u r e l y a f a s t p a t h . F o r a n y t h i n g c o m p l i c a t e d w e u s e t h e i n t 0 x80
* path b e l o w . S e t u p a c o m p l e t e h a r d w a r e s t a c k f r a m e t o s h a r e c o d e
* with t h e i n t 0 x80 p a t h .
* /
ENTRY( i a32 _ s y s e n t e r _ t a r g e t )
2006-01-11 22:41:59 +01:00
CFI_ S T A R T P R O C 3 2 s i m p l e
2006-09-26 10:52:41 +02:00
CFI_ S I G N A L _ F R A M E
2005-09-12 18:49:24 +02:00
CFI_ D E F _ C F A r s p ,0
CFI_ R E G I S T E R r s p ,r b p
2008-06-26 07:28:51 -07:00
SWAPGS_ U N S A F E _ S T A C K
2009-01-19 00:38:58 +09:00
movq P E R _ C P U _ V A R ( k e r n e l _ s t a c k ) , % r s p
addq $ ( K E R N E L _ S T A C K _ O F F S E T ) ,% r s p
2006-07-03 00:24:45 -07:00
/ *
* No n e e d t o f o l l o w t h i s i r q s o n / o f f s e c t i o n : t h e s y s c a l l
* disabled i r q s , h e r e w e e n a b l e i t s t r a i g h t a f t e r e n t r y :
* /
2008-06-25 00:19:29 -04:00
ENABLE_ I N T E R R U P T S ( C L B R _ N O N E )
2005-04-16 15:20:36 -07:00
movl % e b p ,% e b p / * z e r o e x t e n s i o n * /
2011-02-28 15:54:40 +00:00
pushq_ c f i $ _ _ U S E R 3 2 _ D S
2005-09-12 18:49:24 +02:00
/*CFI_REL_OFFSET ss,0*/
2011-02-28 15:54:40 +00:00
pushq_ c f i % r b p
2005-09-12 18:49:24 +02:00
CFI_ R E L _ O F F S E T r s p ,0
2011-02-28 15:54:40 +00:00
pushfq_ c f i
2005-09-12 18:49:24 +02:00
/*CFI_REL_OFFSET rflags,0*/
2011-11-29 11:17:45 +00:00
movl T I _ s y s e n t e r _ r e t u r n + T H R E A D _ I N F O ( % r s p ,3 * 8 - K E R N E L _ S T A C K _ O F F S E T ) ,% r10 d
2005-09-12 18:49:24 +02:00
CFI_ R E G I S T E R r i p ,r10
2011-02-28 15:54:40 +00:00
pushq_ c f i $ _ _ U S E R 3 2 _ C S
2005-09-12 18:49:24 +02:00
/*CFI_REL_OFFSET cs,0*/
2005-04-16 15:20:36 -07:00
movl % e a x , % e a x
2011-02-28 15:54:40 +00:00
pushq_ c f i % r10
2005-09-12 18:49:24 +02:00
CFI_ R E L _ O F F S E T r i p ,0
2011-02-28 15:54:40 +00:00
pushq_ c f i % r a x
2005-04-16 15:20:36 -07:00
cld
2011-05-31 22:21:52 +02:00
SAVE_ A R G S 0 ,1 ,0
2005-04-16 15:20:36 -07:00
/ * no n e e d t o d o a n a c c e s s _ o k c h e c k h e r e b e c a u s e r b p h a s b e e n
3 2 bit z e r o e x t e n d e d * /
2008-08-29 13:21:11 +01:00
1 : movl ( % r b p ) ,% e b p
2005-04-16 15:20:36 -07:00
.section _ _ ex_ t a b l e ," a "
.quad 1 b,i a32 _ b a d a r g
.previous
2011-11-29 11:17:45 +00:00
orl $ T S _ C O M P A T ,T I _ s t a t u s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
testl $ _ T I F _ W O R K _ S Y S C A L L _ E N T R Y ,T I _ f l a g s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2005-09-12 18:49:24 +02:00
CFI_ R E M E M B E R _ S T A T E
2005-04-16 15:20:36 -07:00
jnz s y s e n t e r _ t r a c e s y s
x86-64, compat: Test %rax for the syscall number, not %eax
On 64 bits, we always, by necessity, jump through the system call
table via %rax. For 32-bit system calls, in theory the system call
number is stored in %eax, and the code was testing %eax for a valid
system call number. At one point we loaded the stored value back from
the stack to enforce zero-extension, but that was removed in checkin
d4d67150165df8bf1cc05e532f6efca96f907cab. An actual 32-bit process
will not be able to introduce a non-zero-extended number, but it can
happen via ptrace.
Instead of re-introducing the zero-extension, test what we are
actually going to use, i.e. %rax. This only adds a handful of REX
prefixes to the code.
Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@kernel.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
2010-09-14 12:42:41 -07:00
cmpq $ ( I A 3 2 _ N R _ s y s c a l l s - 1 ) ,% r a x
2006-04-07 19:50:31 +02:00
ja i a32 _ b a d s y s
2008-07-09 02:38:07 -07:00
sysenter_do_call :
2008-08-29 13:21:11 +01:00
IA3 2 _ A R G _ F I X U P
2008-06-24 01:13:31 -07:00
sysenter_dispatch :
2005-04-16 15:20:36 -07:00
call * i a32 _ s y s _ c a l l _ t a b l e ( ,% r a x ,8 )
movq % r a x ,R A X - A R G O F F S E T ( % r s p )
2008-06-25 00:19:29 -04:00
DISABLE_ I N T E R R U P T S ( C L B R _ N O N E )
2006-07-03 00:24:45 -07:00
TRACE_ I R Q S _ O F F
2011-11-29 11:17:45 +00:00
testl $ _ T I F _ A L L W O R K _ M A S K ,T I _ f l a g s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2008-06-24 01:13:31 -07:00
jnz s y s e x i t _ a u d i t
sysexit_from_sys_call :
2011-11-29 11:17:45 +00:00
andl $ ~ T S _ C O M P A T ,T I _ s t a t u s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2005-04-16 15:20:36 -07:00
/* clear IF, that popfq doesn't enable interrupts early */
andl $ ~ 0 x20 0 ,E F L A G S - R 1 1 ( % r s p )
2008-01-30 13:30:43 +01:00
movl R I P - R 1 1 ( % r s p ) ,% e d x / * U s e r % e i p * /
CFI_ R E G I S T E R r i p ,r d x
2011-05-31 22:21:53 +02:00
RESTORE_ A R G S 0 ,2 4 ,0 ,0 ,0 ,0
2009-09-30 11:22:11 +01:00
xorq % r8 ,% r8
xorq % r9 ,% r9
xorq % r10 ,% r10
xorq % r11 ,% r11
2011-02-28 15:54:40 +00:00
popfq_ c f i
2005-09-12 18:49:24 +02:00
/*CFI_RESTORE rflags*/
2011-02-28 15:54:40 +00:00
popq_ c f i % r c x / * U s e r % e s p * /
2005-09-12 18:49:24 +02:00
CFI_ R E G I S T E R r s p ,r c x
2006-07-03 00:24:45 -07:00
TRACE_ I R Q S _ O N
2008-06-25 00:19:28 -04:00
ENABLE_ I N T E R R U P T S _ S Y S E X I T 3 2
2005-04-16 15:20:36 -07:00
2008-06-24 01:13:31 -07:00
# ifdef C O N F I G _ A U D I T S Y S C A L L
.macro auditsys_entry_common
movl % e s i ,% r9 d / * 6 t h a r g : 4 t h s y s c a l l a r g * /
movl % e d x ,% r8 d / * 5 t h a r g : 3 r d s y s c a l l a r g * /
/* (already in %ecx) 4th arg: 2nd syscall arg */
movl % e b x ,% e d x / * 3 r d a r g : 1 s t s y s c a l l a r g * /
movl % e a x ,% e s i / * 2 n d a r g : s y s c a l l n u m b e r * /
movl $ A U D I T _ A R C H _ I 3 8 6 ,% e d i / * 1 s t a r g : a u d i t a r c h * /
2012-01-03 14:23:06 -05:00
call _ _ a u d i t _ s y s c a l l _ e n t r y
2008-06-24 01:13:31 -07:00
movl R A X - A R G O F F S E T ( % r s p ) ,% e a x / * r e l o a d s y s c a l l n u m b e r * /
x86-64, compat: Test %rax for the syscall number, not %eax
On 64 bits, we always, by necessity, jump through the system call
table via %rax. For 32-bit system calls, in theory the system call
number is stored in %eax, and the code was testing %eax for a valid
system call number. At one point we loaded the stored value back from
the stack to enforce zero-extension, but that was removed in checkin
d4d67150165df8bf1cc05e532f6efca96f907cab. An actual 32-bit process
will not be able to introduce a non-zero-extended number, but it can
happen via ptrace.
Instead of re-introducing the zero-extension, test what we are
actually going to use, i.e. %rax. This only adds a handful of REX
prefixes to the code.
Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@kernel.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
2010-09-14 12:42:41 -07:00
cmpq $ ( I A 3 2 _ N R _ s y s c a l l s - 1 ) ,% r a x
2008-06-24 01:13:31 -07:00
ja i a32 _ b a d s y s
movl % e b x ,% e d i / * r e l o a d 1 s t s y s c a l l a r g * /
movl R C X - A R G O F F S E T ( % r s p ) ,% e s i / * r e l o a d 2 n d s y s c a l l a r g * /
movl R D X - A R G O F F S E T ( % r s p ) ,% e d x / * r e l o a d 3 r d s y s c a l l a r g * /
movl R S I - A R G O F F S E T ( % r s p ) ,% e c x / * r e l o a d 4 t h s y s c a l l a r g * /
movl R D I - A R G O F F S E T ( % r s p ) ,% r8 d / * r e l o a d 5 t h s y s c a l l a r g * /
.endm
2009-10-26 15:20:29 +00:00
.macro auditsys_exit exit
2011-11-29 11:17:45 +00:00
testl $ ( _ T I F _ A L L W O R K _ M A S K & ~ _ T I F _ S Y S C A L L _ A U D I T ) ,T I _ f l a g s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2009-09-30 11:22:11 +01:00
jnz i a32 _ r e t _ f r o m _ s y s _ c a l l
2008-06-24 01:13:31 -07:00
TRACE_ I R Q S _ O N
sti
movl % e a x ,% e s i / * s e c o n d a r g , s y s c a l l r e t u r n v a l u e * /
2012-01-03 14:23:06 -05:00
cmpl $ - M A X _ E R R N O ,% e a x / * i s i t a n e r r o r ? * /
2012-01-03 14:23:06 -05:00
jbe 1 f
movslq % e a x , % r s i / * i f e r r o r s i g n e x t e n d t o 6 4 b i t s * /
1 : setbe % a l / * 1 i f e r r o r , 0 i f n o t * /
2008-06-24 01:13:31 -07:00
movzbl % a l ,% e d i / * z e r o - e x t e n d t h a t i n t o % e d i * /
2012-01-03 14:23:06 -05:00
call _ _ a u d i t _ s y s c a l l _ e x i t
movq R A X - A R G O F F S E T ( % r s p ) ,% r a x / * r e l o a d s y s c a l l r e t u r n v a l u e * /
2008-06-24 01:13:31 -07:00
movl $ ( _ T I F _ A L L W O R K _ M A S K & ~ _ T I F _ S Y S C A L L _ A U D I T ) ,% e d i
cli
TRACE_ I R Q S _ O F F
2011-11-29 11:17:45 +00:00
testl % e d i ,T I _ f l a g s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2009-09-30 11:22:11 +01:00
jz \ e x i t
CLEAR_ R R E G S - A R G O F F S E T
jmp i n t _ w i t h _ c h e c k
2008-06-24 01:13:31 -07:00
.endm
sysenter_auditsys :
2005-09-12 18:49:24 +02:00
CFI_ R E S T O R E _ S T A T E
2008-06-24 01:13:31 -07:00
auditsys_ e n t r y _ c o m m o n
movl % e b p ,% r9 d / * r e l o a d 6 t h s y s c a l l a r g * /
jmp s y s e n t e r _ d i s p a t c h
sysexit_audit :
auditsys_ e x i t s y s e x i t _ f r o m _ s y s _ c a l l
# endif
sysenter_tracesys :
# ifdef C O N F I G _ A U D I T S Y S C A L L
2011-11-29 11:17:45 +00:00
testl $ ( _ T I F _ W O R K _ S Y S C A L L _ E N T R Y & ~ _ T I F _ S Y S C A L L _ A U D I T ) ,T I _ f l a g s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2008-06-24 01:13:31 -07:00
jz s y s e n t e r _ a u d i t s y s
# endif
2005-04-16 15:20:36 -07:00
SAVE_ R E S T
CLEAR_ R R E G S
2008-03-18 18:23:50 -07:00
movq $ - E N O S Y S ,R A X ( % r s p ) / * p t r a c e c a n c h a n g e t h i s f o r a b a d s y s c a l l * /
2005-04-16 15:20:36 -07:00
movq % r s p ,% r d i / * & p t _ r e g s - > a r g 1 * /
call s y s c a l l _ t r a c e _ e n t e r
2007-09-21 16:16:18 +02:00
LOAD_ A R G S 3 2 A R G O F F S E T / * r e l o a d a r g s f r o m s t a c k i n c a s e p t r a c e c h a n g e d i t * /
2005-04-16 15:20:36 -07:00
RESTORE_ R E S T
x86-64, compat: Test %rax for the syscall number, not %eax
On 64 bits, we always, by necessity, jump through the system call
table via %rax. For 32-bit system calls, in theory the system call
number is stored in %eax, and the code was testing %eax for a valid
system call number. At one point we loaded the stored value back from
the stack to enforce zero-extension, but that was removed in checkin
d4d67150165df8bf1cc05e532f6efca96f907cab. An actual 32-bit process
will not be able to introduce a non-zero-extended number, but it can
happen via ptrace.
Instead of re-introducing the zero-extension, test what we are
actually going to use, i.e. %rax. This only adds a handful of REX
prefixes to the code.
Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@kernel.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
2010-09-14 12:42:41 -07:00
cmpq $ ( I A 3 2 _ N R _ s y s c a l l s - 1 ) ,% r a x
2008-03-18 18:23:50 -07:00
ja i n t _ r e t _ f r o m _ s y s _ c a l l / * s y s e n t e r _ t r a c e s y s h a s s e t R A X ( % r s p ) * /
2005-04-16 15:20:36 -07:00
jmp s y s e n t e r _ d o _ c a l l
CFI_ E N D P R O C
2006-06-26 13:56:55 +02:00
ENDPROC( i a32 _ s y s e n t e r _ t a r g e t )
2005-04-16 15:20:36 -07:00
/ *
* 3 2 bit S Y S C A L L i n s t r u c t i o n e n t r y .
*
* Arguments :
* % eax S y s t e m c a l l n u m b e r .
* % ebx A r g 1
* % ecx r e t u r n E I P
* % edx A r g 3
* % esi A r g 4
* % edi A r g 5
* % ebp A r g 2 [ n o t e : n o t s a v e d i n t h e s t a c k f r a m e , s h o u l d n o t b e t o u c h e d ]
* % esp u s e r s t a c k
* 0 ( % esp) A r g 6
*
* Interrupts o f f .
*
* This i s p u r e l y a f a s t p a t h . F o r a n y t h i n g c o m p l i c a t e d w e u s e t h e i n t 0 x80
* path b e l o w . S e t u p a c o m p l e t e h a r d w a r e s t a c k f r a m e t o s h a r e c o d e
* with t h e i n t 0 x80 p a t h .
* /
ENTRY( i a32 _ c s t a r _ t a r g e t )
2006-01-11 22:41:59 +01:00
CFI_ S T A R T P R O C 3 2 s i m p l e
2006-09-26 10:52:41 +02:00
CFI_ S I G N A L _ F R A M E
2009-01-19 00:38:58 +09:00
CFI_ D E F _ C F A r s p ,K E R N E L _ S T A C K _ O F F S E T
2005-09-12 18:49:24 +02:00
CFI_ R E G I S T E R r i p ,r c x
/*CFI_REGISTER rflags,r11*/
2008-06-26 07:28:51 -07:00
SWAPGS_ U N S A F E _ S T A C K
2005-04-16 15:20:36 -07:00
movl % e s p ,% r8 d
2005-09-12 18:49:24 +02:00
CFI_ R E G I S T E R r s p ,r8
2009-01-19 00:38:58 +09:00
movq P E R _ C P U _ V A R ( k e r n e l _ s t a c k ) ,% r s p
2006-07-03 00:24:45 -07:00
/ *
* No n e e d t o f o l l o w t h i s i r q s o n / o f f s e c t i o n : t h e s y s c a l l
* disabled i r q s a n d h e r e w e e n a b l e i t s t r a i g h t a f t e r e n t r y :
* /
2008-06-25 00:19:29 -04:00
ENABLE_ I N T E R R U P T S ( C L B R _ N O N E )
2011-05-31 22:21:52 +02:00
SAVE_ A R G S 8 ,0 ,0
2005-04-16 15:20:36 -07:00
movl % e a x ,% e a x / * z e r o e x t e n s i o n * /
movq % r a x ,O R I G _ R A X - A R G O F F S E T ( % r s p )
movq % r c x ,R I P - A R G O F F S E T ( % r s p )
2005-09-12 18:49:24 +02:00
CFI_ R E L _ O F F S E T r i p ,R I P - A R G O F F S E T
2005-04-16 15:20:36 -07:00
movq % r b p ,R C X - A R G O F F S E T ( % r s p ) / * t h i s l i e s s l i g h t l y t o p t r a c e * /
movl % e b p ,% e c x
movq $ _ _ U S E R 3 2 _ C S ,C S - A R G O F F S E T ( % r s p )
movq $ _ _ U S E R 3 2 _ D S ,S S - A R G O F F S E T ( % r s p )
movq % r11 ,E F L A G S - A R G O F F S E T ( % r s p )
2005-09-12 18:49:24 +02:00
/*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/
2005-04-16 15:20:36 -07:00
movq % r8 ,R S P - A R G O F F S E T ( % r s p )
2005-09-12 18:49:24 +02:00
CFI_ R E L _ O F F S E T r s p ,R S P - A R G O F F S E T
2005-04-16 15:20:36 -07:00
/ * no n e e d t o d o a n a c c e s s _ o k c h e c k h e r e b e c a u s e r8 h a s b e e n
3 2 bit z e r o e x t e n d e d * /
/* hardware stack frame is complete now */
1 : movl ( % r8 ) ,% r9 d
.section _ _ ex_ t a b l e ," a "
.quad 1 b,i a32 _ b a d a r g
.previous
2011-11-29 11:17:45 +00:00
orl $ T S _ C O M P A T ,T I _ s t a t u s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
testl $ _ T I F _ W O R K _ S Y S C A L L _ E N T R Y ,T I _ f l a g s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2005-09-12 18:49:24 +02:00
CFI_ R E M E M B E R _ S T A T E
2005-04-16 15:20:36 -07:00
jnz c s t a r _ t r a c e s y s
x86-64, compat: Test %rax for the syscall number, not %eax
On 64 bits, we always, by necessity, jump through the system call
table via %rax. For 32-bit system calls, in theory the system call
number is stored in %eax, and the code was testing %eax for a valid
system call number. At one point we loaded the stored value back from
the stack to enforce zero-extension, but that was removed in checkin
d4d67150165df8bf1cc05e532f6efca96f907cab. An actual 32-bit process
will not be able to introduce a non-zero-extended number, but it can
happen via ptrace.
Instead of re-introducing the zero-extension, test what we are
actually going to use, i.e. %rax. This only adds a handful of REX
prefixes to the code.
Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@kernel.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
2010-09-14 12:42:41 -07:00
cmpq $ I A 3 2 _ N R _ s y s c a l l s - 1 ,% r a x
2006-04-07 19:50:31 +02:00
ja i a32 _ b a d s y s
2008-08-29 13:21:11 +01:00
cstar_do_call :
2005-04-16 15:20:36 -07:00
IA3 2 _ A R G _ F I X U P 1
2008-06-24 01:13:31 -07:00
cstar_dispatch :
2005-04-16 15:20:36 -07:00
call * i a32 _ s y s _ c a l l _ t a b l e ( ,% r a x ,8 )
movq % r a x ,R A X - A R G O F F S E T ( % r s p )
2008-06-25 00:19:29 -04:00
DISABLE_ I N T E R R U P T S ( C L B R _ N O N E )
2006-07-03 00:24:45 -07:00
TRACE_ I R Q S _ O F F
2011-11-29 11:17:45 +00:00
testl $ _ T I F _ A L L W O R K _ M A S K ,T I _ f l a g s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2008-06-24 01:13:31 -07:00
jnz s y s r e t l _ a u d i t
sysretl_from_sys_call :
2011-11-29 11:17:45 +00:00
andl $ ~ T S _ C O M P A T ,T I _ s t a t u s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2011-05-31 22:21:53 +02:00
RESTORE_ A R G S 0 ,- A R G _ S K I P ,0 ,0 ,0
2005-04-16 15:20:36 -07:00
movl R I P - A R G O F F S E T ( % r s p ) ,% e c x
2005-09-12 18:49:24 +02:00
CFI_ R E G I S T E R r i p ,r c x
2005-04-16 15:20:36 -07:00
movl E F L A G S - A R G O F F S E T ( % r s p ) ,% r11 d
2005-09-12 18:49:24 +02:00
/*CFI_REGISTER rflags,r11*/
2009-09-30 11:22:11 +01:00
xorq % r10 ,% r10
xorq % r9 ,% r9
xorq % r8 ,% r8
2006-07-03 00:24:45 -07:00
TRACE_ I R Q S _ O N
2005-04-16 15:20:36 -07:00
movl R S P - A R G O F F S E T ( % r s p ) ,% e s p
2005-09-12 18:49:24 +02:00
CFI_ R E S T O R E r s p
2008-06-25 00:19:28 -04:00
USERGS_ S Y S R E T 3 2
2005-04-16 15:20:36 -07:00
2008-06-24 01:13:31 -07:00
# ifdef C O N F I G _ A U D I T S Y S C A L L
cstar_auditsys :
2005-09-12 18:49:24 +02:00
CFI_ R E S T O R E _ S T A T E
2008-06-24 01:13:31 -07:00
movl % r9 d ,R 9 - A R G O F F S E T ( % r s p ) / * r e g i s t e r t o b e c l o b b e r e d b y c a l l * /
auditsys_ e n t r y _ c o m m o n
movl R 9 - A R G O F F S E T ( % r s p ) ,% r9 d / * r e l o a d 6 t h s y s c a l l a r g * /
jmp c s t a r _ d i s p a t c h
sysretl_audit :
2009-10-26 15:20:29 +00:00
auditsys_ e x i t s y s r e t l _ f r o m _ s y s _ c a l l
2008-06-24 01:13:31 -07:00
# endif
cstar_tracesys :
# ifdef C O N F I G _ A U D I T S Y S C A L L
2011-11-29 11:17:45 +00:00
testl $ ( _ T I F _ W O R K _ S Y S C A L L _ E N T R Y & ~ _ T I F _ S Y S C A L L _ A U D I T ) ,T I _ f l a g s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2008-06-24 01:13:31 -07:00
jz c s t a r _ a u d i t s y s
# endif
2007-11-07 10:48:39 -05:00
xchgl % r9 d ,% e b p
2005-04-16 15:20:36 -07:00
SAVE_ R E S T
2009-09-30 11:22:11 +01:00
CLEAR_ R R E G S 0 , r9
2008-03-18 18:23:50 -07:00
movq $ - E N O S Y S ,R A X ( % r s p ) / * p t r a c e c a n c h a n g e t h i s f o r a b a d s y s c a l l * /
2005-04-16 15:20:36 -07:00
movq % r s p ,% r d i / * & p t _ r e g s - > a r g 1 * /
call s y s c a l l _ t r a c e _ e n t e r
2008-08-29 13:21:11 +01:00
LOAD_ A R G S 3 2 A R G O F F S E T , 1 / * r e l o a d a r g s f r o m s t a c k i n c a s e p t r a c e c h a n g e d i t * /
2005-04-16 15:20:36 -07:00
RESTORE_ R E S T
2007-11-07 10:48:39 -05:00
xchgl % e b p ,% r9 d
x86-64, compat: Test %rax for the syscall number, not %eax
On 64 bits, we always, by necessity, jump through the system call
table via %rax. For 32-bit system calls, in theory the system call
number is stored in %eax, and the code was testing %eax for a valid
system call number. At one point we loaded the stored value back from
the stack to enforce zero-extension, but that was removed in checkin
d4d67150165df8bf1cc05e532f6efca96f907cab. An actual 32-bit process
will not be able to introduce a non-zero-extended number, but it can
happen via ptrace.
Instead of re-introducing the zero-extension, test what we are
actually going to use, i.e. %rax. This only adds a handful of REX
prefixes to the code.
Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@kernel.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
2010-09-14 12:42:41 -07:00
cmpq $ ( I A 3 2 _ N R _ s y s c a l l s - 1 ) ,% r a x
2008-03-18 18:23:50 -07:00
ja i n t _ r e t _ f r o m _ s y s _ c a l l / * c s t a r _ t r a c e s y s h a s s e t R A X ( % r s p ) * /
2005-04-16 15:20:36 -07:00
jmp c s t a r _ d o _ c a l l
2006-06-26 13:56:55 +02:00
END( i a32 _ c s t a r _ t a r g e t )
2005-04-16 15:20:36 -07:00
ia32_badarg :
movq $ - E F A U L T ,% r a x
jmp i a32 _ s y s r e t
CFI_ E N D P R O C
/ *
* Emulated I A 3 2 s y s t e m c a l l s v i a i n t 0 x80 .
*
* Arguments :
* % eax S y s t e m c a l l n u m b e r .
* % ebx A r g 1
* % ecx A r g 2
* % edx A r g 3
* % esi A r g 4
* % edi A r g 5
* % ebp A r g 6 [ n o t e : n o t s a v e d i n t h e s t a c k f r a m e , s h o u l d n o t b e t o u c h e d ]
*
* Notes :
* Uses t h e s a m e s t a c k f r a m e a s t h e x86 - 6 4 v e r s i o n .
* All r e g i s t e r s e x c e p t % e a x m u s t b e s a v e d ( b u t p t r a c e m a y v i o l a t e t h a t )
* Arguments a r e z e r o e x t e n d e d . F o r s y s t e m c a l l s t h a t w a n t s i g n e x t e n s i o n a n d
* take l o n g a r g u m e n t s a w r a p p e r i s n e e d e d . M o s t c a l l s c a n j u s t b e c a l l e d
* directly.
* Assumes i t i s o n l y c a l l e d f r o m u s e r s p a c e a n d e n t e r e d w i t h i n t e r r u p t s o f f .
* /
ENTRY( i a32 _ s y s c a l l )
2007-07-21 17:10:20 +02:00
CFI_ S T A R T P R O C 3 2 s i m p l e
2006-09-26 10:52:41 +02:00
CFI_ S I G N A L _ F R A M E
2005-09-12 18:49:24 +02:00
CFI_ D E F _ C F A r s p ,S S + 8 - R I P
/*CFI_REL_OFFSET ss,SS-RIP*/
CFI_ R E L _ O F F S E T r s p ,R S P - R I P
/*CFI_REL_OFFSET rflags,EFLAGS-RIP*/
/*CFI_REL_OFFSET cs,CS-RIP*/
CFI_ R E L _ O F F S E T r i p ,R I P - R I P
2008-07-08 15:06:28 -07:00
PARAVIRT_ A D J U S T _ E X C E P T I O N _ F R A M E
2008-06-25 00:19:29 -04:00
SWAPGS
2006-07-03 00:24:45 -07:00
/ *
* No n e e d t o f o l l o w t h i s i r q s o n / o f f s e c t i o n : t h e s y s c a l l
* disabled i r q s a n d h e r e w e e n a b l e i t s t r a i g h t a f t e r e n t r y :
* /
2008-06-25 00:19:29 -04:00
ENABLE_ I N T E R R U P T S ( C L B R _ N O N E )
2005-04-16 15:20:36 -07:00
movl % e a x ,% e a x
2011-02-28 15:54:40 +00:00
pushq_ c f i % r a x
2005-04-16 15:20:36 -07:00
cld
/ * note t h e r e g i s t e r s a r e n o t z e r o e x t e n d e d t o t h e s f .
this c o u l d b e a p r o b l e m . * /
2011-05-31 22:21:52 +02:00
SAVE_ A R G S 0 ,1 ,0
2011-11-29 11:17:45 +00:00
orl $ T S _ C O M P A T ,T I _ s t a t u s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
testl $ _ T I F _ W O R K _ S Y S C A L L _ E N T R Y ,T I _ f l a g s + T H R E A D _ I N F O ( % r s p ,R I P - A R G O F F S E T )
2005-04-16 15:20:36 -07:00
jnz i a32 _ t r a c e s y s
x86-64, compat: Test %rax for the syscall number, not %eax
On 64 bits, we always, by necessity, jump through the system call
table via %rax. For 32-bit system calls, in theory the system call
number is stored in %eax, and the code was testing %eax for a valid
system call number. At one point we loaded the stored value back from
the stack to enforce zero-extension, but that was removed in checkin
d4d67150165df8bf1cc05e532f6efca96f907cab. An actual 32-bit process
will not be able to introduce a non-zero-extended number, but it can
happen via ptrace.
Instead of re-introducing the zero-extension, test what we are
actually going to use, i.e. %rax. This only adds a handful of REX
prefixes to the code.
Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@kernel.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
2010-09-14 12:42:41 -07:00
cmpq $ ( I A 3 2 _ N R _ s y s c a l l s - 1 ) ,% r a x
2009-02-06 18:15:18 -08:00
ja i a32 _ b a d s y s
ia32_do_call :
2005-04-16 15:20:36 -07:00
IA3 2 _ A R G _ F I X U P
call * i a32 _ s y s _ c a l l _ t a b l e ( ,% r a x ,8 ) # x x x : r i p r e l a t i v e
ia32_sysret :
movq % r a x ,R A X - A R G O F F S E T ( % r s p )
2009-09-30 11:22:11 +01:00
ia32_ret_from_sys_call :
CLEAR_ R R E G S - A R G O F F S E T
2005-04-16 15:20:36 -07:00
jmp i n t _ r e t _ f r o m _ s y s _ c a l l
ia32_tracesys :
SAVE_ R E S T
2007-07-21 17:10:20 +02:00
CLEAR_ R R E G S
2008-03-16 21:57:41 -07:00
movq $ - E N O S Y S ,R A X ( % r s p ) / * p t r a c e c a n c h a n g e t h i s f o r a b a d s y s c a l l * /
2005-04-16 15:20:36 -07:00
movq % r s p ,% r d i / * & p t _ r e g s - > a r g 1 * /
call s y s c a l l _ t r a c e _ e n t e r
2007-09-21 16:16:18 +02:00
LOAD_ A R G S 3 2 A R G O F F S E T / * r e l o a d a r g s f r o m s t a c k i n c a s e p t r a c e c h a n g e d i t * /
2005-04-16 15:20:36 -07:00
RESTORE_ R E S T
x86-64, compat: Test %rax for the syscall number, not %eax
On 64 bits, we always, by necessity, jump through the system call
table via %rax. For 32-bit system calls, in theory the system call
number is stored in %eax, and the code was testing %eax for a valid
system call number. At one point we loaded the stored value back from
the stack to enforce zero-extension, but that was removed in checkin
d4d67150165df8bf1cc05e532f6efca96f907cab. An actual 32-bit process
will not be able to introduce a non-zero-extended number, but it can
happen via ptrace.
Instead of re-introducing the zero-extension, test what we are
actually going to use, i.e. %rax. This only adds a handful of REX
prefixes to the code.
Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: <stable@kernel.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
2010-09-14 12:42:41 -07:00
cmpq $ ( I A 3 2 _ N R _ s y s c a l l s - 1 ) ,% r a x
2009-02-06 18:15:18 -08:00
ja i n t _ r e t _ f r o m _ s y s _ c a l l / * i a32 _ t r a c e s y s h a s s e t R A X ( % r s p ) * /
jmp i a32 _ d o _ c a l l
2006-06-26 13:56:55 +02:00
END( i a32 _ s y s c a l l )
2005-04-16 15:20:36 -07:00
ia32_badsys :
movq $ 0 ,O R I G _ R A X - A R G O F F S E T ( % r s p )
2009-09-30 11:22:11 +01:00
movq $ - E N O S Y S ,% r a x
jmp i a32 _ s y s r e t
2005-04-16 15:20:36 -07:00
CFI_ E N D P R O C
.macro PTREGSCALL label, f u n c , a r g
2011-11-29 11:24:10 +00:00
ALIGN
GLOBAL( \ l a b e l )
2005-04-16 15:20:36 -07:00
leaq \ f u n c ( % r i p ) ,% r a x
leaq - A R G O F F S E T + 8 ( % r s p ) ,\ a r g / * 8 f o r r e t u r n a d d r e s s * /
jmp i a32 _ p t r e g s _ c o m m o n
.endm
2006-01-11 22:41:59 +01:00
CFI_ S T A R T P R O C 3 2
2005-09-12 18:49:24 +02:00
2005-04-16 15:20:36 -07:00
PTREGSCALL s t u b32 _ r t _ s i g r e t u r n , s y s32 _ r t _ s i g r e t u r n , % r d i
PTREGSCALL s t u b32 _ s i g r e t u r n , s y s32 _ s i g r e t u r n , % r d i
PTREGSCALL s t u b32 _ s i g a l t s t a c k , s y s32 _ s i g a l t s t a c k , % r d x
PTREGSCALL s t u b32 _ e x e c v e , s y s32 _ e x e c v e , % r c x
PTREGSCALL s t u b32 _ f o r k , s y s _ f o r k , % r d i
PTREGSCALL s t u b32 _ c l o n e , s y s32 _ c l o n e , % r d x
PTREGSCALL s t u b32 _ v f o r k , s y s _ v f o r k , % r d i
PTREGSCALL s t u b32 _ i o p l , s y s _ i o p l , % r s i
2011-11-29 11:24:10 +00:00
ALIGN
ia32_ptregs_common :
2005-04-16 15:20:36 -07:00
popq % r11
2006-01-11 22:41:59 +01:00
CFI_ E N D P R O C
CFI_ S T A R T P R O C 3 2 s i m p l e
2006-09-26 10:52:41 +02:00
CFI_ S I G N A L _ F R A M E
2006-01-11 22:41:59 +01:00
CFI_ D E F _ C F A r s p ,S S + 8 - A R G O F F S E T
CFI_ R E L _ O F F S E T r a x ,R A X - A R G O F F S E T
CFI_ R E L _ O F F S E T r c x ,R C X - A R G O F F S E T
CFI_ R E L _ O F F S E T r d x ,R D X - A R G O F F S E T
CFI_ R E L _ O F F S E T r s i ,R S I - A R G O F F S E T
CFI_ R E L _ O F F S E T r d i ,R D I - A R G O F F S E T
CFI_ R E L _ O F F S E T r i p ,R I P - A R G O F F S E T
/* CFI_REL_OFFSET cs,CS-ARGOFFSET*/
/* CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/
CFI_ R E L _ O F F S E T r s p ,R S P - A R G O F F S E T
/* CFI_REL_OFFSET ss,SS-ARGOFFSET*/
2005-04-16 15:20:36 -07:00
SAVE_ R E S T
call * % r a x
RESTORE_ R E S T
jmp i a32 _ s y s r e t / * m i s b a l a n c e s t h e r e t u r n c a c h e * /
CFI_ E N D P R O C
2006-06-26 13:56:55 +02:00
END( i a32 _ p t r e g s _ c o m m o n )