2008-07-08 15:06:46 -07:00
/ *
2009-02-06 00:57:48 +09:00
* Asm v e r s i o n s o f X e n p v - o p s , s u i t a b l e f o r e i t h e r d i r e c t u s e o r
* inlining. T h e i n l i n e v e r s i o n s a r e t h e s a m e a s t h e d i r e c t - u s e
* versions, w i t h t h e p r e - a n d p o s t - a m b l e c h o p p e d o f f .
*
* This c o d e i s e n c o d e d f o r s i z e r a t h e r t h a n a b s o l u t e e f f i c i e n c y , w i t h
* a v i e w t o b e i n g a b l e t o i n l i n e a s m u c h a s p o s s i b l e .
*
* We o n l y b o t h e r w i t h d i r e c t f o r m s ( i e , v c p u i n p d a ) o f t h e
* operations h e r e ; the indirect forms are better handled in C, since
* they' r e g e n e r a l l y t o o l a r g e t o i n l i n e a n y w a y .
2008-07-08 15:06:46 -07:00
* /
2008-07-08 15:07:14 -07:00
# include < a s m / e r r n o . h >
2009-01-19 00:38:58 +09:00
# include < a s m / p e r c p u . h >
2009-02-02 13:55:42 -08:00
# include < a s m / p r o c e s s o r - f l a g s . h >
# include < a s m / s e g m e n t . h >
2008-07-08 15:06:46 -07:00
# include < x e n / i n t e r f a c e / x e n . h >
2009-02-02 13:55:42 -08:00
# include " x e n - a s m . h "
2008-07-08 15:06:46 -07:00
2008-07-08 15:07:00 -07:00
ENTRY( x e n _ a d j u s t _ e x c e p t i o n _ f r a m e )
2009-02-06 00:57:48 +09:00
mov 8 + 0 ( % r s p ) , % r c x
mov 8 + 8 ( % r s p ) , % r11
2008-07-08 15:07:00 -07:00
ret $ 1 6
2008-07-08 15:07:14 -07:00
hypercall_ i r e t = h y p e r c a l l _ p a g e + _ _ H Y P E R V I S O R _ i r e t * 3 2
/ *
2009-02-06 00:57:48 +09:00
* Xen6 4 i r e t f r a m e :
*
* ss
* rsp
* rflags
* cs
* rip < - - s t a n d a r d i r e t f r a m e
*
* flags
*
* rcx }
* r1 1 } < - - p u s h e d b y h y p e r c a l l p a g e
* rsp- > r a x }
2008-07-08 15:07:14 -07:00
* /
2008-07-08 15:06:46 -07:00
ENTRY( x e n _ i r e t )
pushq $ 0
2008-07-08 15:07:14 -07:00
1 : jmp h y p e r c a l l _ i r e t
ENDPATCH( x e n _ i r e t )
RELOC( x e n _ i r e t , 1 b + 1 )
2008-07-08 15:06:46 -07:00
2008-07-08 15:07:14 -07:00
/ *
2009-02-06 00:57:48 +09:00
* sysexit i s n o t u s e d f o r 6 4 - b i t p r o c e s s e s , s o i t ' s o n l y e v e r u s e d t o
* return t o 3 2 - b i t c o m p a t u s e r s p a c e .
2008-07-08 15:07:14 -07:00
* /
2008-07-08 15:06:46 -07:00
ENTRY( x e n _ s y s e x i t )
2008-07-08 15:07:14 -07:00
pushq $ _ _ U S E R 3 2 _ D S
pushq % r c x
pushq $ X 8 6 _ E F L A G S _ I F
pushq $ _ _ U S E R 3 2 _ C S
pushq % r d x
2008-07-21 16:49:58 -07:00
pushq $ 0
2008-07-08 15:07:14 -07:00
1 : jmp h y p e r c a l l _ i r e t
ENDPATCH( x e n _ s y s e x i t )
RELOC( x e n _ s y s e x i t , 1 b + 1 )
ENTRY( x e n _ s y s r e t 6 4 )
2009-02-06 00:57:48 +09:00
/ *
* We' r e a l r e a d y o n t h e u s e r m o d e s t a c k a t t h i s p o i n t , b u t
* still w i t h t h e k e r n e l g s , s o w e c a n e a s i l y s w i t c h b a c k
* /
2009-01-19 00:38:58 +09:00
movq % r s p , P E R _ C P U _ V A R ( o l d _ r s p )
2009-02-06 00:57:48 +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
2008-07-08 15:07:14 -07:00
pushq $ _ _ U S E R _ D S
2009-01-19 00:38:58 +09:00
pushq P E R _ C P U _ V A R ( o l d _ r s p )
2008-07-08 15:07:14 -07:00
pushq % r11
pushq $ _ _ U S E R _ C S
pushq % r c x
pushq $ V G C F _ i n _ s y s c a l l
1 : jmp h y p e r c a l l _ i r e t
ENDPATCH( x e n _ s y s r e t 6 4 )
RELOC( x e n _ s y s r e t 6 4 , 1 b + 1 )
ENTRY( x e n _ s y s r e t 3 2 )
2009-02-06 00:57:48 +09:00
/ *
* We' r e a l r e a d y o n t h e u s e r m o d e s t a c k a t t h i s p o i n t , b u t
* still w i t h t h e k e r n e l g s , s o w e c a n e a s i l y s w i t c h b a c k
* /
2009-01-19 00:38:58 +09:00
movq % r s p , P E R _ C P U _ V A R ( o l d _ r s p )
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
2008-07-08 15:07:14 -07:00
pushq $ _ _ U S E R 3 2 _ D S
2009-01-19 00:38:58 +09:00
pushq P E R _ C P U _ V A R ( o l d _ r s p )
2008-07-08 15:07:14 -07:00
pushq % r11
pushq $ _ _ U S E R 3 2 _ C S
pushq % r c x
2009-11-25 13:15:38 -08:00
pushq $ 0
2008-07-08 15:07:14 -07:00
1 : jmp h y p e r c a l l _ i r e t
ENDPATCH( x e n _ s y s r e t 3 2 )
RELOC( x e n _ s y s r e t 3 2 , 1 b + 1 )
/ *
2009-02-06 00:57:48 +09:00
* Xen h a n d l e s s y s c a l l c a l l b a c k s m u c h l i k e o r d i n a r y e x c e p t i o n s , w h i c h
* means w e h a v e :
* - kernel g s
* - kernel r s p
* - an i r e t - l i k e s t a c k f r a m e o n t h e s t a c k ( i n c l u d i n g r c x a n d r11 ) :
* ss
* rsp
* rflags
* cs
* rip
* r1 1
* rsp- > r c x
*
* In a l l t h e e n t r y p o i n t s , w e u n d o a l l t h a t t o m a k e i t l o o k l i k e a
* CPU- g e n e r a t e d s y s c a l l / s y s e n t e r a n d j u m p t o t h e n o r m a l e n t r y p o i n t .
2008-07-08 15:07:14 -07:00
* /
.macro undo_xen_syscall
2009-02-06 00:57:48 +09:00
mov 0 * 8 ( % r s p ) , % r c x
mov 1 * 8 ( % r s p ) , % r11
mov 5 * 8 ( % r s p ) , % r s p
2008-07-08 15:07:14 -07:00
.endm
/* Normal 64-bit system call target */
ENTRY( x e n _ s y s c a l l _ t a r g e t )
undo_ x e n _ s y s c a l l
jmp s y s t e m _ c a l l _ a f t e r _ s w a p g s
ENDPROC( x e n _ s y s c a l l _ t a r g e t )
# ifdef C O N F I G _ I A 3 2 _ E M U L A T I O N
/* 32-bit compat syscall target */
ENTRY( x e n _ s y s c a l l 3 2 _ t a r g e t )
undo_ x e n _ s y s c a l l
jmp i a32 _ c s t a r _ t a r g e t
ENDPROC( x e n _ s y s c a l l 3 2 _ t a r g e t )
/* 32-bit compat sysenter target */
ENTRY( x e n _ s y s e n t e r _ t a r g e t )
undo_ x e n _ s y s c a l l
jmp i a32 _ s y s e n t e r _ t a r g e t
ENDPROC( x e n _ s y s e n t e r _ t a r g e t )
# else / * ! C O N F I G _ I A 3 2 _ E M U L A T I O N * /
ENTRY( x e n _ s y s c a l l 3 2 _ t a r g e t )
ENTRY( x e n _ s y s e n t e r _ t a r g e t )
2009-02-06 00:57:48 +09:00
lea 1 6 ( % r s p ) , % r s p / * s t r i p % r c x , % r11 * /
2008-07-08 15:07:14 -07:00
mov $ - E N O S Y S , % r a x
2009-11-25 13:15:38 -08:00
pushq $ 0
2008-07-08 15:07:14 -07:00
jmp h y p e r c a l l _ i r e t
ENDPROC( x e n _ s y s c a l l 3 2 _ t a r g e t )
ENDPROC( x e n _ s y s e n t e r _ t a r g e t )
# endif / * C O N F I G _ I A 3 2 _ E M U L A T I O N * /