2019-02-20 12:26:58 +05:30
/* SPDX-License-Identifier: GPL-2.0 */
/ *
* Non- e m u l a t e d s i n g l e - s t e p p i n g s u p p o r t ( c u r r e n t l y l i m i t e d t o b a s i c i n t e g e r
* computations) u s e d t o v a l i d a t e t h e i n s t r u c t i o n e m u l a t i o n i n f r a s t r u c t u r e .
*
* Copyright ( C ) 2 0 1 9 I B M C o r p o r a t i o n
* /
# include < a s m / a s m - o f f s e t s . h >
# include < a s m / p p c _ a s m . h >
# include < a s m / c o d e - p a t c h i n g - a s m . h >
# include < l i n u x / e r r n o . h >
/* int exec_instr(struct pt_regs *regs) */
_ GLOBAL( e x e c _ i n s t r )
/ *
* Stack f r a m e l a y o u t ( I N T _ F R A M E _ S I Z E b y t e s )
* In- m e m o r y p t _ r e g s ( S P + S T A C K _ F R A M E _ O V E R H E A D )
* Scratch s p a c e ( S P + 8 )
* Back c h a i n ( S P + 0 )
* /
/ *
* Allocate a n e w s t a c k f r a m e w i t h e n o u g h s p a c e t o h o l d t h e r e g i s t e r
* states i n a n i n - m e m o r y p t _ r e g s a n d a l s o c r e a t e t h e b a c k c h a i n t o
* the c a l l e r ' s s t a c k f r a m e .
* /
stdu r1 , - I N T _ F R A M E _ S I Z E ( r1 )
/ *
* Save n o n - v o l a t i l e G P R s o n s t a c k . T h i s i n c l u d e s T O C p o i n t e r ( G P R 2 )
* and l o c a l v a r i a b l e s ( G P R 1 4 t o G P R 3 1 ) . T h e r e g i s t e r f o r t h e p t _ r e g s
* parameter ( G P R 3 ) i s s a v e d a d d i t i o n a l l y t o e n s u r e t h a t t h e r e s u l t i n g
* register s t a t e c a n s t i l l b e s a v e d e v e n i f G P R 3 g e t s o v e r w r i t t e n
* when l o a d i n g t h e i n i t i a l r e g i s t e r s t a t e f o r t h e t e s t i n s t r u c t i o n .
* The s t a c k p o i n t e r ( G P R 1 ) a n d t h e t h r e a d p o i n t e r ( G P R 1 3 ) a r e n o t
* saved a s t h e s e s h o u l d n o t b e m o d i f i e d a n y w a y .
* /
SAVE_ 2 G P R S ( 2 , r1 )
SAVE_ N V G P R S ( r1 )
/ *
* Save L R o n s t a c k t o e n s u r e t h a t t h e r e t u r n a d d r e s s i s a v a i l a b l e
* even i f i t g e t s o v e r w r i t t e n b y t h e t e s t i n s t r u c t i o n .
* /
mflr r0
std r0 , _ L I N K ( r1 )
/ *
* Save C R o n s t a c k . F o r s i m p l i c i t y , t h e e n t i r e r e g i s t e r i s s a v e d
* even t h o u g h o n l y f i e l d s 2 t o 4 a r e n o n - v o l a t i l e .
* /
mfcr r0
std r0 , _ C C R ( r1 )
/ *
* Load r e g i s t e r s t a t e f o r t h e t e s t i n s t r u c t i o n w i t h o u t t o u c h i n g t h e
* critical n o n - v o l a t i l e r e g i s t e r s . T h e r e g i s t e r s t a t e i s p a s s e d a s a
* pointer t o a p t _ r e g s i n s t a n c e .
* /
subi r31 , r3 , G P R 0
/* Load LR from pt_regs */
ld r0 , _ L I N K ( r31 )
mtlr r0
/* Load CR from pt_regs */
ld r0 , _ C C R ( r31 )
mtcr r0
/* Load XER from pt_regs */
ld r0 , _ X E R ( r31 )
mtxer r0
/* Load GPRs from pt_regs */
REST_ G P R ( 0 , r31 )
REST_ 1 0 G P R S ( 2 , r31 )
REST_ G P R ( 1 2 , r31 )
REST_ N V G P R S ( r31 )
/* Placeholder for the test instruction */
2020-05-25 12:59:23 +10:00
.balign 64
2019-02-20 12:26:58 +05:30
1 : nop
2020-05-25 12:59:23 +10:00
nop
2019-02-20 12:26:58 +05:30
patch_ s i t e 1 b p a t c h _ _ e x e c _ i n s t r
/ *
* Since G P R 3 i s o v e r w r i t t e n , t e m p o r a r i l y r e s t o r e i t b a c k t o i t s
* original s t a t e , i . e . t h e p o i n t e r t o p t _ r e g s , t o e n s u r e t h a t t h e
* resulting r e g i s t e r s t a t e c a n b e s a v e d . B e f o r e d o i n g t h i s , a c o p y
* of i t i s c r e a t e d i n t h e s c r a t c h s p a c e w h i c h i s u s e d l a t e r o n t o
* save i t t o p t _ r e g s .
* /
std r3 , 8 ( r1 )
REST_ G P R ( 3 , r1 )
/* Save resulting GPR state to pt_regs */
subi r3 , r3 , G P R 0
SAVE_ G P R ( 0 , r3 )
SAVE_ G P R ( 2 , r3 )
SAVE_ 8 G P R S ( 4 , r3 )
SAVE_ G P R ( 1 2 , r3 )
SAVE_ N V G P R S ( r3 )
/* Save resulting LR to pt_regs */
mflr r0
std r0 , _ L I N K ( r3 )
/* Save resulting CR to pt_regs */
mfcr r0
std r0 , _ C C R ( r3 )
/* Save resulting XER to pt_regs */
mfxer r0
std r0 , _ X E R ( r3 )
/* Restore resulting GPR3 from scratch space and save it to pt_regs */
ld r0 , 8 ( r1 )
std r0 , G P R 3 ( r3 )
/* Set return value to denote execution success */
li r3 , 0
/* Continue */
b 3 f
/* Set return value to denote execution failure */
2 : li r3 , - E F A U L T
/* Restore the non-volatile GPRs from stack */
3 : REST_ G P R ( 2 , r1 )
REST_ N V G P R S ( r1 )
/* Restore LR from stack to be able to return */
ld r0 , _ L I N K ( r1 )
mtlr r0
/* Restore CR from stack */
ld r0 , _ C C R ( r1 )
mtcr r0
/* Tear down stack frame */
addi r1 , r1 , I N T _ F R A M E _ S I Z E
/* Return */
blr
/* Setup exception table */
EX_ T A B L E ( 1 b , 2 b )
_ ASM_ N O K P R O B E _ S Y M B O L ( e x e c _ i n s t r )