2005-04-17 02:20:36 +04:00
/ *
* linux/ a r c h / i 3 8 6 / e n t r y . S
*
* Copyright ( C ) 1 9 9 1 , 1 9 9 2 L i n u s T o r v a l d s
* /
/ *
* entry. S c o n t a i n s t h e s y s t e m - c a l l a n d f a u l t l o w - l e v e l h a n d l i n g r o u t i n e s .
* This a l s o c o n t a i n s t h e t i m e r - i n t e r r u p t h a n d l e r , a s w e l l a s a l l i n t e r r u p t s
* and f a u l t s t h a t c a n r e s u l t i n a t a s k - s w i t c h .
*
* NOTE : This c o d e h a n d l e s s i g n a l - r e c o g n i t i o n , w h i c h h a p p e n s e v e r y t i m e
* after a t i m e r - i n t e r r u p t a n d a f t e r e a c h s y s t e m c a l l .
*
* I c h a n g e d a l l t h e . a l i g n ' s t o 4 ( 1 6 b y t e a l i g n m e n t ) , a s t h a t ' s f a s t e r
* on a 4 8 6 .
*
* Stack l a y o u t i n ' r e t _ f r o m _ s y s t e m _ c a l l ' :
* ptrace n e e d s t o h a v e a l l r e g s o n t h e s t a c k .
* if t h e o r d e r h e r e i s c h a n g e d , i t n e e d s t o b e
* updated i n f o r k . c : c o p y _ p r o c e s s , s i g n a l . c : d o _ s i g n a l ,
* ptrace. c a n d p t r a c e . h
*
* 0 ( % esp) - % e b x
* 4 ( % esp) - % e c x
* 8 ( % esp) - % e d x
* C( % e s p ) - % e s i
* 1 0 ( % esp) - % e d i
* 1 4 ( % esp) - % e b p
* 1 8 ( % esp) - % e a x
* 1 C( % e s p ) - % d s
* 2 0 ( % esp) - % e s
* 2 4 ( % esp) - o r i g _ e a x
* 2 8 ( % esp) - % e i p
* 2 C( % e s p ) - % c s
* 3 0 ( % esp) - % e f l a g s
* 3 4 ( % esp) - % o l d e s p
* 3 8 ( % esp) - % o l d s s
*
* " current" i s i n r e g i s t e r % e b x d u r i n g a n y s l o w e n t r i e s .
* /
# include < l i n u x / c o n f i g . h >
# include < l i n u x / l i n k a g e . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / e r r n o . h >
# include < a s m / s e g m e n t . h >
# include < a s m / s m p . h >
# include < a s m / p a g e . h >
# include < a s m / d e s c . h >
# include " i r q _ v e c t o r s . h "
# define n r _ s y s c a l l s ( ( s y s c a l l _ t a b l e _ s i z e ) / 4 )
EBX = 0 x00
ECX = 0 x04
EDX = 0 x08
ESI = 0 x0 C
EDI = 0 x10
EBP = 0 x14
EAX = 0 x18
DS = 0 x1 C
ES = 0 x20
ORIG_ E A X = 0 x24
EIP = 0 x28
CS = 0 x2 C
EFLAGS = 0 x30
OLDESP = 0 x34
OLDSS = 0 x38
CF_ M A S K = 0 x00 0 0 0 0 0 1
TF_ M A S K = 0 x00 0 0 0 1 0 0
IF_ M A S K = 0 x00 0 0 0 2 0 0
DF_ M A S K = 0 x00 0 0 0 4 0 0
NT_ M A S K = 0 x00 0 0 4 0 0 0
VM_ M A S K = 0 x00 0 2 0 0 0 0
# ifdef C O N F I G _ P R E E M P T
# define p r e e m p t _ s t o p c l i
# else
# define p r e e m p t _ s t o p
# define r e s u m e _ k e r n e l r e s t o r e _ n o c h e c k
# endif
# define S A V E _ A L L \
cld; \
pushl % e s ; \
pushl % d s ; \
pushl % e a x ; \
pushl % e b p ; \
pushl % e d i ; \
pushl % e s i ; \
pushl % e d x ; \
pushl % e c x ; \
pushl % e b x ; \
movl $ ( _ _ U S E R _ D S ) , % e d x ; \
movl % e d x , % d s ; \
movl % e d x , % e s ;
# define R E S T O R E _ I N T _ R E G S \
popl % e b x ; \
popl % e c x ; \
popl % e d x ; \
popl % e s i ; \
popl % e d i ; \
popl % e b p ; \
popl % e a x
# define R E S T O R E _ R E G S \
RESTORE_ I N T _ R E G S ; \
1 : popl % d s ; \
2 : popl % e s ; \
.section .fixup , " ax" ; \
3 : movl $ 0 ,( % e s p ) ; \
jmp 1 b ; \
4 : movl $ 0 ,( % e s p ) ; \
jmp 2 b ; \
.previous ; \
.section _ _ ex_ t a b l e ," a " ;\
.align 4 ; \
.long 1 b,3 b ; \
.long 2 b,4 b ; \
.previous
ENTRY( r e t _ f r o m _ f o r k )
pushl % e a x
call s c h e d u l e _ t a i l
GET_ T H R E A D _ I N F O ( % e b p )
popl % e a x
jmp s y s c a l l _ e x i t
/ *
* Return t o u s e r m o d e i s n o t a s c o m p l e x a s a l l t h i s l o o k s ,
* but w e w a n t t h e d e f a u l t p a t h f o r a s y s t e m c a l l r e t u r n t o
* go a s q u i c k l y a s p o s s i b l e w h i c h i s w h y s o m e o f t h i s i s
* less c l e a r t h a n i t o t h e r w i s e s h o u l d b e .
* /
# userspace r e s u m p t i o n s t u b b y p a s s i n g s y s c a l l e x i t t r a c i n g
ALIGN
ret_from_exception :
preempt_ s t o p
ret_from_intr :
GET_ T H R E A D _ I N F O ( % e b p )
movl E F L A G S ( % e s p ) , % e a x # m i x E F L A G S a n d C S
movb C S ( % e s p ) , % a l
testl $ ( V M _ M A S K | 3 ) , % e a x
jz r e s u m e _ k e r n e l
ENTRY( r e s u m e _ u s e r s p a c e )
cli # m a k e s u r e w e d o n ' t m i s s a n i n t e r r u p t
# setting n e e d _ r e s c h e d o r s i g p e n d i n g
# between s a m p l i n g a n d t h e i r e t
movl T I _ f l a g s ( % e b p ) , % e c x
andl $ _ T I F _ W O R K _ M A S K , % e c x # i s t h e r e a n y w o r k t o b e d o n e o n
# int/ e x c e p t i o n r e t u r n ?
jne w o r k _ p e n d i n g
jmp r e s t o r e _ a l l
# ifdef C O N F I G _ P R E E M P T
ENTRY( r e s u m e _ k e r n e l )
cli
cmpl $ 0 ,T I _ p r e e m p t _ c o u n t ( % e b p ) # n o n - z e r o p r e e m p t _ c o u n t ?
jnz r e s t o r e _ n o c h e c k
need_resched :
movl T I _ f l a g s ( % e b p ) , % e c x # n e e d _ r e s c h e d s e t ?
testb $ _ T I F _ N E E D _ R E S C H E D , % c l
jz r e s t o r e _ a l l
testl $ I F _ M A S K ,E F L A G S ( % e s p ) # i n t e r r u p t s o f f ( e x c e p t i o n p a t h ) ?
jz r e s t o r e _ a l l
call p r e e m p t _ s c h e d u l e _ i r q
jmp n e e d _ r e s c h e d
# endif
/ * SYSENTER_ R E T U R N p o i n t s t o a f t e r t h e " s y s e n t e r " i n s t r u c t i o n i n
the v s y s c a l l p a g e . S e e v s y s c a l l - s y s e n t r y . S , w h i c h d e f i n e s t h e s y m b o l . * /
# sysenter c a l l h a n d l e r s t u b
ENTRY( s y s e n t e r _ e n t r y )
movl T S S _ s y s e n t e r _ e s p0 ( % e s p ) ,% e s p
sysenter_past_esp :
sti
pushl $ ( _ _ U S E R _ D S )
pushl % e b p
pushfl
pushl $ ( _ _ U S E R _ C S )
pushl $ S Y S E N T E R _ R E T U R N
/ *
* Load t h e p o t e n t i a l s i x t h a r g u m e n t f r o m u s e r s t a c k .
* Careful a b o u t s e c u r i t y .
* /
cmpl $ _ _ P A G E _ O F F S E T - 3 ,% e b p
jae s y s c a l l _ f a u l t
1 : movl ( % e b p ) ,% e b p
.section _ _ ex_ t a b l e ," a "
.align 4
.long 1 b,s y s c a l l _ f a u l t
.previous
pushl % e a x
SAVE_ A L L
GET_ T H R E A D _ I N F O ( % e b p )
/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
testw $ ( _ T I F _ S Y S C A L L _ T R A C E | _ T I F _ S Y S C A L L _ A U D I T | _ T I F _ S E C C O M P ) ,T I _ f l a g s ( % e b p )
jnz s y s c a l l _ t r a c e _ e n t r y
cmpl $ ( n r _ s y s c a l l s ) , % e a x
jae s y s c a l l _ b a d s y s
call * s y s _ c a l l _ t a b l e ( ,% e a x ,4 )
movl % e a x ,E A X ( % e s p )
cli
movl T I _ f l a g s ( % e b p ) , % e c x
testw $ _ T I F _ A L L W O R K _ M A S K , % c x
jne s y s c a l l _ e x i t _ w o r k
/* if something modifies registers it must also disable sysexit */
movl E I P ( % e s p ) , % e d x
movl O L D E S P ( % e s p ) , % e c x
xorl % e b p ,% e b p
sti
sysexit
# system c a l l h a n d l e r s t u b
ENTRY( s y s t e m _ c a l l )
pushl % e a x # s a v e o r i g _ e a x
SAVE_ A L L
GET_ T H R E A D _ I N F O ( % e b p )
# system c a l l t r a c i n g i n o p e r a t i o n
/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
testw $ ( _ T I F _ S Y S C A L L _ T R A C E | _ T I F _ S Y S C A L L _ A U D I T | _ T I F _ S E C C O M P ) ,T I _ f l a g s ( % e b p )
jnz s y s c a l l _ t r a c e _ e n t r y
cmpl $ ( n r _ s y s c a l l s ) , % e a x
jae s y s c a l l _ b a d s y s
syscall_call :
call * s y s _ c a l l _ t a b l e ( ,% e a x ,4 )
movl % e a x ,E A X ( % e s p ) # s t o r e t h e r e t u r n v a l u e
syscall_exit :
cli # m a k e s u r e w e d o n ' t m i s s a n i n t e r r u p t
# setting n e e d _ r e s c h e d o r s i g p e n d i n g
# between s a m p l i n g a n d t h e i r e t
movl T I _ f l a g s ( % e b p ) , % e c x
testw $ _ T I F _ A L L W O R K _ M A S K , % c x # c u r r e n t - > w o r k
jne s y s c a l l _ e x i t _ w o r k
restore_all :
movl E F L A G S ( % e s p ) , % e a x # m i x E F L A G S , S S a n d C S
2005-04-17 02:24:01 +04:00
# Warning : OLDSS( % e s p ) c o n t a i n s t h e w r o n g / r a n d o m v a l u e s i f w e
# are r e t u r n i n g t o t h e k e r n e l .
# See c o m m e n t s i n p r o c e s s . c : c o p y _ t h r e a d ( ) f o r d e t a i l s .
2005-04-17 02:20:36 +04:00
movb O L D S S ( % e s p ) , % a h
movb C S ( % e s p ) , % a l
andl $ ( V M _ M A S K | ( 4 < < 8 ) | 3 ) , % e a x
cmpl $ ( ( 4 < < 8 ) | 3 ) , % e a x
je l d t _ s s # r e t u r n i n g t o u s e r - s p a c e w i t h L D T S S
restore_nocheck :
RESTORE_ R E G S
addl $ 4 , % e s p
1 : iret
.section .fixup , " ax"
iret_exc :
sti
2005-04-29 20:38:44 +04:00
pushl $ 0 # n o e r r o r c o d e
pushl $ d o _ i r e t _ e r r o r
jmp e r r o r _ c o d e
2005-04-17 02:20:36 +04:00
.previous
.section _ _ ex_ t a b l e ," a "
.align 4
.long 1 b,i r e t _ e x c
.previous
ldt_ss :
larl O L D S S ( % e s p ) , % e a x
jnz r e s t o r e _ n o c h e c k
testl $ 0 x00 4 0 0 0 0 0 , % e a x # r e t u r n i n g t o 32 b i t s t a c k ?
jnz r e s t o r e _ n o c h e c k # a l l r i g h t , n o r m a l r e t u r n
/ * If r e t u r n i n g t o u s e r s p a c e w i t h 1 6 b i t s t a c k ,
* try t o f i x t h e h i g h e r w o r d o f E S P , a s t h e C P U
* won' t r e s t o r e i t .
* This i s a n " o f f i c i a l " b u g o f a l l t h e x86 - c o m p a t i b l e
* CPUs, w h i c h w e c a n t r y t o w o r k a r o u n d t o m a k e
* dosemu a n d w i n e h a p p y . * /
subl $ 8 , % e s p # r e s e r v e s p a c e f o r s w i t c h 16 p o i n t e r
cli
movl % e s p , % e a x
/ * Set u p t h e 1 6 b i t s t a c k f r a m e w i t h s w i t c h32 p o i n t e r o n t o p ,
* and a s w i t c h16 p o i n t e r o n t o p o f t h e c u r r e n t f r a m e . * /
call s e t u p _ x86 _ b o g u s _ s t a c k
RESTORE_ R E G S
lss 2 0 + 4 ( % e s p ) , % e s p # s w i t c h t o 16 b i t s t a c k
1 : iret
.section _ _ ex_ t a b l e ," a "
.align 4
.long 1 b,i r e t _ e x c
.previous
# perform w o r k t h a t n e e d s t o b e d o n e i m m e d i a t e l y b e f o r e r e s u m p t i o n
ALIGN
work_pending :
testb $ _ T I F _ N E E D _ R E S C H E D , % c l
jz w o r k _ n o t i f y s i g
work_resched :
call s c h e d u l e
cli # m a k e s u r e w e d o n ' t m i s s a n i n t e r r u p t
# setting n e e d _ r e s c h e d o r s i g p e n d i n g
# between s a m p l i n g a n d t h e i r e t
movl T I _ f l a g s ( % e b p ) , % e c x
andl $ _ T I F _ W O R K _ M A S K , % e c x # i s t h e r e a n y w o r k t o b e d o n e o t h e r
# than s y s c a l l t r a c i n g ?
jz r e s t o r e _ a l l
testb $ _ T I F _ N E E D _ R E S C H E D , % c l
jnz w o r k _ r e s c h e d
work_notifysig : # deal w i t h p e n d i n g s i g n a l s a n d
# notify- r e s u m e r e q u e s t s
testl $ V M _ M A S K , E F L A G S ( % e s p )
movl % e s p , % e a x
jne w o r k _ n o t i f y s i g _ v86 # r e t u r n i n g t o k e r n e l - s p a c e o r
# vm8 6 - s p a c e
xorl % e d x , % e d x
call d o _ n o t i f y _ r e s u m e
jmp r e s t o r e _ a l l
ALIGN
work_notifysig_v86 :
pushl % e c x # s a v e t i _ f l a g s f o r d o _ n o t i f y _ r e s u m e
call s a v e _ v86 _ s t a t e # % e a x c o n t a i n s p t _ r e g s p o i n t e r
popl % e c x
movl % e a x , % e s p
xorl % e d x , % e d x
call d o _ n o t i f y _ r e s u m e
jmp r e s t o r e _ a l l
# perform s y s c a l l e x i t t r a c i n g
ALIGN
syscall_trace_entry :
movl $ - E N O S Y S ,E A X ( % e s p )
movl % e s p , % e a x
xorl % e d x ,% e d x
call d o _ s y s c a l l _ t r a c e
movl O R I G _ E A X ( % e s p ) , % e a x
cmpl $ ( n r _ s y s c a l l s ) , % e a x
jnae s y s c a l l _ c a l l
jmp s y s c a l l _ e x i t
# perform s y s c a l l e x i t t r a c i n g
ALIGN
syscall_exit_work :
testb $ ( _ T I F _ S Y S C A L L _ T R A C E | _ T I F _ S Y S C A L L _ A U D I T | _ T I F _ S I N G L E S T E P ) , % c l
jz w o r k _ p e n d i n g
sti # c o u l d l e t d o _ s y s c a l l _ t r a c e ( ) c a l l
# schedule( ) i n s t e a d
movl % e s p , % e a x
movl $ 1 , % e d x
call d o _ s y s c a l l _ t r a c e
jmp r e s u m e _ u s e r s p a c e
ALIGN
syscall_fault :
pushl % e a x # s a v e o r i g _ e a x
SAVE_ A L L
GET_ T H R E A D _ I N F O ( % e b p )
movl $ - E F A U L T ,E A X ( % e s p )
jmp r e s u m e _ u s e r s p a c e
ALIGN
syscall_badsys :
movl $ - E N O S Y S ,E A X ( % e s p )
jmp r e s u m e _ u s e r s p a c e
# define F I X U P _ E S P F I X _ S T A C K \
movl % e s p , % e a x ; \
/* switch to 32bit stack using the pointer on top of 16bit stack */ \
lss % s s : C P U _ 1 6 B I T _ S T A C K _ S I Z E - 8 , % e s p ; \
/* copy data from 16bit stack to 32bit stack */ \
call f i x u p _ x86 _ b o g u s _ s t a c k ; \
/* put ESP to the proper location */ \
movl % e a x , % e s p ;
# define U N W I N D _ E S P F I X _ S T A C K \
pushl % e a x ; \
movl % s s , % e a x ; \
/* see if on 16bit stack */ \
cmpw $ _ _ E S P F I X _ S S , % a x ; \
jne 2 8 f ; \
movl $ _ _ K E R N E L _ D S , % e d x ; \
movl % e d x , % d s ; \
movl % e d x , % e s ; \
/* switch to 32bit stack */ \
FIXUP_ E S P F I X _ S T A C K \
28 : popl % e a x ;
/ *
* Build t h e e n t r y s t u b s a n d p o i n t e r t a b l e w i t h
* some a s s e m b l e r m a g i c .
* /
.data
ENTRY( i n t e r r u p t )
.text
vector=0
ENTRY( i r q _ e n t r i e s _ s t a r t )
.rept NR_IRQS
ALIGN
1 : pushl $ v e c t o r - 2 5 6
jmp c o m m o n _ i n t e r r u p t
.data
.long 1b
.text
vector=vector + 1
.endr
ALIGN
common_interrupt :
SAVE_ A L L
movl % e s p ,% e a x
call d o _ I R Q
jmp r e t _ f r o m _ i n t r
# define B U I L D _ I N T E R R U P T ( n a m e , n r ) \
ENTRY( n a m e ) \
pushl $ n r - 2 5 6 ; \
SAVE_ A L L \
movl % e s p ,% e a x ; \
call s m p _ / * * / n a m e ; \
jmp r e t _ f r o m _ i n t r ;
/* The include is where all of the SMP etc. interrupts come from */
# include " e n t r y _ a r c h . h "
ENTRY( d i v i d e _ e r r o r )
pushl $ 0 # n o e r r o r c o d e
pushl $ d o _ d i v i d e _ e r r o r
ALIGN
error_code :
pushl % d s
pushl % e a x
xorl % e a x , % e a x
pushl % e b p
pushl % e d i
pushl % e s i
pushl % e d x
decl % e a x # e a x = - 1
pushl % e c x
pushl % e b x
cld
pushl % e s
UNWIND_ E S P F I X _ S T A C K
popl % e c x
movl E S ( % e s p ) , % e d i # g e t t h e f u n c t i o n a d d r e s s
movl O R I G _ E A X ( % e s p ) , % e d x # g e t t h e e r r o r c o d e
movl % e a x , O R I G _ E A X ( % e s p )
movl % e c x , E S ( % e s p )
movl $ ( _ _ U S E R _ D S ) , % e c x
movl % e c x , % d s
movl % e c x , % e s
movl % e s p ,% e a x # p t _ r e g s p o i n t e r
call * % e d i
jmp r e t _ f r o m _ e x c e p t i o n
ENTRY( c o p r o c e s s o r _ e r r o r )
pushl $ 0
pushl $ d o _ c o p r o c e s s o r _ e r r o r
jmp e r r o r _ c o d e
ENTRY( s i m d _ c o p r o c e s s o r _ e r r o r )
pushl $ 0
pushl $ d o _ s i m d _ c o p r o c e s s o r _ e r r o r
jmp e r r o r _ c o d e
ENTRY( d e v i c e _ n o t _ a v a i l a b l e )
pushl $ - 1 # m a r k t h i s a s a n i n t
SAVE_ A L L
movl % c r0 , % e a x
testl $ 0 x4 , % e a x # E M ( m a t h e m u l a t i o n b i t )
jne d e v i c e _ n o t _ a v a i l a b l e _ e m u l a t e
preempt_ s t o p
call m a t h _ s t a t e _ r e s t o r e
jmp r e t _ f r o m _ e x c e p t i o n
device_not_available_emulate :
pushl $ 0 # t e m p o r a r y s t o r a g e f o r O R I G _ E I P
call m a t h _ e m u l a t e
addl $ 4 , % e s p
jmp r e t _ f r o m _ e x c e p t i o n
/ *
* Debug t r a p s a n d N M I c a n h a p p e n a t t h e o n e S Y S E N T E R i n s t r u c t i o n
* that s e t s u p t h e r e a l k e r n e l s t a c k . C h e c k h e r e , s i n c e w e c a n ' t
* allow t h e w r o n g s t a c k t o b e u s e d .
*
* " TSS_ s y s e n t e r _ e s p0 + 1 2 " i s b e c a u s e t h e N M I / d e b u g h a n d l e r w i l l h a v e
* already p u s h e d 3 w o r d s i f i t h i t s o n t h e s y s e n t e r i n s t r u c t i o n :
* eflags, c s a n d e i p .
*
* We j u s t l o a d t h e r i g h t s t a c k , a n d p u s h t h e t h r e e ( k n o w n ) v a l u e s
* by h a n d o n t o t h e n e w s t a c k - w h i l e u p d a t i n g t h e r e t u r n e i p p a s t
* the i n s t r u c t i o n t h a t w o u l d h a v e d o n e i t f o r s y s e n t e r .
* /
# define F I X _ S T A C K ( o f f s e t , o k , l a b e l ) \
cmpw $ _ _ K E R N E L _ C S ,4 ( % e s p ) ; \
jne o k ; \
label : \
movl T S S _ s y s e n t e r _ e s p0 + o f f s e t ( % e s p ) ,% e s p ; \
pushfl; \
pushl $ _ _ K E R N E L _ C S ; \
pushl $ s y s e n t e r _ p a s t _ e s p
ENTRY( d e b u g )
cmpl $ s y s e n t e r _ e n t r y ,( % e s p )
jne d e b u g _ s t a c k _ c o r r e c t
FIX_ S T A C K ( 1 2 , d e b u g _ s t a c k _ c o r r e c t , d e b u g _ e s p _ f i x _ i n s n )
debug_stack_correct :
pushl $ - 1 # m a r k t h i s a s a n i n t
SAVE_ A L L
xorl % e d x ,% e d x # e r r o r c o d e 0
movl % e s p ,% e a x # p t _ r e g s p o i n t e r
call d o _ d e b u g
jmp r e t _ f r o m _ e x c e p t i o n
/ *
* NMI i s d o u b l y n a s t y . I t c a n h a p p e n _ w h i l e _ w e ' r e h a n d l i n g
* a d e b u g f a u l t , a n d t h e d e b u g f a u l t h a s n ' t y e t b e e n a b l e t o
* clear u p t h e s t a c k . S o w e f i r s t c h e c k w h e t h e r w e g o t a n
* NMI o n t h e s y s e n t e r e n t r y p a t h , b u t a f t e r t h a t w e n e e d t o
* check w h e t h e r w e g o t a n N M I o n t h e d e b u g p a t h w h e r e t h e d e b u g
* fault h a p p e n e d o n t h e s y s e n t e r p a t h .
* /
ENTRY( n m i )
pushl % e a x
movl % s s , % e a x
cmpw $ _ _ E S P F I X _ S S , % a x
popl % e a x
je n m i _ 1 6 b i t _ s t a c k
cmpl $ s y s e n t e r _ e n t r y ,( % e s p )
je n m i _ s t a c k _ f i x u p
pushl % e a x
movl % e s p ,% e a x
/ * Do n o t a c c e s s m e m o r y a b o v e t h e e n d o f o u r s t a c k p a g e ,
* it m i g h t n o t e x i s t .
* /
andl $ ( T H R E A D _ S I Z E - 1 ) ,% e a x
cmpl $ ( T H R E A D _ S I Z E - 2 0 ) ,% e a x
popl % e a x
jae n m i _ s t a c k _ c o r r e c t
cmpl $ s y s e n t e r _ e n t r y ,1 2 ( % e s p )
je n m i _ d e b u g _ s t a c k _ c h e c k
nmi_stack_correct :
pushl % e a x
SAVE_ A L L
xorl % e d x ,% e d x # z e r o e r r o r c o d e
movl % e s p ,% e a x # p t _ r e g s p o i n t e r
call d o _ n m i
jmp r e s t o r e _ a l l
nmi_stack_fixup :
FIX_ S T A C K ( 1 2 ,n m i _ s t a c k _ c o r r e c t , 1 )
jmp n m i _ s t a c k _ c o r r e c t
nmi_debug_stack_check :
cmpw $ _ _ K E R N E L _ C S ,1 6 ( % e s p )
jne n m i _ s t a c k _ c o r r e c t
cmpl $ d e b u g - 1 ,( % e s p )
jle n m i _ s t a c k _ c o r r e c t
cmpl $ d e b u g _ e s p _ f i x _ i n s n ,( % e s p )
jle n m i _ d e b u g _ s t a c k _ f i x u p
nmi_debug_stack_fixup :
FIX_ S T A C K ( 2 4 ,n m i _ s t a c k _ c o r r e c t , 1 )
jmp n m i _ s t a c k _ c o r r e c t
nmi_16bit_stack :
/* create the pointer to lss back */
pushl % s s
pushl % e s p
movzwl % s p , % e s p
addw $ 4 , ( % e s p )
/* copy the iret frame of 12 bytes */
.rept 3
pushl 1 6 ( % e s p )
.endr
pushl % e a x
SAVE_ A L L
FIXUP_ E S P F I X _ S T A C K # % e a x = = % e s p
xorl % e d x ,% e d x # z e r o e r r o r c o d e
call d o _ n m i
RESTORE_ R E G S
lss 1 2 + 4 ( % e s p ) , % e s p # b a c k t o 16 b i t s t a c k
1 : iret
.section _ _ ex_ t a b l e ," a "
.align 4
.long 1 b,i r e t _ e x c
.previous
ENTRY( i n t 3 )
pushl $ - 1 # m a r k t h i s a s a n i n t
SAVE_ A L L
xorl % e d x ,% e d x # z e r o e r r o r c o d e
movl % e s p ,% e a x # p t _ r e g s p o i n t e r
call d o _ i n t 3
jmp r e t _ f r o m _ e x c e p t i o n
ENTRY( o v e r f l o w )
pushl $ 0
pushl $ d o _ o v e r f l o w
jmp e r r o r _ c o d e
ENTRY( b o u n d s )
pushl $ 0
pushl $ d o _ b o u n d s
jmp e r r o r _ c o d e
ENTRY( i n v a l i d _ o p )
pushl $ 0
pushl $ d o _ i n v a l i d _ o p
jmp e r r o r _ c o d e
ENTRY( c o p r o c e s s o r _ s e g m e n t _ o v e r r u n )
pushl $ 0
pushl $ d o _ c o p r o c e s s o r _ s e g m e n t _ o v e r r u n
jmp e r r o r _ c o d e
ENTRY( i n v a l i d _ T S S )
pushl $ d o _ i n v a l i d _ T S S
jmp e r r o r _ c o d e
ENTRY( s e g m e n t _ n o t _ p r e s e n t )
pushl $ d o _ s e g m e n t _ n o t _ p r e s e n t
jmp e r r o r _ c o d e
ENTRY( s t a c k _ s e g m e n t )
pushl $ d o _ s t a c k _ s e g m e n t
jmp e r r o r _ c o d e
ENTRY( g e n e r a l _ p r o t e c t i o n )
pushl $ d o _ g e n e r a l _ p r o t e c t i o n
jmp e r r o r _ c o d e
ENTRY( a l i g n m e n t _ c h e c k )
pushl $ d o _ a l i g n m e n t _ c h e c k
jmp e r r o r _ c o d e
ENTRY( p a g e _ f a u l t )
pushl $ d o _ p a g e _ f a u l t
jmp e r r o r _ c o d e
# ifdef C O N F I G _ X 8 6 _ M C E
ENTRY( m a c h i n e _ c h e c k )
pushl $ 0
pushl m a c h i n e _ c h e c k _ v e c t o r
jmp e r r o r _ c o d e
# endif
ENTRY( s p u r i o u s _ i n t e r r u p t _ b u g )
pushl $ 0
pushl $ d o _ s p u r i o u s _ i n t e r r u p t _ b u g
jmp e r r o r _ c o d e
2005-05-01 19:58:55 +04:00
# include " s y s c a l l _ t a b l e . S "
2005-04-17 02:20:36 +04:00
syscall_ t a b l e _ s i z e = ( . - s y s _ c a l l _ t a b l e )