2009-02-03 00:55:42 +03: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 e r c p u d a t 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 .
2009-02-03 00:55:42 +03:00
* /
# include < a s m / a s m - o f f s e t s . h >
# include < a s m / p e r c p u . h >
# include < a s m / p r o c e s s o r - f l a g s . h >
# include " x e n - a s m . h "
/ *
2009-02-05 18:57:48 +03:00
* Enable e v e n t s . T h i s c l e a r s t h e e v e n t m a s k a n d t e s t s t h e p e n d i n g
* event s t a t u s w i t h o n e a n d o p e r a t i o n . I f t h e r e a r e p e n d i n g e v e n t s ,
* then e n t e r t h e h y p e r v i s o r t o g e t t h e m h a n d l e d .
2009-02-03 00:55:42 +03:00
* /
ENTRY( x e n _ i r q _ e n a b l e _ d i r e c t )
/* Unmask events */
movb $ 0 , P E R _ C P U _ V A R ( x e n _ v c p u _ i n f o ) + X E N _ v c p u _ i n f o _ m a s k
2009-02-05 18:57:48 +03:00
/ *
* Preempt h e r e d o e s n ' t m a t t e r b e c a u s e t h a t w i l l d e a l w i t h a n y
* pending i n t e r r u p t s . T h e p e n d i n g c h e c k m a y e n d u p b e i n g r u n
* on t h e w r o n g C P U , b u t t h a t d o e s n ' t h u r t .
* /
2009-02-03 00:55:42 +03:00
/* Test for pending */
testb $ 0 x f f , P E R _ C P U _ V A R ( x e n _ v c p u _ i n f o ) + X E N _ v c p u _ i n f o _ p e n d i n g
jz 1 f
2 : call c h e c k _ e v e n t s
1 :
ENDPATCH( x e n _ i r q _ e n a b l e _ d i r e c t )
ret
ENDPROC( x e n _ i r q _ e n a b l e _ d i r e c t )
RELOC( x e n _ i r q _ e n a b l e _ d i r e c t , 2 b + 1 )
/ *
2009-02-05 18:57:48 +03:00
* Disabling e v e n t s i s s i m p l y a m a t t e r o f m a k i n g t h e e v e n t m a s k
* non- z e r o .
2009-02-03 00:55:42 +03:00
* /
ENTRY( x e n _ i r q _ d i s a b l e _ d i r e c t )
movb $ 1 , P E R _ C P U _ V A R ( x e n _ v c p u _ i n f o ) + X E N _ v c p u _ i n f o _ m a s k
ENDPATCH( x e n _ i r q _ d i s a b l e _ d i r e c t )
ret
ENDPROC( x e n _ i r q _ d i s a b l e _ d i r e c t )
RELOC( x e n _ i r q _ d i s a b l e _ d i r e c t , 0 )
/ *
2009-02-05 18:57:48 +03:00
* ( xen_ ) s a v e _ f l i s u s e d t o g e t t h e c u r r e n t i n t e r r u p t e n a b l e s t a t u s .
* Callers e x p e c t t h e s t a t u s t o b e i n X 8 6 _ E F L A G S _ I F , a n d o t h e r b i t s
* may b e s e t i n t h e r e t u r n v a l u e . W e t a k e a d v a n t a g e o f t h i s b y
* making s u r e t h a t X 8 6 _ E F L A G S _ I F h a s t h e r i g h t v a l u e ( a n d o t h e r b i t s
* in t h a t b y t e a r e 0 ) , b u t o t h e r b i t s i n t h e r e t u r n v a l u e a r e
* undefined. W e n e e d t o t o g g l e t h e s t a t e o f t h e b i t , b e c a u s e X e n a n d
* x8 6 u s e o p p o s i t e s e n s e s ( m a s k v s e n a b l e ) .
2009-02-03 00:55:42 +03:00
* /
ENTRY( x e n _ s a v e _ f l _ d i r e c t )
testb $ 0 x f f , P E R _ C P U _ V A R ( x e n _ v c p u _ i n f o ) + X E N _ v c p u _ i n f o _ m a s k
setz % a h
2009-02-05 18:57:48 +03:00
addb % a h , % a h
2009-02-03 00:55:42 +03:00
ENDPATCH( x e n _ s a v e _ f l _ d i r e c t )
ret
ENDPROC( x e n _ s a v e _ f l _ d i r e c t )
RELOC( x e n _ s a v e _ f l _ d i r e c t , 0 )
/ *
2009-02-05 18:57:48 +03:00
* In p r i n c i p l e t h e c a l l e r s h o u l d b e p a s s i n g u s a v a l u e r e t u r n f r o m
* xen_ s a v e _ f l _ d i r e c t , b u t f o r r o b u s t n e s s s a k e w e t e s t o n l y t h e
* X8 6 _ E F L A G S _ I F f l a g r a t h e r t h a n t h e w h o l e b y t e . A f t e r s e t t i n g t h e
* interrupt m a s k s t a t e , i t c h e c k s f o r u n m a s k e d p e n d i n g e v e n t s a n d
* enters t h e h y p e r v i s o r t o g e t t h e m d e l i v e r e d i f s o .
2009-02-03 00:55:42 +03:00
* /
ENTRY( x e n _ r e s t o r e _ f l _ d i r e c t )
# ifdef C O N F I G _ X 8 6 _ 6 4
testw $ X 8 6 _ E F L A G S _ I F , % d i
# else
testb $ X 8 6 _ E F L A G S _ I F > > 8 , % a h
# endif
setz P E R _ C P U _ V A R ( x e n _ v c p u _ i n f o ) + X E N _ v c p u _ i n f o _ m a s k
2009-02-05 18:57:48 +03:00
/ *
* Preempt h e r e d o e s n ' t m a t t e r b e c a u s e t h a t w i l l d e a l w i t h a n y
* pending i n t e r r u p t s . T h e p e n d i n g c h e c k m a y e n d u p b e i n g r u n
* on t h e w r o n g C P U , b u t t h a t d o e s n ' t h u r t .
* /
2009-02-03 00:55:42 +03:00
/* check for unmasked and pending */
cmpw $ 0 x00 0 1 , P E R _ C P U _ V A R ( x e n _ v c p u _ i n f o ) + X E N _ v c p u _ i n f o _ p e n d i n g
jz 1 f
2 : call c h e c k _ e v e n t s
1 :
ENDPATCH( x e n _ r e s t o r e _ f l _ d i r e c t )
ret
ENDPROC( x e n _ r e s t o r e _ f l _ d i r e c t )
RELOC( x e n _ r e s t o r e _ f l _ d i r e c t , 2 b + 1 )
/ *
2009-02-05 18:57:48 +03:00
* Force a n e v e n t c h e c k b y m a k i n g a h y p e r c a l l , b u t p r e s e r v e r e g s
* before m a k i n g t h e c a l l .
2009-02-03 00:55:42 +03:00
* /
check_events :
# ifdef C O N F I G _ X 8 6 _ 3 2
push % e a x
push % e c x
push % e d x
call x e n _ f o r c e _ e v t c h n _ c a l l b a c k
pop % e d x
pop % e c x
pop % e a x
# else
push % r a x
push % r c x
push % r d x
push % r s i
push % r d i
push % r8
push % r9
push % r10
push % r11
call x e n _ f o r c e _ e v t c h n _ c a l l b a c k
pop % r11
pop % r10
pop % r9
pop % r8
pop % r d i
pop % r s i
pop % r d x
pop % r c x
pop % r a x
# endif
ret