2009-10-30 05:47:07 +00: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 S U S E L i n u x P r o d u c t s G m b H 2 0 0 9
*
* Authors : Alexander G r a f < a g r a f @suse.de>
* /
# 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 / p a g e . h >
# include < a s m / a s m - o f f s e t s . h >
# include < a s m / e x c e p t i o n - 6 4 s . h >
2010-04-16 00:11:47 +02:00
# if d e f i n e d ( C O N F I G _ P P C _ B O O K 3 S _ 6 4 )
# define F U N C ( n a m e ) G L U E ( . ,n a m e )
# elif d e f i n e d ( C O N F I G _ P P C _ B O O K 3 S _ 3 2 )
# define F U N C ( n a m e ) n a m e
# endif / * C O N F I G _ P P C _ B O O K 3 S _ X X * /
2010-01-04 22:19:25 +01:00
# define V C P U _ L O A D _ N V G P R S ( v c p u ) \
2012-06-25 13:33:10 +00:00
PPC_ L L r14 , V C P U _ G P R ( R 1 4 ) ( v c p u ) ; \
PPC_ L L r15 , V C P U _ G P R ( R 1 5 ) ( v c p u ) ; \
PPC_ L L r16 , V C P U _ G P R ( R 1 6 ) ( v c p u ) ; \
PPC_ L L r17 , V C P U _ G P R ( R 1 7 ) ( v c p u ) ; \
PPC_ L L r18 , V C P U _ G P R ( R 1 8 ) ( v c p u ) ; \
PPC_ L L r19 , V C P U _ G P R ( R 1 9 ) ( v c p u ) ; \
PPC_ L L r20 , V C P U _ G P R ( R 2 0 ) ( v c p u ) ; \
PPC_ L L r21 , V C P U _ G P R ( R 2 1 ) ( v c p u ) ; \
PPC_ L L r22 , V C P U _ G P R ( R 2 2 ) ( v c p u ) ; \
PPC_ L L r23 , V C P U _ G P R ( R 2 3 ) ( v c p u ) ; \
PPC_ L L r24 , V C P U _ G P R ( R 2 4 ) ( v c p u ) ; \
PPC_ L L r25 , V C P U _ G P R ( R 2 5 ) ( v c p u ) ; \
PPC_ L L r26 , V C P U _ G P R ( R 2 6 ) ( v c p u ) ; \
PPC_ L L r27 , V C P U _ G P R ( R 2 7 ) ( v c p u ) ; \
PPC_ L L r28 , V C P U _ G P R ( R 2 8 ) ( v c p u ) ; \
PPC_ L L r29 , V C P U _ G P R ( R 2 9 ) ( v c p u ) ; \
PPC_ L L r30 , V C P U _ G P R ( R 3 0 ) ( v c p u ) ; \
PPC_ L L r31 , V C P U _ G P R ( R 3 1 ) ( v c p u ) ; \
2010-01-04 22:19:25 +01:00
2009-10-30 05:47:07 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Guest e n t r y / e x i t c o d e t h a t i s i n k e r n e l m o d u l e m e m o r y ( h i g h m e m ) *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * Registers :
* r3 : kvm_ r u n p o i n t e r
* r4 : vcpu p o i n t e r
* /
2011-06-29 00:19:50 +00:00
_ GLOBAL( _ _ k v m p p c _ v c p u _ r u n )
2009-10-30 05:47:07 +00:00
kvm_start_entry :
/* Write correct stack frame */
2010-04-16 00:11:47 +02:00
mflr r0
PPC_ S T L r0 ,P P C _ L R _ S T K O F F ( r1 )
2009-10-30 05:47:07 +00:00
/* Save host state to the stack */
2010-04-16 00:11:47 +02:00
PPC_ S T L U r1 , - S W I T C H _ F R A M E _ S I Z E ( r1 )
2009-10-30 05:47:07 +00:00
/* Save r3 (kvm_run) and r4 (vcpu) */
SAVE_ 2 G P R S ( 3 , r1 )
/* Save non-volatile registers (r14 - r31) */
SAVE_ N V G P R S ( r1 )
2012-03-05 16:00:28 +01:00
/* Save CR */
mfcr r14
stw r14 , _ C C R ( r1 )
2009-10-30 05:47:07 +00:00
/* Save LR */
2010-04-16 00:11:47 +02:00
PPC_ S T L r0 , _ L I N K ( r1 )
2010-01-04 22:19:25 +01:00
/* Load non-volatile guest state from the vcpu */
VCPU_ L O A D _ N V G P R S ( r4 )
2009-10-30 05:47:07 +00:00
2011-06-29 00:20:58 +00:00
kvm_start_lightweight :
2010-01-08 02:58:03 +01:00
2010-04-16 00:11:47 +02:00
# ifdef C O N F I G _ P P C _ B O O K 3 S _ 6 4
PPC_ L L r3 , V C P U _ H F L A G S ( r4 )
2011-07-23 17:41:44 +10:00
rldicl r3 , r3 , 0 , 6 3 / * r3 & = 1 * /
stb r3 , H S T A T E _ R E S T O R E _ H I D 5 ( r13 )
2010-04-16 00:11:47 +02:00
# endif / * C O N F I G _ P P C _ B O O K 3 S _ 6 4 * /
2011-07-23 17:41:44 +10:00
PPC_ L L r4 , V C P U _ S H A D O W _ M S R ( r4 ) / * g e t s h a d o w _ m s r * /
2010-01-08 02:58:03 +01:00
2010-04-16 00:11:47 +02:00
/* Jump to segment patching handler and into our guest */
2011-07-23 17:41:44 +10:00
bl F U N C ( k v m p p c _ e n t r y _ t r a m p o l i n e )
nop
2009-10-30 05:47:07 +00:00
/ *
* This i s t h e h a n d l e r i n m o d u l e m e m o r y . I t g e t s j u m p e d a t f r o m t h e
* lowmem t r a m p o l i n e c o d e , s o i t ' s b a s i c a l l y t h e g u e s t e x i t c o d e .
*
* /
.global kvmppc_handler_highmem
kvmppc_handler_highmem :
/ *
* Register u s a g e a t t h i s p o i n t :
*
2010-04-16 00:11:47 +02:00
* R1 = h o s t R 1
* R2 = h o s t R 2
* R1 2 = e x i t h a n d l e r i d
* R1 3 = P A C A
* SVCPU. * = g u e s t *
2009-10-30 05:47:07 +00:00
*
* /
2010-01-08 02:58:03 +01:00
/* R7 = vcpu */
2010-04-16 00:11:47 +02:00
PPC_ L L r7 , G P R 4 ( r1 )
2009-10-30 05:47:07 +00:00
2012-06-25 13:33:10 +00:00
PPC_ S T L r14 , V C P U _ G P R ( R 1 4 ) ( r7 )
PPC_ S T L r15 , V C P U _ G P R ( R 1 5 ) ( r7 )
PPC_ S T L r16 , V C P U _ G P R ( R 1 6 ) ( r7 )
PPC_ S T L r17 , V C P U _ G P R ( R 1 7 ) ( r7 )
PPC_ S T L r18 , V C P U _ G P R ( R 1 8 ) ( r7 )
PPC_ S T L r19 , V C P U _ G P R ( R 1 9 ) ( r7 )
PPC_ S T L r20 , V C P U _ G P R ( R 2 0 ) ( r7 )
PPC_ S T L r21 , V C P U _ G P R ( R 2 1 ) ( r7 )
PPC_ S T L r22 , V C P U _ G P R ( R 2 2 ) ( r7 )
PPC_ S T L r23 , V C P U _ G P R ( R 2 3 ) ( r7 )
PPC_ S T L r24 , V C P U _ G P R ( R 2 4 ) ( r7 )
PPC_ S T L r25 , V C P U _ G P R ( R 2 5 ) ( r7 )
PPC_ S T L r26 , V C P U _ G P R ( R 2 6 ) ( r7 )
PPC_ S T L r27 , V C P U _ G P R ( R 2 7 ) ( r7 )
PPC_ S T L r28 , V C P U _ G P R ( R 2 8 ) ( r7 )
PPC_ S T L r29 , V C P U _ G P R ( R 2 9 ) ( r7 )
PPC_ S T L r30 , V C P U _ G P R ( R 3 0 ) ( r7 )
PPC_ S T L r31 , V C P U _ G P R ( R 3 1 ) ( r7 )
2009-10-30 05:47:07 +00:00
2010-01-04 22:19:25 +01:00
/* Pass the exit number as 3rd argument to kvmppc_handle_exit */
2010-01-08 02:58:03 +01:00
mr r5 , r12
2010-01-04 22:19:25 +01:00
2009-10-30 05:47:07 +00:00
/* Restore r3 (kvm_run) and r4 (vcpu) */
REST_ 2 G P R S ( 3 , r1 )
2010-04-16 00:11:47 +02:00
bl F U N C ( k v m p p c _ h a n d l e _ e x i t )
2009-10-30 05:47:07 +00:00
2010-01-04 22:19:25 +01:00
/* If RESUME_GUEST, get back in the loop */
2009-10-30 05:47:07 +00:00
cmpwi r3 , R E S U M E _ G U E S T
2010-01-04 22:19:25 +01:00
beq k v m _ l o o p _ l i g h t w e i g h t
2009-10-30 05:47:07 +00:00
2010-01-04 22:19:25 +01:00
cmpwi r3 , R E S U M E _ G U E S T _ N V
beq k v m _ l o o p _ h e a v y w e i g h t
2009-10-30 05:47:07 +00:00
2010-01-04 22:19:25 +01:00
kvm_exit_loop :
2009-10-30 05:47:07 +00:00
2010-04-16 00:11:47 +02:00
PPC_ L L r4 , _ L I N K ( r1 )
2009-10-30 05:47:07 +00:00
mtlr r4
2012-03-05 16:00:28 +01:00
lwz r14 , _ C C R ( r1 )
mtcr r14
2010-01-04 22:19:25 +01:00
/* Restore non-volatile host registers (r14 - r31) */
REST_ N V G P R S ( r1 )
addi r1 , r1 , S W I T C H _ F R A M E _ S I Z E
blr
kvm_loop_heavyweight :
2009-10-30 05:47:07 +00:00
2010-04-16 00:11:47 +02:00
PPC_ L L r4 , _ L I N K ( r1 )
PPC_ S T L r4 , ( P P C _ L R _ S T K O F F + S W I T C H _ F R A M E _ S I Z E ) ( r1 )
2010-01-04 22:19:25 +01:00
/* Load vcpu and cpu_run */
2009-10-30 05:47:07 +00:00
REST_ 2 G P R S ( 3 , r1 )
2010-01-04 22:19:25 +01:00
/* Load non-volatile guest state from the vcpu */
VCPU_ L O A D _ N V G P R S ( r4 )
2009-10-30 05:47:07 +00:00
2010-01-04 22:19:25 +01:00
/* Jump back into the beginning of this function */
b k v m _ s t a r t _ l i g h t w e i g h t
2009-10-30 05:47:07 +00:00
2010-01-04 22:19:25 +01:00
kvm_loop_lightweight :
2009-10-30 05:47:07 +00:00
2010-01-04 22:19:25 +01:00
/* We'll need the vcpu pointer */
REST_ G P R ( 4 , r1 )
/* Jump back into the beginning of this function */
b k v m _ s t a r t _ l i g h t w e i g h t