2019-05-29 17:12:40 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
2009-10-30 08:47:09 +03:00
/ *
*
* 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 >
2011-07-23 11:41:11 +04:00
# include < a s m / m m u . h >
2009-10-30 08:47:09 +03:00
# include < a s m / p a g e . h >
# include < a s m / a s m - o f f s e t s . h >
2018-07-05 19:24:57 +03:00
# include < a s m / a s m - c o m p a t . h >
2010-04-16 02:11:46 +04:00
# ifdef C O N F I G _ P P C _ B O O K 3 S _ 6 4
2009-10-30 08:47:09 +03:00
# include < a s m / e x c e p t i o n - 6 4 s . h >
2010-04-16 02:11:46 +04:00
# endif
2009-10-30 08:47:09 +03:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Real M o d e h a n d l e r s t h a t n e e d t o b e i n l o w p h y s i c a l m e m o r y *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2010-04-16 02:11:46 +04: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 )
2016-06-06 19:56:10 +03:00
# ifdef P P C 6 4 _ E L F _ A B I _ v2
2014-06-16 16:37:53 +04:00
# define F U N C ( n a m e ) n a m e
# else
2010-04-16 02:11:46 +04:00
# define F U N C ( n a m e ) G L U E ( . ,n a m e )
2014-06-16 16:37:53 +04:00
# endif
2010-04-16 02:11:46 +04:00
2011-06-29 04:18:26 +04:00
# 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 )
2010-04-16 02:11:46 +04:00
# define F U N C ( n a m e ) n a m e
2020-11-08 19:57:36 +03:00
# define R F I _ T O _ K E R N E L r f i
# define R F I _ T O _ G U E S T r f i
2018-01-09 19:07:15 +03:00
2009-10-30 08:47:09 +03:00
.macro INTERRUPT_TRAMPOLINE intno
.global kvmppc_ t r a m p o l i n e _ \ i n t n o
kvmppc_ t r a m p o l i n e _ \ i n t n o :
2011-06-29 04:18:26 +04:00
mtspr S P R N _ S P R G _ S C R A T C H 0 , r13 / * S a v e r13 * /
2009-10-30 08:47:09 +03:00
/ *
* First t h i n g t o d o i s t o f i n d o u t i f w e ' r e c o m i n g
* from a K V M g u e s t o r a L i n u x p r o c e s s .
*
2010-04-16 02:11:46 +04:00
* To d i s t i n g u i s h , w e c h e c k a m a g i c b y t e i n t h e P A C A / c u r r e n t
2009-10-30 08:47:09 +03:00
* /
2011-06-29 04:18:26 +04:00
mfspr r13 , S P R N _ S P R G _ T H R E A D
lwz r13 , T H R E A D _ K V M _ S V C P U ( r13 )
/* PPC32 can have a NULL pointer - let's check for that */
mtspr S P R N _ S P R G _ S C R A T C H 1 , r12 / * S a v e r12 * /
2009-10-30 08:47:09 +03:00
mfcr r12
2011-06-29 04:18:26 +04:00
cmpwi r13 , 0
bne 1 f
2 : mtcr r12
mfspr r12 , S P R N _ S P R G _ S C R A T C H 1
mfspr r13 , S P R N _ S P R G _ S C R A T C H 0 / * r13 = o r i g i n a l r13 * /
b k v m p p c _ r e s u m e _ \ i n t n o / * G e t b a c k o r i g i n a l h a n d l e r * /
1 : tophys( r13 , r13 )
2011-06-29 04:20:58 +04:00
stw r12 , H S T A T E _ S C R A T C H 1 ( r13 )
2011-06-29 04:18:26 +04:00
mfspr r12 , S P R N _ S P R G _ S C R A T C H 1
2011-06-29 04:20:58 +04:00
stw r12 , H S T A T E _ S C R A T C H 0 ( r13 )
lbz r12 , H S T A T E _ I N _ G U E S T ( r13 )
2010-01-08 04:58:04 +03:00
cmpwi r12 , K V M _ G U E S T _ M O D E _ N O N E
2009-10-30 08:47:09 +03:00
bne . . k v m p p c _ h a n d l e r _ h a s m a g i c _ \ i n t n o
/* No KVM guest? Then jump back to the Linux handler! */
2011-06-29 04:20:58 +04:00
lwz r12 , H S T A T E _ S C R A T C H 1 ( r13 )
2011-06-29 04:18:26 +04:00
b 2 b
2009-10-30 08:47:09 +03:00
/* Now we know we're handling a KVM guest */
. .kvmppc_handler_hasmagic_ \ intno :
2010-01-08 04:58:04 +03:00
/* Should we just skip the faulting instruction? */
cmpwi r12 , K V M _ G U E S T _ M O D E _ S K I P
beq k v m p p c _ h a n d l e r _ s k i p _ i n s
2009-10-30 08:47:09 +03:00
/* Let's store which interrupt we're handling */
li r12 , \ i n t n o
/* Jump into the SLB exit code that goes to the highmem handler */
b k v m p p c _ h a n d l e r _ t r a m p o l i n e _ e x i t
.endm
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ S Y S T E M _ R E S E T
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ M A C H I N E _ C H E C K
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ D A T A _ S T O R A G E
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ I N S T _ S T O R A G E
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ E X T E R N A L
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ A L I G N M E N T
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ P R O G R A M
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ F P _ U N A V A I L
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ D E C R E M E N T E R
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ S Y S C A L L
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ T R A C E
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ P E R F M O N
INTERRUPT_ T R A M P O L I N E B O O K 3 S _ I N T E R R U P T _ A L T I V E C
2010-04-16 02:11:46 +04:00
2010-01-08 04:58:04 +03:00
/ *
* Bring u s b a c k t o t h e f a u l t i n g c o d e , b u t s k i p t h e
* faulting i n s t r u c t i o n .
*
* This i s a g e n e r i c e x i t p a t h f r o m t h e i n t e r r u p t
* trampolines a b o v e .
*
* Input R e g i s t e r s :
*
2010-04-16 02:11:46 +04:00
* R1 2 = f r e e
* R1 3 = S h a d o w V C P U ( P A C A )
2011-06-29 04:20:58 +04:00
* HSTATE. S C R A T C H 0 = g u e s t R 1 2
* HSTATE. S C R A T C H 1 = g u e s t C R
2010-04-16 02:11:46 +04:00
* SPRG_ S C R A T C H 0 = g u e s t R 1 3
2010-01-08 04:58:04 +03:00
*
* /
kvmppc_handler_skip_ins :
/* Patch the IP to the next instruction */
mfsrr0 r12
addi r12 , r12 , 4
mtsrr0 r12
/* Clean up all state */
2011-06-29 04:20:58 +04:00
lwz r12 , H S T A T E _ S C R A T C H 1 ( r13 )
2010-01-08 04:58:04 +03:00
mtcr r12
2011-06-29 04:20:58 +04:00
PPC_ L L r12 , H S T A T E _ S C R A T C H 0 ( r13 )
2011-04-05 07:59:58 +04:00
GET_ S C R A T C H 0 ( r13 )
2010-01-08 04:58:04 +03:00
/* And get back into the code */
2018-01-09 19:07:15 +03:00
RFI_ T O _ K E R N E L
2011-06-29 04:18:26 +04:00
# endif
2010-01-08 04:58:04 +03:00
2009-10-30 08:47:09 +03:00
/ *
2011-07-23 11:41:44 +04:00
* Call k v m p p c _ h a n d l e r _ t r a m p o l i n e _ e n t e r i n r e a l m o d e
2009-10-30 08:47:09 +03:00
*
2011-07-23 11:41:44 +04:00
* On e n t r y , r4 c o n t a i n s t h e g u e s t s h a d o w M S R
2012-08-13 03:04:19 +04:00
* MSR. E E h a s t o b e 0 w h e n c a l l i n g t h i s f u n c t i o n
2009-10-30 08:47:09 +03:00
* /
2014-06-12 12:16:53 +04:00
_ GLOBAL_ T O C ( k v m p p c _ e n t r y _ t r a m p o l i n e )
2011-07-23 11:41:44 +04:00
mfmsr r5
LOAD_ R E G _ A D D R ( r7 , k v m p p c _ h a n d l e r _ t r a m p o l i n e _ e n t e r )
toreal( r7 )
li r6 , M S R _ I R | M S R _ D R
2012-08-13 03:04:19 +04:00
andc r6 , r5 , r6 / * C l e a r D R a n d I R i n M S R v a l u e * /
/ *
* Set E E i n H O S T _ M S R s o t h a t i t ' s e n a b l e d w h e n w e g e t i n t o o u r
2013-11-29 05:32:31 +04:00
* C e x i t h a n d l e r f u n c t i o n .
2012-08-13 03:04:19 +04:00
* /
ori r5 , r5 , M S R _ E E
mtsrr0 r7
2010-01-08 04:58:03 +03:00
mtsrr1 r6
2018-01-09 19:07:15 +03:00
RFI_ T O _ K E R N E L
2010-01-08 04:58:06 +03:00
2010-04-16 02:11:48 +04:00
# include " b o o k 3 s _ s e g m e n t . S "