2008-07-09 02:06:46 +04:00
/ *
2009-02-05 18:57:48 +03: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-09 02:06:46 +04:00
* /
2008-07-09 02:07:14 +04:00
# include < a s m / e r r n o . h >
2009-01-18 18:38:58 +03:00
# include < a s m / p e r c p u . h >
2009-02-03 00:55:42 +03: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 >
2015-04-24 18:31:33 +03:00
# include < a s m / a s m - o f f s e t s . h >
2015-04-24 18:31:35 +03:00
# include < a s m / t h r e a d _ i n f o . h >
2008-07-09 02:06:46 +04:00
# include < x e n / i n t e r f a c e / x e n . h >
2009-02-03 00:55:42 +03:00
# include " x e n - a s m . h "
2008-07-09 02:06:46 +04:00
2008-07-09 02:07:00 +04: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-05 18:57:48 +03:00
mov 8 + 0 ( % r s p ) , % r c x
mov 8 + 8 ( % r s p ) , % r11
2008-07-09 02:07:00 +04:00
ret $ 1 6
2008-07-09 02:07:14 +04: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-05 18:57:48 +03: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-09 02:07:14 +04:00
* /
2008-07-09 02:06:46 +04:00
ENTRY( x e n _ i r e t )
pushq $ 0
2008-07-09 02:07:14 +04: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-09 02:06:46 +04:00
2008-07-09 02:07:14 +04:00
ENTRY( x e n _ s y s r e t 6 4 )
2009-02-05 18:57:48 +03: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
* /
2015-03-17 16:42:59 +03:00
movq % r s p , P E R _ C P U _ V A R ( r s p _ s c r a t c h )
2015-04-24 18:31:35 +03:00
movq P E R _ C P U _ V A R ( c p u _ c u r r e n t _ t o p _ o f _ s t a c k ) , % r s p
2008-07-09 02:07:14 +04:00
pushq $ _ _ U S E R _ D S
2015-03-17 16:42:59 +03:00
pushq P E R _ C P U _ V A R ( r s p _ s c r a t c h )
2008-07-09 02:07:14 +04: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-05 18:57:48 +03: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
* /
2015-03-17 16:42:59 +03:00
movq % r s p , P E R _ C P U _ V A R ( r s p _ s c r a t c h )
2015-04-24 18:31:35 +03:00
movq P E R _ C P U _ V A R ( c p u _ c u r r e n t _ t o p _ o f _ s t a c k ) , % r s p
2008-07-09 02:07:14 +04:00
pushq $ _ _ U S E R 3 2 _ D S
2015-03-17 16:42:59 +03:00
pushq P E R _ C P U _ V A R ( r s p _ s c r a t c h )
2008-07-09 02:07:14 +04:00
pushq % r11
pushq $ _ _ U S E R 3 2 _ C S
pushq % r c x
2009-11-26 00:15:38 +03:00
pushq $ 0
2008-07-09 02:07:14 +04: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-05 18:57:48 +03: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-09 02:07:14 +04:00
* /
.macro undo_xen_syscall
2009-02-05 18:57:48 +03: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-09 02:07:14 +04: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
2015-06-08 09:28:07 +03:00
jmp e n t r y _ S Y S C A L L _ c o m p a t
2008-07-09 02:07:14 +04:00
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
2015-06-08 09:33:56 +03:00
jmp e n t r y _ S Y S E N T E R _ c o m p a t
2008-07-09 02:07:14 +04:00
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-05 18:57:48 +03:00
lea 1 6 ( % r s p ) , % r s p / * s t r i p % r c x , % r11 * /
2008-07-09 02:07:14 +04:00
mov $ - E N O S Y S , % r a x
2009-11-26 00:15:38 +03:00
pushq $ 0
2008-07-09 02:07:14 +04: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 * /