2011-12-20 19:34:43 +04:00
/ *
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e , v e r s i o n 2 , a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n .
*
* This p r o g r a m i s d i s t r i b u t e d i n t h e h o p e t h a t i t w i l l b e u s e f u l ,
* but W I T H O U T A N Y W A R R A N T Y ; without even the implied warranty of
* MERCHANTABILITY o r F I T N E S S F O R A P A R T I C U L A R P U R P O S E . S e e t h e
* GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e d e t a i l s .
*
* You s h o u l d h a v e r e c e i v e d a c o p y o f t h e G N U G e n e r a l P u b l i c L i c e n s e
* along w i t h t h i s p r o g r a m ; if not, write to the Free Software
* Foundation, 5 1 F r a n k l i n S t r e e t , F i f t h F l o o r , B o s t o n , M A 0 2 1 1 0 - 1 3 0 1 , U S A .
*
* Copyright ( C ) 2 0 1 0 - 2 0 1 1 F r e e s c a l e S e m i c o n d u c t o r , I n c .
*
* Author : Varun S e t h i < v a r u n . s e t h i @freescale.com>
* Author : Scott W o o d < s c o t w o o d @freescale.com>
*
* This f i l e i s d e r i v e d f r o m a r c h / p o w e r p c / k v m / b o o k e _ i n t e r r u p t s . S
* /
# include < a s m / p p c _ a s m . h >
# include < a s m / k v m _ a s m . h >
# include < a s m / r e g . h >
# include < a s m / m m u - 4 4 x . h >
# include < a s m / p a g e . h >
# include < a s m / a s m - c o m p a t . h >
# include < a s m / a s m - o f f s e t s . h >
# include < a s m / b i t s p e r l o n g . h >
2012-02-16 03:24:28 +04:00
# include < a s m / t h r e a d _ i n f o . h >
2011-12-20 19:34:43 +04:00
# include " . . / k e r n e l / h e a d _ b o o k e . h " / * f o r T H R E A D _ N O R M S A V E ( ) * /
# define G E T _ V C P U ( v c p u , t h r e a d ) \
PPC_ L L v c p u , T H R E A D _ K V M _ V C P U ( t h r e a d )
# define L O N G B Y T E S ( B I T S _ P E R _ L O N G / 8 )
# define V C P U _ G P R ( n ) ( V C P U _ G P R S + ( n * L O N G B Y T E S ) )
# define V C P U _ G U E S T _ S P R G ( n ) ( V C P U _ G U E S T _ S P R G S + ( n * L O N G B Y T E S ) )
/* The host stack layout: */
# define H O S T _ R 1 ( 0 * L O N G B Y T E S ) / * I m p l i e d b y s t w u . * /
# define H O S T _ C A L L E E _ L R ( 1 * L O N G B Y T E S )
# define H O S T _ R U N ( 2 * L O N G B Y T E S ) / * s t r u c t k v m _ r u n * /
/ *
* r2 i s s p e c i a l : i t h o l d s ' c u r r e n t ' , a n d i t m a d e n o n v o l a t i l e i n t h e
* kernel w i t h t h e - f f i x e d - r2 g c c o p t i o n .
* /
# define H O S T _ R 2 ( 3 * L O N G B Y T E S )
2012-03-05 19:00:28 +04:00
# define H O S T _ C R ( 4 * L O N G B Y T E S )
# define H O S T _ N V _ G P R S ( 5 * L O N G B Y T E S )
2011-12-20 19:34:43 +04:00
# define H O S T _ N V _ G P R ( n ) ( H O S T _ N V _ G P R S + ( ( n - 1 4 ) * L O N G B Y T E S ) )
# define H O S T _ M I N _ S T A C K _ S I Z E ( H O S T _ N V _ G P R ( 3 1 ) + L O N G B Y T E S )
# define H O S T _ S T A C K _ S I Z E ( ( H O S T _ M I N _ S T A C K _ S I Z E + 1 5 ) & ~ 1 5 ) / * A l i g n . * /
# define H O S T _ S T A C K _ L R ( H O S T _ S T A C K _ S I Z E + L O N G B Y T E S ) / * I n c a l l e r s t a c k f r a m e . * /
# define N E E D _ E M U 0 x00 0 0 0 0 0 1 / * e m u l a t i o n - - s a v e n v r e g s * /
# define N E E D _ D E A R 0 x00 0 0 0 0 0 2 / * s a v e f a u l t i n g D E A R * /
# define N E E D _ E S R 0 x00 0 0 0 0 0 4 / * s a v e f a u l t i n g E S R * /
/ *
* On e n t r y :
* r4 = v c p u , r5 = s r r0 , r6 = s r r1
* saved i n v c p u : c r , c t r , r3 - r13
* /
.macro kvm_handler_common intno, s r r0 , f l a g s
2012-02-16 03:06:24 +04:00
/* Restore host stack pointer */
PPC_ S T L r1 , V C P U _ G P R ( r1 ) ( r4 )
PPC_ S T L r2 , V C P U _ G P R ( r2 ) ( r4 )
PPC_ L L r1 , V C P U _ H O S T _ S T A C K ( r4 )
PPC_ L L r2 , H O S T _ R 2 ( r1 )
2011-12-20 19:34:43 +04:00
mfspr r10 , S P R N _ P I D
lwz r8 , V C P U _ H O S T _ P I D ( r4 )
PPC_ L L r11 , V C P U _ S H A R E D ( r4 )
PPC_ S T L r14 , V C P U _ G P R ( r14 ) ( r4 ) / * W e n e e d a n o n - v o l a t i l e G P R . * /
li r14 , \ i n t n o
stw r10 , V C P U _ G U E S T _ P I D ( r4 )
mtspr S P R N _ P I D , r8
# ifdef C O N F I G _ K V M _ E X I T _ T I M I N G
/* save exit time */
1 : mfspr r7 , S P R N _ T B R U
mfspr r8 , S P R N _ T B R L
mfspr r9 , S P R N _ T B R U
cmpw r9 , r7
2012-04-16 08:08:54 +04:00
stw r8 , V C P U _ T I M I N G _ E X I T _ T B L ( r4 )
2011-12-20 19:34:43 +04:00
bne- 1 b
2012-04-16 08:08:54 +04:00
stw r9 , V C P U _ T I M I N G _ E X I T _ T B U ( r4 )
2011-12-20 19:34:43 +04:00
# endif
oris r8 , r6 , M S R _ C E @h
2012-04-25 05:26:43 +04:00
PPC_ S T D ( r6 , V C P U _ S H A R E D _ M S R , r11 )
2011-12-20 19:34:43 +04:00
ori r8 , r8 , M S R _ M E | M S R _ R I
PPC_ S T L r5 , V C P U _ P C ( r4 )
/ *
* Make s u r e C E / M E / R I a r e s e t ( i f a p p r o p r i a t e f o r e x c e p t i o n t y p e )
* whether o r n o t t h e g u e s t h a d i t s e t . S i n c e m f m s r / m t m s r a r e
* somewhat e x p e n s i v e , s k i p i n t h e c o m m o n c a s e w h e r e t h e g u e s t
* had a l l t h e s e b i t s s e t ( a n d t h u s t h e y ' r e s t i l l s e t i f
* appropriate f o r t h e e x c e p t i o n t y p e ) .
* /
cmpw r6 , r8
beq 1 f
mfmsr r7
.if \ srr0 ! = S P R N _ M C S R R 0 & & \ s r r0 ! = S P R N _ C S R R 0
oris r7 , r7 , M S R _ C E @h
.endif
.if \ srr0 ! = S P R N _ M C S R R 0
ori r7 , r7 , M S R _ M E | M S R _ R I
.endif
mtmsr r7
1 :
.if \ flags & N E E D _ E M U
/ *
* This a s s u m e s y o u h a v e e x t e r n a l P I D s u p p o r t .
* To s u p p o r t a b o o k e h v C P U w i t h o u t e x t e r n a l P I D , y o u ' l l
* need t o l o o k u p t h e T L B e n t r y a n d c r e a t e a t e m p o r a r y m a p p i n g .
*
* FIXME : we d o n ' t c u r r e n t l y h a n d l e i f t h e l w e p x f a u l t s . P R - m o d e
* booke d o e s n ' t h a n d l e i t e i t h e r . S i n c e L i n u x d o e s n ' t u s e
* broadcast t l b i v a x a n y m o r e , t h e o n l y w a y t h i s s h o u l d h a p p e n i s
* if t h e g u e s t m a p s i t s m e m o r y e x e c u t e - b u t - n o t - r e a d , o r i f w e
* somehow t a k e a T L B m i s s i n t h e m i d d l e o f t h i s e n t r y c o d e a n d
* evict t h e r e l e v a n t e n t r y . O n e 5 0 0 m c , a l l k e r n e l l o w m e m i s
* bolted i n t o T L B 1 l a r g e p a g e m a p p i n g s , a n d w e d o n ' t u s e
* broadcast i n v a l i d a t e s , s o w e s h o u l d n o t t a k e a T L B m i s s h e r e .
*
* Later w e ' l l n e e d t o d e a l w i t h f a u l t s h e r e . D i s a l l o w i n g g u e s t
* mappings t h a t a r e e x e c u t e - b u t - n o t - r e a d c o u l d b e a n o p t i o n o n
* e5 0 0 m c , b u t n o t o n c h i p s w i t h a n L R A T i f i t i s u s e d .
* /
mfspr r3 , S P R N _ E P L C / * w i l l a l r e a d y h a v e c o r r e c t E L P I D a n d E G S * /
PPC_ S T L r15 , V C P U _ G P R ( r15 ) ( r4 )
PPC_ S T L r16 , V C P U _ G P R ( r16 ) ( r4 )
PPC_ S T L r17 , V C P U _ G P R ( r17 ) ( r4 )
PPC_ S T L r18 , V C P U _ G P R ( r18 ) ( r4 )
PPC_ S T L r19 , V C P U _ G P R ( r19 ) ( r4 )
mr r8 , r3
PPC_ S T L r20 , V C P U _ G P R ( r20 ) ( r4 )
rlwimi r8 , r6 , E P C _ E A S _ S H I F T - M S R _ I R _ L G , E P C _ E A S
PPC_ S T L r21 , V C P U _ G P R ( r21 ) ( r4 )
rlwimi r8 , r6 , E P C _ E P R _ S H I F T - M S R _ P R _ L G , E P C _ E P R
PPC_ S T L r22 , V C P U _ G P R ( r22 ) ( r4 )
rlwimi r8 , r10 , E P C _ E P I D _ S H I F T , E P C _ E P I D
PPC_ S T L r23 , V C P U _ G P R ( r23 ) ( r4 )
PPC_ S T L r24 , V C P U _ G P R ( r24 ) ( r4 )
PPC_ S T L r25 , V C P U _ G P R ( r25 ) ( r4 )
PPC_ S T L r26 , V C P U _ G P R ( r26 ) ( r4 )
PPC_ S T L r27 , V C P U _ G P R ( r27 ) ( r4 )
PPC_ S T L r28 , V C P U _ G P R ( r28 ) ( r4 )
PPC_ S T L r29 , V C P U _ G P R ( r29 ) ( r4 )
PPC_ S T L r30 , V C P U _ G P R ( r30 ) ( r4 )
PPC_ S T L r31 , V C P U _ G P R ( r31 ) ( r4 )
mtspr S P R N _ E P L C , r8
2012-02-16 03:24:28 +04:00
/* disable preemption, so we are sure we hit the fixup handler */
# ifdef C O N F I G _ P P C 6 4
clrrdi r8 ,r1 ,T H R E A D _ S H I F T
# else
rlwinm r8 ,r1 ,0 ,0 ,3 1 - T H R E A D _ S H I F T / * c u r r e n t t h r e a d _ i n f o * /
# endif
li r7 , 1
stw r7 , T I _ P R E E M P T ( r8 )
2011-12-20 19:34:43 +04:00
isync
2012-02-16 03:24:28 +04:00
/ *
* In c a s e t h e r e a d g o e s w r o n g , w e c a t c h i t a n d w r i t e a n i n v a l i d v a l u e
* in L A S T _ I N S T i n s t e a d .
* /
1 : lwepx r9 , 0 , r5
2 :
.section .fixup , " ax"
3 : li r9 , K V M _ I N S T _ F E T C H _ F A I L E D
b 2 b
.previous
.section _ _ ex_ t a b l e ," a "
PPC_ L O N G _ A L I G N
PPC_ L O N G 1 b ,3 b
.previous
2011-12-20 19:34:43 +04:00
mtspr S P R N _ E P L C , r3
2012-02-16 03:24:28 +04:00
li r7 , 0
stw r7 , T I _ P R E E M P T ( r8 )
2011-12-20 19:34:43 +04:00
stw r9 , V C P U _ L A S T _ I N S T ( r4 )
.endif
.if \ flags & N E E D _ E S R
mfspr r8 , S P R N _ E S R
PPC_ S T L r8 , V C P U _ F A U L T _ E S R ( r4 )
.endif
.if \ flags & N E E D _ D E A R
mfspr r9 , S P R N _ D E A R
PPC_ S T L r9 , V C P U _ F A U L T _ D E A R ( r4 )
.endif
b k v m p p c _ r e s u m e _ h o s t
.endm
/ *
* For i n p u t r e g i s t e r v a l u e s , s e e a r c h / p o w e r p c / i n c l u d e / a s m / k v m _ b o o k e _ h v _ a s m . h
* /
.macro kvm_handler intno s r r0 , s r r1 , f l a g s
_ GLOBAL( k v m p p c _ h a n d l e r _ \ i n t n o \ ( ) _ \ s r r1 )
GET_ V C P U ( r11 , r10 )
PPC_ S T L r3 , V C P U _ G P R ( r3 ) ( r11 )
mfspr r3 , S P R N _ S P R G _ R S C R A T C H 0
PPC_ S T L r4 , V C P U _ G P R ( r4 ) ( r11 )
PPC_ L L r4 , T H R E A D _ N O R M S A V E ( 0 ) ( r10 )
PPC_ S T L r5 , V C P U _ G P R ( r5 ) ( r11 )
2012-04-16 08:08:54 +04:00
stw r13 , V C P U _ C R ( r11 )
2011-12-20 19:34:43 +04:00
mfspr r5 , \ s r r0
PPC_ S T L r3 , V C P U _ G P R ( r10 ) ( r11 )
PPC_ L L r3 , T H R E A D _ N O R M S A V E ( 2 ) ( r10 )
PPC_ S T L r6 , V C P U _ G P R ( r6 ) ( r11 )
PPC_ S T L r4 , V C P U _ G P R ( r11 ) ( r11 )
mfspr r6 , \ s r r1
PPC_ S T L r7 , V C P U _ G P R ( r7 ) ( r11 )
PPC_ S T L r8 , V C P U _ G P R ( r8 ) ( r11 )
PPC_ S T L r9 , V C P U _ G P R ( r9 ) ( r11 )
PPC_ S T L r3 , V C P U _ G P R ( r13 ) ( r11 )
mfctr r7
PPC_ S T L r12 , V C P U _ G P R ( r12 ) ( r11 )
PPC_ S T L r7 , V C P U _ C T R ( r11 )
mr r4 , r11
kvm_ h a n d l e r _ c o m m o n \ i n t n o , \ s r r0 , \ f l a g s
.endm
.macro kvm_lvl_handler intno s c r a t c h s r r0 , s r r1 , f l a g s
_ GLOBAL( k v m p p c _ h a n d l e r _ \ i n t n o \ ( ) _ \ s r r1 )
mfspr r10 , S P R N _ S P R G _ T H R E A D
GET_ V C P U ( r11 , r10 )
PPC_ S T L r3 , V C P U _ G P R ( r3 ) ( r11 )
mfspr r3 , \ s c r a t c h
PPC_ S T L r4 , V C P U _ G P R ( r4 ) ( r11 )
PPC_ L L r4 , G P R 9 ( r8 )
PPC_ S T L r5 , V C P U _ G P R ( r5 ) ( r11 )
2012-04-16 08:08:54 +04:00
stw r9 , V C P U _ C R ( r11 )
2011-12-20 19:34:43 +04:00
mfspr r5 , \ s r r0
PPC_ S T L r3 , V C P U _ G P R ( r8 ) ( r11 )
PPC_ L L r3 , G P R 1 0 ( r8 )
PPC_ S T L r6 , V C P U _ G P R ( r6 ) ( r11 )
PPC_ S T L r4 , V C P U _ G P R ( r9 ) ( r11 )
mfspr r6 , \ s r r1
PPC_ L L r4 , G P R 1 1 ( r8 )
PPC_ S T L r7 , V C P U _ G P R ( r7 ) ( r11 )
PPC_ S T L r3 , V C P U _ G P R ( r10 ) ( r11 )
mfctr r7
PPC_ S T L r12 , V C P U _ G P R ( r12 ) ( r11 )
2012-04-16 08:08:53 +04:00
PPC_ S T L r13 , V C P U _ G P R ( r13 ) ( r11 )
2011-12-20 19:34:43 +04:00
PPC_ S T L r4 , V C P U _ G P R ( r11 ) ( r11 )
PPC_ S T L r7 , V C P U _ C T R ( r11 )
mr r4 , r11
kvm_ h a n d l e r _ c o m m o n \ i n t n o , \ s r r0 , \ f l a g s
.endm
kvm_ l v l _ h a n d l e r B O O K E _ I N T E R R U P T _ C R I T I C A L , \
SPRN_ S P R G _ R S C R A T C H _ C R I T , S P R N _ C S R R 0 , S P R N _ C S R R 1 , 0
kvm_ l v l _ h a n d l e r B O O K E _ I N T E R R U P T _ M A C H I N E _ C H E C K , \
SPRN_ S P R G _ R S C R A T C H _ M C , S P R N _ M C S R R 0 , S P R N _ M C S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ D A T A _ S T O R A G E , \
SPRN_ S R R 0 , S P R N _ S R R 1 , ( N E E D _ E M U | N E E D _ D E A R )
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ I N S T _ S T O R A G E , S P R N _ S R R 0 , S P R N _ S R R 1 , N E E D _ E S R
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ E X T E R N A L , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ A L I G N M E N T , \
SPRN_ S R R 0 , S P R N _ S R R 1 , ( N E E D _ D E A R | N E E D _ E S R )
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ P R O G R A M , S P R N _ S R R 0 , S P R N _ S R R 1 , N E E D _ E S R
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ F P _ U N A V A I L , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ S Y S C A L L , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ A P _ U N A V A I L , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ D E C R E M E N T E R , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ F I T , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ l v l _ h a n d l e r B O O K E _ I N T E R R U P T _ W A T C H D O G , \
SPRN_ S P R G _ R S C R A T C H _ C R I T , S P R N _ C S R R 0 , S P R N _ C S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ D T L B _ M I S S , \
SPRN_ S R R 0 , S P R N _ S R R 1 , ( N E E D _ E M U | N E E D _ D E A R | N E E D _ E S R )
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ I T L B _ M I S S , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ S P E _ U N A V A I L , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ S P E _ F P _ D A T A , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ S P E _ F P _ R O U N D , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ P E R F O R M A N C E _ M O N I T O R , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ D O O R B E L L , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ l v l _ h a n d l e r B O O K E _ I N T E R R U P T _ D O O R B E L L _ C R I T I C A L , \
SPRN_ S P R G _ R S C R A T C H _ C R I T , S P R N _ C S R R 0 , S P R N _ C S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ H V _ P R I V , S P R N _ S R R 0 , S P R N _ S R R 1 , N E E D _ E M U
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ H V _ S Y S C A L L , S P R N _ S R R 0 , S P R N _ S R R 1 , 0
kvm_ h a n d l e r B O O K E _ I N T E R R U P T _ G U E S T _ D B E L L , S P R N _ G S R R 0 , S P R N _ G S R R 1 , 0
kvm_ l v l _ h a n d l e r B O O K E _ I N T E R R U P T _ G U E S T _ D B E L L _ C R I T , \
SPRN_ S P R G _ R S C R A T C H _ C R I T , S P R N _ C S R R 0 , S P R N _ C S R R 1 , 0
kvm_ l v l _ h a n d l e r B O O K E _ I N T E R R U P T _ D E B U G , \
SPRN_ S P R G _ R S C R A T C H _ C R I T , S P R N _ C S R R 0 , S P R N _ C S R R 1 , 0
kvm_ l v l _ h a n d l e r B O O K E _ I N T E R R U P T _ D E B U G , \
SPRN_ S P R G _ R S C R A T C H _ D B G , S P R N _ D S R R 0 , S P R N _ D S R R 1 , 0
/ * Registers :
* SPRG_SCRATCH0 : guest r10
* r4 : vcpu p o i n t e r
* r11 : vcpu- > a r c h . s h a r e d
* r14 : KVM e x i t n u m b e r
* /
_ GLOBAL( k v m p p c _ r e s u m e _ h o s t )
/* Save remaining volatile guest register state to vcpu. */
mfspr r3 , S P R N _ V R S A V E
PPC_ S T L r0 , V C P U _ G P R ( r0 ) ( r4 )
mflr r5
mfspr r6 , S P R N _ S P R G 4
PPC_ S T L r5 , V C P U _ L R ( r4 )
mfspr r7 , S P R N _ S P R G 5
2012-04-16 08:08:54 +04:00
stw r3 , V C P U _ V R S A V E ( r4 )
2012-04-25 05:27:34 +04:00
PPC_ S T D ( r6 , V C P U _ S H A R E D _ S P R G 4 , r11 )
2011-12-20 19:34:43 +04:00
mfspr r8 , S P R N _ S P R G 6
2012-04-25 05:27:34 +04:00
PPC_ S T D ( r7 , V C P U _ S H A R E D _ S P R G 5 , r11 )
2011-12-20 19:34:43 +04:00
mfspr r9 , S P R N _ S P R G 7
2012-04-25 05:27:34 +04:00
PPC_ S T D ( r8 , V C P U _ S H A R E D _ S P R G 6 , r11 )
2011-12-20 19:34:43 +04:00
mfxer r3
2012-04-25 05:27:34 +04:00
PPC_ S T D ( r9 , V C P U _ S H A R E D _ S P R G 7 , r11 )
2011-12-20 19:34:43 +04:00
/* save guest MAS registers and restore host mas4 & mas6 */
mfspr r5 , S P R N _ M A S 0
PPC_ S T L r3 , V C P U _ X E R ( r4 )
mfspr r6 , S P R N _ M A S 1
stw r5 , V C P U _ S H A R E D _ M A S 0 ( r11 )
mfspr r7 , S P R N _ M A S 2
stw r6 , V C P U _ S H A R E D _ M A S 1 ( r11 )
2012-04-25 05:26:43 +04:00
PPC_ S T D ( r7 , V C P U _ S H A R E D _ M A S 2 , r11 )
2011-12-20 19:34:43 +04:00
mfspr r5 , S P R N _ M A S 3
mfspr r6 , S P R N _ M A S 4
stw r5 , V C P U _ S H A R E D _ M A S 7 _ 3 + 4 ( r11 )
mfspr r7 , S P R N _ M A S 6
stw r6 , V C P U _ S H A R E D _ M A S 4 ( r11 )
mfspr r5 , S P R N _ M A S 7
lwz r6 , V C P U _ H O S T _ M A S 4 ( r4 )
stw r7 , V C P U _ S H A R E D _ M A S 6 ( r11 )
lwz r8 , V C P U _ H O S T _ M A S 6 ( r4 )
mtspr S P R N _ M A S 4 , r6
stw r5 , V C P U _ S H A R E D _ M A S 7 _ 3 + 0 ( r11 )
mtspr S P R N _ M A S 6 , r8
2012-02-16 18:53:04 +04:00
/* Enable MAS register updates via exception */
2011-12-20 19:34:43 +04:00
mfspr r3 , S P R N _ E P C R
rlwinm r3 , r3 , 0 , ~ S P R N _ E P C R _ D M I U H
mtspr S P R N _ E P C R , r3
isync
/* Switch to kernel stack and jump to handler. */
PPC_ L L r3 , H O S T _ R U N ( r1 )
mr r5 , r14 / * i n t n o * /
mr r14 , r4 / * S a v e v c p u p o i n t e r . * /
bl k v m p p c _ h a n d l e _ e x i t
/* Restore vcpu pointer and the nonvolatiles we used. */
mr r4 , r14
PPC_ L L r14 , V C P U _ G P R ( r14 ) ( r4 )
andi. r5 , r3 , R E S U M E _ F L A G _ N V
beq s k i p _ n v _ l o a d
PPC_ L L r15 , V C P U _ G P R ( r15 ) ( r4 )
PPC_ L L r16 , V C P U _ G P R ( r16 ) ( r4 )
PPC_ L L r17 , V C P U _ G P R ( r17 ) ( r4 )
PPC_ L L r18 , V C P U _ G P R ( r18 ) ( r4 )
PPC_ L L r19 , V C P U _ G P R ( r19 ) ( r4 )
PPC_ L L r20 , V C P U _ G P R ( r20 ) ( r4 )
PPC_ L L r21 , V C P U _ G P R ( r21 ) ( r4 )
PPC_ L L r22 , V C P U _ G P R ( r22 ) ( r4 )
PPC_ L L r23 , V C P U _ G P R ( r23 ) ( r4 )
PPC_ L L r24 , V C P U _ G P R ( r24 ) ( r4 )
PPC_ L L r25 , V C P U _ G P R ( r25 ) ( r4 )
PPC_ L L r26 , V C P U _ G P R ( r26 ) ( r4 )
PPC_ L L r27 , V C P U _ G P R ( r27 ) ( r4 )
PPC_ L L r28 , V C P U _ G P R ( r28 ) ( r4 )
PPC_ L L r29 , V C P U _ G P R ( r29 ) ( r4 )
PPC_ L L r30 , V C P U _ G P R ( r30 ) ( r4 )
PPC_ L L r31 , V C P U _ G P R ( r31 ) ( r4 )
skip_nv_load :
/* Should we return to the guest? */
andi. r5 , r3 , R E S U M E _ F L A G _ H O S T
beq l i g h t w e i g h t _ e x i t
srawi r3 , r3 , 2 / * S h i f t - E R R b a c k d o w n . * /
heavyweight_exit :
/* Not returning to guest. */
PPC_ L L r5 , H O S T _ S T A C K _ L R ( r1 )
2012-03-05 19:00:28 +04:00
lwz r6 , H O S T _ C R ( r1 )
2011-12-20 19:34:43 +04:00
/ *
* We a l r e a d y s a v e d g u e s t v o l a t i l e r e g i s t e r s t a t e ; now save the
* non- v o l a t i l e s .
* /
PPC_ S T L r15 , V C P U _ G P R ( r15 ) ( r4 )
PPC_ S T L r16 , V C P U _ G P R ( r16 ) ( r4 )
PPC_ S T L r17 , V C P U _ G P R ( r17 ) ( r4 )
PPC_ S T L r18 , V C P U _ G P R ( r18 ) ( r4 )
PPC_ S T L r19 , V C P U _ G P R ( r19 ) ( r4 )
PPC_ S T L r20 , V C P U _ G P R ( r20 ) ( r4 )
PPC_ S T L r21 , V C P U _ G P R ( r21 ) ( r4 )
PPC_ S T L r22 , V C P U _ G P R ( r22 ) ( r4 )
PPC_ S T L r23 , V C P U _ G P R ( r23 ) ( r4 )
PPC_ S T L r24 , V C P U _ G P R ( r24 ) ( r4 )
PPC_ S T L r25 , V C P U _ G P R ( r25 ) ( r4 )
PPC_ S T L r26 , V C P U _ G P R ( r26 ) ( r4 )
PPC_ S T L r27 , V C P U _ G P R ( r27 ) ( r4 )
PPC_ S T L r28 , V C P U _ G P R ( r28 ) ( r4 )
PPC_ S T L r29 , V C P U _ G P R ( r29 ) ( r4 )
PPC_ S T L r30 , V C P U _ G P R ( r30 ) ( r4 )
PPC_ S T L r31 , V C P U _ G P R ( r31 ) ( r4 )
/* Load host non-volatile register state from host stack. */
PPC_ L L r14 , H O S T _ N V _ G P R ( r14 ) ( r1 )
PPC_ L L r15 , H O S T _ N V _ G P R ( r15 ) ( r1 )
PPC_ L L r16 , H O S T _ N V _ G P R ( r16 ) ( r1 )
PPC_ L L r17 , H O S T _ N V _ G P R ( r17 ) ( r1 )
PPC_ L L r18 , H O S T _ N V _ G P R ( r18 ) ( r1 )
PPC_ L L r19 , H O S T _ N V _ G P R ( r19 ) ( r1 )
PPC_ L L r20 , H O S T _ N V _ G P R ( r20 ) ( r1 )
PPC_ L L r21 , H O S T _ N V _ G P R ( r21 ) ( r1 )
PPC_ L L r22 , H O S T _ N V _ G P R ( r22 ) ( r1 )
PPC_ L L r23 , H O S T _ N V _ G P R ( r23 ) ( r1 )
PPC_ L L r24 , H O S T _ N V _ G P R ( r24 ) ( r1 )
PPC_ L L r25 , H O S T _ N V _ G P R ( r25 ) ( r1 )
PPC_ L L r26 , H O S T _ N V _ G P R ( r26 ) ( r1 )
PPC_ L L r27 , H O S T _ N V _ G P R ( r27 ) ( r1 )
PPC_ L L r28 , H O S T _ N V _ G P R ( r28 ) ( r1 )
PPC_ L L r29 , H O S T _ N V _ G P R ( r29 ) ( r1 )
PPC_ L L r30 , H O S T _ N V _ G P R ( r30 ) ( r1 )
PPC_ L L r31 , H O S T _ N V _ G P R ( r31 ) ( r1 )
/* Return to kvm_vcpu_run(). */
mtlr r5
2012-03-05 19:00:28 +04:00
mtcr r6
2011-12-20 19:34:43 +04:00
addi r1 , r1 , H O S T _ S T A C K _ S I Z E
/* r3 still contains the return code from kvmppc_handle_exit(). */
blr
/ * Registers :
* r3 : kvm_ r u n p o i n t e r
* r4 : vcpu p o i n t e r
* /
_ GLOBAL( _ _ k v m p p c _ v c p u _ r u n )
stwu r1 , - H O S T _ S T A C K _ S I Z E ( r1 )
PPC_ S T L r1 , V C P U _ H O S T _ S T A C K ( r4 ) / * S a v e s t a c k p o i n t e r t o v c p u . * /
/* Save host state to stack. */
PPC_ S T L r3 , H O S T _ R U N ( r1 )
mflr r3
2012-03-05 19:00:28 +04:00
mfcr r5
2011-12-20 19:34:43 +04:00
PPC_ S T L r3 , H O S T _ S T A C K _ L R ( r1 )
2012-03-05 19:00:28 +04:00
stw r5 , H O S T _ C R ( r1 )
2011-12-20 19:34:43 +04:00
/* Save host non-volatile register state to stack. */
PPC_ S T L r14 , H O S T _ N V _ G P R ( r14 ) ( r1 )
PPC_ S T L r15 , H O S T _ N V _ G P R ( r15 ) ( r1 )
PPC_ S T L r16 , H O S T _ N V _ G P R ( r16 ) ( r1 )
PPC_ S T L r17 , H O S T _ N V _ G P R ( r17 ) ( r1 )
PPC_ S T L r18 , H O S T _ N V _ G P R ( r18 ) ( r1 )
PPC_ S T L r19 , H O S T _ N V _ G P R ( r19 ) ( r1 )
PPC_ S T L r20 , H O S T _ N V _ G P R ( r20 ) ( r1 )
PPC_ S T L r21 , H O S T _ N V _ G P R ( r21 ) ( r1 )
PPC_ S T L r22 , H O S T _ N V _ G P R ( r22 ) ( r1 )
PPC_ S T L r23 , H O S T _ N V _ G P R ( r23 ) ( r1 )
PPC_ S T L r24 , H O S T _ N V _ G P R ( r24 ) ( r1 )
PPC_ S T L r25 , H O S T _ N V _ G P R ( r25 ) ( r1 )
PPC_ S T L r26 , H O S T _ N V _ G P R ( r26 ) ( r1 )
PPC_ S T L r27 , H O S T _ N V _ G P R ( r27 ) ( r1 )
PPC_ S T L r28 , H O S T _ N V _ G P R ( r28 ) ( r1 )
PPC_ S T L r29 , H O S T _ N V _ G P R ( r29 ) ( r1 )
PPC_ S T L r30 , H O S T _ N V _ G P R ( r30 ) ( r1 )
PPC_ S T L r31 , H O S T _ N V _ G P R ( r31 ) ( r1 )
/* Load guest non-volatiles. */
PPC_ L L r14 , V C P U _ G P R ( r14 ) ( r4 )
PPC_ L L r15 , V C P U _ G P R ( r15 ) ( r4 )
PPC_ L L r16 , V C P U _ G P R ( r16 ) ( r4 )
PPC_ L L r17 , V C P U _ G P R ( r17 ) ( r4 )
PPC_ L L r18 , V C P U _ G P R ( r18 ) ( r4 )
PPC_ L L r19 , V C P U _ G P R ( r19 ) ( r4 )
PPC_ L L r20 , V C P U _ G P R ( r20 ) ( r4 )
PPC_ L L r21 , V C P U _ G P R ( r21 ) ( r4 )
PPC_ L L r22 , V C P U _ G P R ( r22 ) ( r4 )
PPC_ L L r23 , V C P U _ G P R ( r23 ) ( r4 )
PPC_ L L r24 , V C P U _ G P R ( r24 ) ( r4 )
PPC_ L L r25 , V C P U _ G P R ( r25 ) ( r4 )
PPC_ L L r26 , V C P U _ G P R ( r26 ) ( r4 )
PPC_ L L r27 , V C P U _ G P R ( r27 ) ( r4 )
PPC_ L L r28 , V C P U _ G P R ( r28 ) ( r4 )
PPC_ L L r29 , V C P U _ G P R ( r29 ) ( r4 )
PPC_ L L r30 , V C P U _ G P R ( r30 ) ( r4 )
PPC_ L L r31 , V C P U _ G P R ( r31 ) ( r4 )
lightweight_exit :
PPC_ S T L r2 , H O S T _ R 2 ( r1 )
mfspr r3 , S P R N _ P I D
stw r3 , V C P U _ H O S T _ P I D ( r4 )
lwz r3 , V C P U _ G U E S T _ P I D ( r4 )
mtspr S P R N _ P I D , r3
PPC_ L L r11 , V C P U _ S H A R E D ( r4 )
2012-02-16 18:53:04 +04:00
/* Disable MAS register updates via exception */
mfspr r3 , S P R N _ E P C R
oris r3 , r3 , S P R N _ E P C R _ D M I U H @h
mtspr S P R N _ E P C R , r3
isync
2011-12-20 19:34:43 +04:00
/* Save host mas4 and mas6 and load guest MAS registers */
mfspr r3 , S P R N _ M A S 4
stw r3 , V C P U _ H O S T _ M A S 4 ( r4 )
mfspr r3 , S P R N _ M A S 6
stw r3 , V C P U _ H O S T _ M A S 6 ( r4 )
lwz r3 , V C P U _ S H A R E D _ M A S 0 ( r11 )
lwz r5 , V C P U _ S H A R E D _ M A S 1 ( r11 )
2012-04-25 05:26:43 +04:00
PPC_ L D ( r6 , V C P U _ S H A R E D _ M A S 2 , r11 )
2011-12-20 19:34:43 +04:00
lwz r7 , V C P U _ S H A R E D _ M A S 7 _ 3 + 4 ( r11 )
lwz r8 , V C P U _ S H A R E D _ M A S 4 ( r11 )
mtspr S P R N _ M A S 0 , r3
mtspr S P R N _ M A S 1 , r5
mtspr S P R N _ M A S 2 , r6
mtspr S P R N _ M A S 3 , r7
mtspr S P R N _ M A S 4 , r8
lwz r3 , V C P U _ S H A R E D _ M A S 6 ( r11 )
lwz r5 , V C P U _ S H A R E D _ M A S 7 _ 3 + 0 ( r11 )
mtspr S P R N _ M A S 6 , r3
mtspr S P R N _ M A S 7 , r5
/ *
* Host i n t e r r u p t h a n d l e r s m a y h a v e c l o b b e r e d t h e s e g u e s t - r e a d a b l e
* SPRGs, s o w e n e e d t o r e l o a d t h e m h e r e w i t h t h e g u e s t ' s v a l u e s .
* /
lwz r3 , V C P U _ V R S A V E ( r4 )
2012-04-25 05:27:34 +04:00
PPC_ L D ( r5 , V C P U _ S H A R E D _ S P R G 4 , r11 )
2011-12-20 19:34:43 +04:00
mtspr S P R N _ V R S A V E , r3
2012-04-25 05:27:34 +04:00
PPC_ L D ( r6 , V C P U _ S H A R E D _ S P R G 5 , r11 )
2011-12-20 19:34:43 +04:00
mtspr S P R N _ S P R G 4 W , r5
2012-04-25 05:27:34 +04:00
PPC_ L D ( r7 , V C P U _ S H A R E D _ S P R G 6 , r11 )
2011-12-20 19:34:43 +04:00
mtspr S P R N _ S P R G 5 W , r6
2012-04-25 05:27:34 +04:00
PPC_ L D ( r8 , V C P U _ S H A R E D _ S P R G 7 , r11 )
2011-12-20 19:34:43 +04:00
mtspr S P R N _ S P R G 6 W , r7
mtspr S P R N _ S P R G 7 W , r8
/* Load some guest volatiles. */
PPC_ L L r3 , V C P U _ L R ( r4 )
PPC_ L L r5 , V C P U _ X E R ( r4 )
PPC_ L L r6 , V C P U _ C T R ( r4 )
2012-04-16 08:08:54 +04:00
lwz r7 , V C P U _ C R ( r4 )
2011-12-20 19:34:43 +04:00
PPC_ L L r8 , V C P U _ P C ( r4 )
2012-04-25 05:26:43 +04:00
PPC_ L D ( r9 , V C P U _ S H A R E D _ M S R , r11 )
2011-12-20 19:34:43 +04:00
PPC_ L L r0 , V C P U _ G P R ( r0 ) ( r4 )
PPC_ L L r1 , V C P U _ G P R ( r1 ) ( r4 )
PPC_ L L r2 , V C P U _ G P R ( r2 ) ( r4 )
PPC_ L L r10 , V C P U _ G P R ( r10 ) ( r4 )
PPC_ L L r11 , V C P U _ G P R ( r11 ) ( r4 )
PPC_ L L r12 , V C P U _ G P R ( r12 ) ( r4 )
PPC_ L L r13 , V C P U _ G P R ( r13 ) ( r4 )
mtlr r3
mtxer r5
mtctr r6
mtsrr0 r8
mtsrr1 r9
# ifdef C O N F I G _ K V M _ E X I T _ T I M I N G
/* save enter time */
1 :
mfspr r6 , S P R N _ T B R U
2012-03-05 05:34:08 +04:00
mfspr r9 , S P R N _ T B R L
2011-12-20 19:34:43 +04:00
mfspr r8 , S P R N _ T B R U
cmpw r8 , r6
2012-04-16 08:08:54 +04:00
stw r9 , V C P U _ T I M I N G _ L A S T _ E N T E R _ T B L ( r4 )
2011-12-20 19:34:43 +04:00
bne 1 b
2012-04-16 08:08:54 +04:00
stw r8 , V C P U _ T I M I N G _ L A S T _ E N T E R _ T B U ( r4 )
2011-12-20 19:34:43 +04:00
# endif
2012-03-05 05:34:08 +04:00
/ *
* Don' t e x e c u t e a n y i n s t r u c t i o n w h i c h c a n c h a n g e C R a f t e r
* below i n s t r u c t i o n .
* /
mtcr r7
2011-12-20 19:34:43 +04:00
/* Finish loading guest volatiles and jump to guest. */
PPC_ L L r5 , V C P U _ G P R ( r5 ) ( r4 )
PPC_ L L r6 , V C P U _ G P R ( r6 ) ( r4 )
PPC_ L L r7 , V C P U _ G P R ( r7 ) ( r4 )
PPC_ L L r8 , V C P U _ G P R ( r8 ) ( r4 )
PPC_ L L r9 , V C P U _ G P R ( r9 ) ( r4 )
PPC_ L L r3 , V C P U _ G P R ( r3 ) ( r4 )
PPC_ L L r4 , V C P U _ G P R ( r4 ) ( r4 )
rfi