2012-12-10 20:40:18 +04:00
/ *
* Copyright ( C ) 2 0 1 2 ,2 0 1 3 - A R M L t d
* Author : Marc Z y n g i e r < m a r c . z y n g i e r @arm.com>
*
* 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 . I f n o t , s e e < h t t p : / / w w w . g n u . o r g / l i c e n s e s / > .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
# include < a s m / m e m o r y . h >
# include < a s m / a s m - o f f s e t s . h >
2014-05-07 16:44:49 +04:00
# include < a s m / d e b u g - m o n i t o r s . h >
2012-12-10 20:40:18 +04:00
# include < a s m / f p s i m d m a c r o s . h >
# include < a s m / k v m . h >
# include < a s m / k v m _ a s m . h >
# include < a s m / k v m _ a r m . h >
# include < a s m / k v m _ m m u . h >
# define C P U _ G P _ R E G _ O F F S E T ( x ) ( C P U _ G P _ R E G S + x )
# define C P U _ X R E G _ O F F S E T ( x ) C P U _ G P _ R E G _ O F F S E T ( C P U _ U S E R _ P T _ R E G S + 8 * x )
# define C P U _ S P S R _ O F F S E T ( x ) C P U _ G P _ R E G _ O F F S E T ( C P U _ S P S R + 8 * x )
# define C P U _ S Y S R E G _ O F F S E T ( x ) ( C P U _ S Y S R E G S + 8 * x )
.text
.pushsection .hyp .text , " ax"
.align PAGE_SHIFT
.macro save_common_regs
/ / x2 : base a d d r e s s f o r c p u c o n t e x t
/ / x3 : tmp r e g i s t e r
add x3 , x2 , #C P U _ X R E G _ O F F S E T ( 19 )
stp x19 , x20 , [ x3 ]
stp x21 , x22 , [ x3 , #16 ]
stp x23 , x24 , [ x3 , #32 ]
stp x25 , x26 , [ x3 , #48 ]
stp x27 , x28 , [ x3 , #64 ]
stp x29 , l r , [ x3 , #80 ]
mrs x19 , s p _ e l 0
mrs x20 , e l r _ e l 2 / / E L 1 P C
mrs x21 , s p s r _ e l 2 / / E L 1 p s t a t e
stp x19 , x20 , [ x3 , #96 ]
str x21 , [ x3 , #112 ]
mrs x22 , s p _ e l 1
mrs x23 , e l r _ e l 1
mrs x24 , s p s r _ e l 1
str x22 , [ x2 , #C P U _ G P _ R E G _ O F F S E T ( C P U _ S P _ E L 1 ) ]
str x23 , [ x2 , #C P U _ G P _ R E G _ O F F S E T ( C P U _ E L R _ E L 1 ) ]
str x24 , [ x2 , #C P U _ S P S R _ O F F S E T ( K V M _ S P S R _ E L 1 ) ]
.endm
.macro restore_common_regs
/ / x2 : base a d d r e s s f o r c p u c o n t e x t
/ / x3 : tmp r e g i s t e r
ldr x22 , [ x2 , #C P U _ G P _ R E G _ O F F S E T ( C P U _ S P _ E L 1 ) ]
ldr x23 , [ x2 , #C P U _ G P _ R E G _ O F F S E T ( C P U _ E L R _ E L 1 ) ]
ldr x24 , [ x2 , #C P U _ S P S R _ O F F S E T ( K V M _ S P S R _ E L 1 ) ]
msr s p _ e l 1 , x22
msr e l r _ e l 1 , x23
msr s p s r _ e l 1 , x24
add x3 , x2 , #C P U _ X R E G _ O F F S E T ( 31 ) / / S P _ E L 0
ldp x19 , x20 , [ x3 ]
ldr x21 , [ x3 , #16 ]
msr s p _ e l 0 , x19
msr e l r _ e l 2 , x20 / / E L 1 P C
msr s p s r _ e l 2 , x21 / / E L 1 p s t a t e
add x3 , x2 , #C P U _ X R E G _ O F F S E T ( 19 )
ldp x19 , x20 , [ x3 ]
ldp x21 , x22 , [ x3 , #16 ]
ldp x23 , x24 , [ x3 , #32 ]
ldp x25 , x26 , [ x3 , #48 ]
ldp x27 , x28 , [ x3 , #64 ]
ldp x29 , l r , [ x3 , #80 ]
.endm
.macro save_host_regs
save_ c o m m o n _ r e g s
.endm
.macro restore_host_regs
restore_ c o m m o n _ r e g s
.endm
.macro save_fpsimd
/ / x2 : cpu c o n t e x t a d d r e s s
/ / x3 , x4 : t m p r e g s
add x3 , x2 , #C P U _ G P _ R E G _ O F F S E T ( C P U _ F P _ R E G S )
fpsimd_ s a v e x3 , 4
.endm
.macro restore_fpsimd
/ / x2 : cpu c o n t e x t a d d r e s s
/ / x3 , x4 : t m p r e g s
add x3 , x2 , #C P U _ G P _ R E G _ O F F S E T ( C P U _ F P _ R E G S )
fpsimd_ r e s t o r e x3 , 4
.endm
.macro save_guest_regs
/ / x0 i s t h e v c p u a d d r e s s
/ / x1 i s t h e r e t u r n c o d e , d o n o t c o r r u p t !
/ / x2 i s t h e c p u c o n t e x t
/ / x3 i s a t m p r e g i s t e r
/ / Guest' s x0 - x3 a r e o n t h e s t a c k
/ / Compute b a s e t o s a v e r e g i s t e r s
add x3 , x2 , #C P U _ X R E G _ O F F S E T ( 4 )
stp x4 , x5 , [ x3 ]
stp x6 , x7 , [ x3 , #16 ]
stp x8 , x9 , [ x3 , #32 ]
stp x10 , x11 , [ x3 , #48 ]
stp x12 , x13 , [ x3 , #64 ]
stp x14 , x15 , [ x3 , #80 ]
stp x16 , x17 , [ x3 , #96 ]
str x18 , [ x3 , #112 ]
pop x6 , x7 / / x2 , x3
pop x4 , x5 / / x0 , x1
add x3 , x2 , #C P U _ X R E G _ O F F S E T ( 0 )
stp x4 , x5 , [ x3 ]
stp x6 , x7 , [ x3 , #16 ]
save_ c o m m o n _ r e g s
.endm
.macro restore_guest_regs
/ / x0 i s t h e v c p u a d d r e s s .
/ / x2 i s t h e c p u c o n t e x t
/ / x3 i s a t m p r e g i s t e r
/ / Prepare x0 - x3 f o r l a t e r r e s t o r e
add x3 , x2 , #C P U _ X R E G _ O F F S E T ( 0 )
ldp x4 , x5 , [ x3 ]
ldp x6 , x7 , [ x3 , #16 ]
push x4 , x5 / / P u s h x0 - x3 o n t h e s t a c k
push x6 , x7
/ / x4 - x18
ldp x4 , x5 , [ x3 , #32 ]
ldp x6 , x7 , [ x3 , #48 ]
ldp x8 , x9 , [ x3 , #64 ]
ldp x10 , x11 , [ x3 , #80 ]
ldp x12 , x13 , [ x3 , #96 ]
ldp x14 , x15 , [ x3 , #112 ]
ldp x16 , x17 , [ x3 , #128 ]
ldr x18 , [ x3 , #144 ]
/ / x1 9 - x29 , l r , s p * , e l r * , s p s r *
restore_ c o m m o n _ r e g s
/ / Last b i t s o f t h e 6 4 b i t s t a t e
pop x2 , x3
pop x0 , x1
/ / Do n o t t o u c h a n y r e g i s t e r a f t e r t h i s !
.endm
/ *
* Macros t o p e r f o r m s y s t e m r e g i s t e r s a v e / r e s t o r e .
*
* Ordering h e r e i s a b s o l u t e l y c r i t i c a l , a n d m u s t b e k e p t c o n s i s t e n t
* in { s a v e ,r e s t o r e } _ s y s r e g s , { s a v e ,r e s t o r e } _ g u e s t _ 3 2 b i t _ s t a t e ,
* and i n k v m _ a s m . h .
*
* In o t h e r w o r d s , d o n ' t t o u c h a n y o f t h e s e u n l e s s y o u k n o w w h a t
* you a r e d o i n g .
* /
.macro save_sysregs
/ / x2 : base a d d r e s s f o r c p u c o n t e x t
/ / x3 : tmp r e g i s t e r
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( M P I D R _ E L 1 )
mrs x4 , v m p i d r _ e l 2
mrs x5 , c s s e l r _ e l 1
mrs x6 , s c t l r _ e l 1
mrs x7 , a c t l r _ e l 1
mrs x8 , c p a c r _ e l 1
mrs x9 , t t b r0 _ e l 1
mrs x10 , t t b r1 _ e l 1
mrs x11 , t c r _ e l 1
mrs x12 , e s r _ e l 1
mrs x13 , a f s r0 _ e l 1
mrs x14 , a f s r1 _ e l 1
mrs x15 , f a r _ e l 1
mrs x16 , m a i r _ e l 1
mrs x17 , v b a r _ e l 1
mrs x18 , c o n t e x t i d r _ e l 1
mrs x19 , t p i d r _ e l 0
mrs x20 , t p i d r r o _ e l 0
mrs x21 , t p i d r _ e l 1
mrs x22 , a m a i r _ e l 1
mrs x23 , c n t k c t l _ e l 1
2013-06-07 14:02:34 +04:00
mrs x24 , p a r _ e l 1
2014-05-07 16:44:49 +04:00
mrs x25 , m d s c r _ e l 1
2012-12-10 20:40:18 +04:00
stp x4 , x5 , [ x3 ]
stp x6 , x7 , [ x3 , #16 ]
stp x8 , x9 , [ x3 , #32 ]
stp x10 , x11 , [ x3 , #48 ]
stp x12 , x13 , [ x3 , #64 ]
stp x14 , x15 , [ x3 , #80 ]
stp x16 , x17 , [ x3 , #96 ]
stp x18 , x19 , [ x3 , #112 ]
stp x20 , x21 , [ x3 , #128 ]
stp x22 , x23 , [ x3 , #144 ]
2014-05-07 16:44:49 +04:00
stp x24 , x25 , [ x3 , #160 ]
.endm
.macro save_debug
/ / x2 : base a d d r e s s f o r c p u c o n t e x t
/ / x3 : tmp r e g i s t e r
mrs x26 , i d _ a a64 d f r0 _ e l 1
ubfx x24 , x26 , #12 , #4 / / E x t r a c t B R P s
ubfx x25 , x26 , #20 , #4 / / E x t r a c t W R P s
mov w26 , #15
sub w24 , w26 , w24 / / H o w m a n y B P s t o s k i p
sub w25 , w26 , w25 / / H o w m a n y W P s t o s k i p
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D B G B C R 0 _ E L 1 )
adr x26 , 1 f
add x26 , x26 , x24 , l s l #2
br x26
1 :
mrs x20 , d b g b c r15 _ e l 1
mrs x19 , d b g b c r14 _ e l 1
mrs x18 , d b g b c r13 _ e l 1
mrs x17 , d b g b c r12 _ e l 1
mrs x16 , d b g b c r11 _ e l 1
mrs x15 , d b g b c r10 _ e l 1
mrs x14 , d b g b c r9 _ e l 1
mrs x13 , d b g b c r8 _ e l 1
mrs x12 , d b g b c r7 _ e l 1
mrs x11 , d b g b c r6 _ e l 1
mrs x10 , d b g b c r5 _ e l 1
mrs x9 , d b g b c r4 _ e l 1
mrs x8 , d b g b c r3 _ e l 1
mrs x7 , d b g b c r2 _ e l 1
mrs x6 , d b g b c r1 _ e l 1
mrs x5 , d b g b c r0 _ e l 1
adr x26 , 1 f
add x26 , x26 , x24 , l s l #2
br x26
1 :
str x20 , [ x3 , #( 15 * 8 ) ]
str x19 , [ x3 , #( 14 * 8 ) ]
str x18 , [ x3 , #( 13 * 8 ) ]
str x17 , [ x3 , #( 12 * 8 ) ]
str x16 , [ x3 , #( 11 * 8 ) ]
str x15 , [ x3 , #( 10 * 8 ) ]
str x14 , [ x3 , #( 9 * 8 ) ]
str x13 , [ x3 , #( 8 * 8 ) ]
str x12 , [ x3 , #( 7 * 8 ) ]
str x11 , [ x3 , #( 6 * 8 ) ]
str x10 , [ x3 , #( 5 * 8 ) ]
str x9 , [ x3 , #( 4 * 8 ) ]
str x8 , [ x3 , #( 3 * 8 ) ]
str x7 , [ x3 , #( 2 * 8 ) ]
str x6 , [ x3 , #( 1 * 8 ) ]
str x5 , [ x3 , #( 0 * 8 ) ]
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D B G B V R 0 _ E L 1 )
adr x26 , 1 f
add x26 , x26 , x24 , l s l #2
br x26
1 :
mrs x20 , d b g b v r15 _ e l 1
mrs x19 , d b g b v r14 _ e l 1
mrs x18 , d b g b v r13 _ e l 1
mrs x17 , d b g b v r12 _ e l 1
mrs x16 , d b g b v r11 _ e l 1
mrs x15 , d b g b v r10 _ e l 1
mrs x14 , d b g b v r9 _ e l 1
mrs x13 , d b g b v r8 _ e l 1
mrs x12 , d b g b v r7 _ e l 1
mrs x11 , d b g b v r6 _ e l 1
mrs x10 , d b g b v r5 _ e l 1
mrs x9 , d b g b v r4 _ e l 1
mrs x8 , d b g b v r3 _ e l 1
mrs x7 , d b g b v r2 _ e l 1
mrs x6 , d b g b v r1 _ e l 1
mrs x5 , d b g b v r0 _ e l 1
adr x26 , 1 f
add x26 , x26 , x24 , l s l #2
br x26
1 :
str x20 , [ x3 , #( 15 * 8 ) ]
str x19 , [ x3 , #( 14 * 8 ) ]
str x18 , [ x3 , #( 13 * 8 ) ]
str x17 , [ x3 , #( 12 * 8 ) ]
str x16 , [ x3 , #( 11 * 8 ) ]
str x15 , [ x3 , #( 10 * 8 ) ]
str x14 , [ x3 , #( 9 * 8 ) ]
str x13 , [ x3 , #( 8 * 8 ) ]
str x12 , [ x3 , #( 7 * 8 ) ]
str x11 , [ x3 , #( 6 * 8 ) ]
str x10 , [ x3 , #( 5 * 8 ) ]
str x9 , [ x3 , #( 4 * 8 ) ]
str x8 , [ x3 , #( 3 * 8 ) ]
str x7 , [ x3 , #( 2 * 8 ) ]
str x6 , [ x3 , #( 1 * 8 ) ]
str x5 , [ x3 , #( 0 * 8 ) ]
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D B G W C R 0 _ E L 1 )
adr x26 , 1 f
add x26 , x26 , x25 , l s l #2
br x26
1 :
mrs x20 , d b g w c r15 _ e l 1
mrs x19 , d b g w c r14 _ e l 1
mrs x18 , d b g w c r13 _ e l 1
mrs x17 , d b g w c r12 _ e l 1
mrs x16 , d b g w c r11 _ e l 1
mrs x15 , d b g w c r10 _ e l 1
mrs x14 , d b g w c r9 _ e l 1
mrs x13 , d b g w c r8 _ e l 1
mrs x12 , d b g w c r7 _ e l 1
mrs x11 , d b g w c r6 _ e l 1
mrs x10 , d b g w c r5 _ e l 1
mrs x9 , d b g w c r4 _ e l 1
mrs x8 , d b g w c r3 _ e l 1
mrs x7 , d b g w c r2 _ e l 1
mrs x6 , d b g w c r1 _ e l 1
mrs x5 , d b g w c r0 _ e l 1
adr x26 , 1 f
add x26 , x26 , x25 , l s l #2
br x26
1 :
str x20 , [ x3 , #( 15 * 8 ) ]
str x19 , [ x3 , #( 14 * 8 ) ]
str x18 , [ x3 , #( 13 * 8 ) ]
str x17 , [ x3 , #( 12 * 8 ) ]
str x16 , [ x3 , #( 11 * 8 ) ]
str x15 , [ x3 , #( 10 * 8 ) ]
str x14 , [ x3 , #( 9 * 8 ) ]
str x13 , [ x3 , #( 8 * 8 ) ]
str x12 , [ x3 , #( 7 * 8 ) ]
str x11 , [ x3 , #( 6 * 8 ) ]
str x10 , [ x3 , #( 5 * 8 ) ]
str x9 , [ x3 , #( 4 * 8 ) ]
str x8 , [ x3 , #( 3 * 8 ) ]
str x7 , [ x3 , #( 2 * 8 ) ]
str x6 , [ x3 , #( 1 * 8 ) ]
str x5 , [ x3 , #( 0 * 8 ) ]
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D B G W V R 0 _ E L 1 )
adr x26 , 1 f
add x26 , x26 , x25 , l s l #2
br x26
1 :
mrs x20 , d b g w v r15 _ e l 1
mrs x19 , d b g w v r14 _ e l 1
mrs x18 , d b g w v r13 _ e l 1
mrs x17 , d b g w v r12 _ e l 1
mrs x16 , d b g w v r11 _ e l 1
mrs x15 , d b g w v r10 _ e l 1
mrs x14 , d b g w v r9 _ e l 1
mrs x13 , d b g w v r8 _ e l 1
mrs x12 , d b g w v r7 _ e l 1
mrs x11 , d b g w v r6 _ e l 1
mrs x10 , d b g w v r5 _ e l 1
mrs x9 , d b g w v r4 _ e l 1
mrs x8 , d b g w v r3 _ e l 1
mrs x7 , d b g w v r2 _ e l 1
mrs x6 , d b g w v r1 _ e l 1
mrs x5 , d b g w v r0 _ e l 1
adr x26 , 1 f
add x26 , x26 , x25 , l s l #2
br x26
1 :
str x20 , [ x3 , #( 15 * 8 ) ]
str x19 , [ x3 , #( 14 * 8 ) ]
str x18 , [ x3 , #( 13 * 8 ) ]
str x17 , [ x3 , #( 12 * 8 ) ]
str x16 , [ x3 , #( 11 * 8 ) ]
str x15 , [ x3 , #( 10 * 8 ) ]
str x14 , [ x3 , #( 9 * 8 ) ]
str x13 , [ x3 , #( 8 * 8 ) ]
str x12 , [ x3 , #( 7 * 8 ) ]
str x11 , [ x3 , #( 6 * 8 ) ]
str x10 , [ x3 , #( 5 * 8 ) ]
str x9 , [ x3 , #( 4 * 8 ) ]
str x8 , [ x3 , #( 3 * 8 ) ]
str x7 , [ x3 , #( 2 * 8 ) ]
str x6 , [ x3 , #( 1 * 8 ) ]
str x5 , [ x3 , #( 0 * 8 ) ]
mrs x21 , m d c c i n t _ e l 1
str x21 , [ x2 , #C P U _ S Y S R E G _ O F F S E T ( M D C C I N T _ E L 1 ) ]
2012-12-10 20:40:18 +04:00
.endm
.macro restore_sysregs
/ / x2 : base a d d r e s s f o r c p u c o n t e x t
/ / x3 : tmp r e g i s t e r
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( M P I D R _ E L 1 )
ldp x4 , x5 , [ x3 ]
ldp x6 , x7 , [ x3 , #16 ]
ldp x8 , x9 , [ x3 , #32 ]
ldp x10 , x11 , [ x3 , #48 ]
ldp x12 , x13 , [ x3 , #64 ]
ldp x14 , x15 , [ x3 , #80 ]
ldp x16 , x17 , [ x3 , #96 ]
ldp x18 , x19 , [ x3 , #112 ]
ldp x20 , x21 , [ x3 , #128 ]
ldp x22 , x23 , [ x3 , #144 ]
2014-05-07 16:44:49 +04:00
ldp x24 , x25 , [ x3 , #160 ]
2012-12-10 20:40:18 +04:00
msr v m p i d r _ e l 2 , x4
msr c s s e l r _ e l 1 , x5
msr s c t l r _ e l 1 , x6
msr a c t l r _ e l 1 , x7
msr c p a c r _ e l 1 , x8
msr t t b r0 _ e l 1 , x9
msr t t b r1 _ e l 1 , x10
msr t c r _ e l 1 , x11
msr e s r _ e l 1 , x12
msr a f s r0 _ e l 1 , x13
msr a f s r1 _ e l 1 , x14
msr f a r _ e l 1 , x15
msr m a i r _ e l 1 , x16
msr v b a r _ e l 1 , x17
msr c o n t e x t i d r _ e l 1 , x18
msr t p i d r _ e l 0 , x19
msr t p i d r r o _ e l 0 , x20
msr t p i d r _ e l 1 , x21
msr a m a i r _ e l 1 , x22
msr c n t k c t l _ e l 1 , x23
2013-06-07 14:02:34 +04:00
msr p a r _ e l 1 , x24
2014-05-07 16:44:49 +04:00
msr m d s c r _ e l 1 , x25
.endm
.macro restore_debug
/ / x2 : base a d d r e s s f o r c p u c o n t e x t
/ / x3 : tmp r e g i s t e r
mrs x26 , i d _ a a64 d f r0 _ e l 1
ubfx x24 , x26 , #12 , #4 / / E x t r a c t B R P s
ubfx x25 , x26 , #20 , #4 / / E x t r a c t W R P s
mov w26 , #15
sub w24 , w26 , w24 / / H o w m a n y B P s t o s k i p
sub w25 , w26 , w25 / / H o w m a n y W P s t o s k i p
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D B G B C R 0 _ E L 1 )
adr x26 , 1 f
add x26 , x26 , x24 , l s l #2
br x26
1 :
ldr x20 , [ x3 , #( 15 * 8 ) ]
ldr x19 , [ x3 , #( 14 * 8 ) ]
ldr x18 , [ x3 , #( 13 * 8 ) ]
ldr x17 , [ x3 , #( 12 * 8 ) ]
ldr x16 , [ x3 , #( 11 * 8 ) ]
ldr x15 , [ x3 , #( 10 * 8 ) ]
ldr x14 , [ x3 , #( 9 * 8 ) ]
ldr x13 , [ x3 , #( 8 * 8 ) ]
ldr x12 , [ x3 , #( 7 * 8 ) ]
ldr x11 , [ x3 , #( 6 * 8 ) ]
ldr x10 , [ x3 , #( 5 * 8 ) ]
ldr x9 , [ x3 , #( 4 * 8 ) ]
ldr x8 , [ x3 , #( 3 * 8 ) ]
ldr x7 , [ x3 , #( 2 * 8 ) ]
ldr x6 , [ x3 , #( 1 * 8 ) ]
ldr x5 , [ x3 , #( 0 * 8 ) ]
adr x26 , 1 f
add x26 , x26 , x24 , l s l #2
br x26
1 :
msr d b g b c r15 _ e l 1 , x20
msr d b g b c r14 _ e l 1 , x19
msr d b g b c r13 _ e l 1 , x18
msr d b g b c r12 _ e l 1 , x17
msr d b g b c r11 _ e l 1 , x16
msr d b g b c r10 _ e l 1 , x15
msr d b g b c r9 _ e l 1 , x14
msr d b g b c r8 _ e l 1 , x13
msr d b g b c r7 _ e l 1 , x12
msr d b g b c r6 _ e l 1 , x11
msr d b g b c r5 _ e l 1 , x10
msr d b g b c r4 _ e l 1 , x9
msr d b g b c r3 _ e l 1 , x8
msr d b g b c r2 _ e l 1 , x7
msr d b g b c r1 _ e l 1 , x6
msr d b g b c r0 _ e l 1 , x5
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D B G B V R 0 _ E L 1 )
adr x26 , 1 f
add x26 , x26 , x24 , l s l #2
br x26
1 :
ldr x20 , [ x3 , #( 15 * 8 ) ]
ldr x19 , [ x3 , #( 14 * 8 ) ]
ldr x18 , [ x3 , #( 13 * 8 ) ]
ldr x17 , [ x3 , #( 12 * 8 ) ]
ldr x16 , [ x3 , #( 11 * 8 ) ]
ldr x15 , [ x3 , #( 10 * 8 ) ]
ldr x14 , [ x3 , #( 9 * 8 ) ]
ldr x13 , [ x3 , #( 8 * 8 ) ]
ldr x12 , [ x3 , #( 7 * 8 ) ]
ldr x11 , [ x3 , #( 6 * 8 ) ]
ldr x10 , [ x3 , #( 5 * 8 ) ]
ldr x9 , [ x3 , #( 4 * 8 ) ]
ldr x8 , [ x3 , #( 3 * 8 ) ]
ldr x7 , [ x3 , #( 2 * 8 ) ]
ldr x6 , [ x3 , #( 1 * 8 ) ]
ldr x5 , [ x3 , #( 0 * 8 ) ]
adr x26 , 1 f
add x26 , x26 , x24 , l s l #2
br x26
1 :
msr d b g b v r15 _ e l 1 , x20
msr d b g b v r14 _ e l 1 , x19
msr d b g b v r13 _ e l 1 , x18
msr d b g b v r12 _ e l 1 , x17
msr d b g b v r11 _ e l 1 , x16
msr d b g b v r10 _ e l 1 , x15
msr d b g b v r9 _ e l 1 , x14
msr d b g b v r8 _ e l 1 , x13
msr d b g b v r7 _ e l 1 , x12
msr d b g b v r6 _ e l 1 , x11
msr d b g b v r5 _ e l 1 , x10
msr d b g b v r4 _ e l 1 , x9
msr d b g b v r3 _ e l 1 , x8
msr d b g b v r2 _ e l 1 , x7
msr d b g b v r1 _ e l 1 , x6
msr d b g b v r0 _ e l 1 , x5
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D B G W C R 0 _ E L 1 )
adr x26 , 1 f
add x26 , x26 , x25 , l s l #2
br x26
1 :
ldr x20 , [ x3 , #( 15 * 8 ) ]
ldr x19 , [ x3 , #( 14 * 8 ) ]
ldr x18 , [ x3 , #( 13 * 8 ) ]
ldr x17 , [ x3 , #( 12 * 8 ) ]
ldr x16 , [ x3 , #( 11 * 8 ) ]
ldr x15 , [ x3 , #( 10 * 8 ) ]
ldr x14 , [ x3 , #( 9 * 8 ) ]
ldr x13 , [ x3 , #( 8 * 8 ) ]
ldr x12 , [ x3 , #( 7 * 8 ) ]
ldr x11 , [ x3 , #( 6 * 8 ) ]
ldr x10 , [ x3 , #( 5 * 8 ) ]
ldr x9 , [ x3 , #( 4 * 8 ) ]
ldr x8 , [ x3 , #( 3 * 8 ) ]
ldr x7 , [ x3 , #( 2 * 8 ) ]
ldr x6 , [ x3 , #( 1 * 8 ) ]
ldr x5 , [ x3 , #( 0 * 8 ) ]
adr x26 , 1 f
add x26 , x26 , x25 , l s l #2
br x26
1 :
msr d b g w c r15 _ e l 1 , x20
msr d b g w c r14 _ e l 1 , x19
msr d b g w c r13 _ e l 1 , x18
msr d b g w c r12 _ e l 1 , x17
msr d b g w c r11 _ e l 1 , x16
msr d b g w c r10 _ e l 1 , x15
msr d b g w c r9 _ e l 1 , x14
msr d b g w c r8 _ e l 1 , x13
msr d b g w c r7 _ e l 1 , x12
msr d b g w c r6 _ e l 1 , x11
msr d b g w c r5 _ e l 1 , x10
msr d b g w c r4 _ e l 1 , x9
msr d b g w c r3 _ e l 1 , x8
msr d b g w c r2 _ e l 1 , x7
msr d b g w c r1 _ e l 1 , x6
msr d b g w c r0 _ e l 1 , x5
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D B G W V R 0 _ E L 1 )
adr x26 , 1 f
add x26 , x26 , x25 , l s l #2
br x26
1 :
ldr x20 , [ x3 , #( 15 * 8 ) ]
ldr x19 , [ x3 , #( 14 * 8 ) ]
ldr x18 , [ x3 , #( 13 * 8 ) ]
ldr x17 , [ x3 , #( 12 * 8 ) ]
ldr x16 , [ x3 , #( 11 * 8 ) ]
ldr x15 , [ x3 , #( 10 * 8 ) ]
ldr x14 , [ x3 , #( 9 * 8 ) ]
ldr x13 , [ x3 , #( 8 * 8 ) ]
ldr x12 , [ x3 , #( 7 * 8 ) ]
ldr x11 , [ x3 , #( 6 * 8 ) ]
ldr x10 , [ x3 , #( 5 * 8 ) ]
ldr x9 , [ x3 , #( 4 * 8 ) ]
ldr x8 , [ x3 , #( 3 * 8 ) ]
ldr x7 , [ x3 , #( 2 * 8 ) ]
ldr x6 , [ x3 , #( 1 * 8 ) ]
ldr x5 , [ x3 , #( 0 * 8 ) ]
adr x26 , 1 f
add x26 , x26 , x25 , l s l #2
br x26
1 :
msr d b g w v r15 _ e l 1 , x20
msr d b g w v r14 _ e l 1 , x19
msr d b g w v r13 _ e l 1 , x18
msr d b g w v r12 _ e l 1 , x17
msr d b g w v r11 _ e l 1 , x16
msr d b g w v r10 _ e l 1 , x15
msr d b g w v r9 _ e l 1 , x14
msr d b g w v r8 _ e l 1 , x13
msr d b g w v r7 _ e l 1 , x12
msr d b g w v r6 _ e l 1 , x11
msr d b g w v r5 _ e l 1 , x10
msr d b g w v r4 _ e l 1 , x9
msr d b g w v r3 _ e l 1 , x8
msr d b g w v r2 _ e l 1 , x7
msr d b g w v r1 _ e l 1 , x6
msr d b g w v r0 _ e l 1 , x5
ldr x21 , [ x2 , #C P U _ S Y S R E G _ O F F S E T ( M D C C I N T _ E L 1 ) ]
msr m d c c i n t _ e l 1 , x21
2012-12-10 20:40:18 +04:00
.endm
2013-02-07 14:52:10 +04:00
.macro skip_32bit_state tmp, t a r g e t
/ / Skip 3 2 b i t s t a t e i f n o t n e e d e d
mrs \ t m p , h c r _ e l 2
tbnz \ t m p , #H C R _ R W _ S H I F T , \ t a r g e t
.endm
.macro skip_tee_state tmp, t a r g e t
/ / Skip T h u m b E E s t a t e i f n o t n e e d e d
mrs \ t m p , i d _ p f r0 _ e l 1
tbz \ t m p , #12 , \ t a r g e t
.endm
2014-05-07 16:44:49 +04:00
.macro skip_debug_state tmp, t a r g e t
ldr \ t m p , [ x0 , #V C P U _ D E B U G _ F L A G S ]
tbz \ t m p , #K V M _ A R M 64 _ D E B U G _ D I R T Y _ S H I F T , \ t a r g e t
.endm
.macro compute_debug_state target
/ / Compute d e b u g s t a t e : I f a n y o f K D E , M D E o r K V M _ A R M 6 4 _ D E B U G _ D I R T Y
/ / is s e t , w e d o a f u l l s a v e / r e s t o r e c y c l e a n d d i s a b l e t r a p p i n g .
add x25 , x0 , #V C P U _ C O N T E X T
/ / Check t h e s t a t e o f M D S C R _ E L 1
ldr x25 , [ x25 , #C P U _ S Y S R E G _ O F F S E T ( M D S C R _ E L 1 ) ]
and x26 , x25 , #D B G _ M D S C R _ K D E
and x25 , x25 , #D B G _ M D S C R _ M D E
adds x z r , x25 , x26
b. e q 9 9 9 8 f / / N o t h i n g t o s e e t h e r e
/ / If a n y i n t e r e s t i n g b i t s w a s s e t , w e m u s t s e t t h e f l a g
mov x26 , #K V M _ A R M 64 _ D E B U G _ D I R T Y
str x26 , [ x0 , #V C P U _ D E B U G _ F L A G S ]
b 9 9 9 9 f / / D o n ' t s k i p r e s t o r e
9998 :
/ / Otherwise l o a d t h e f l a g s f r o m m e m o r y i n c a s e w e r e c e n t l y
/ / trapped
skip_ d e b u g _ s t a t e x25 , \ t a r g e t
9999 :
.endm
2013-02-07 14:52:10 +04:00
.macro save_guest_32bit_state
skip_ 3 2 b i t _ s t a t e x3 , 1 f
add x3 , x2 , #C P U _ S P S R _ O F F S E T ( K V M _ S P S R _ A B T )
mrs x4 , s p s r _ a b t
mrs x5 , s p s r _ u n d
mrs x6 , s p s r _ i r q
mrs x7 , s p s r _ f i q
stp x4 , x5 , [ x3 ]
stp x6 , x7 , [ x3 , #16 ]
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D A C R 32 _ E L 2 )
mrs x4 , d a c r32 _ e l 2
mrs x5 , i f s r32 _ e l 2
mrs x6 , f p e x c32 _ e l 2
stp x4 , x5 , [ x3 ]
2014-05-07 16:44:49 +04:00
str x6 , [ x3 , #16 ]
2013-02-07 14:52:10 +04:00
2014-05-07 16:44:49 +04:00
skip_ d e b u g _ s t a t e x8 , 2 f
mrs x7 , d b g v c r32 _ e l 2
str x7 , [ x3 , #24 ]
2 :
2013-02-07 14:52:10 +04:00
skip_ t e e _ s t a t e x8 , 1 f
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( T E E C R 32 _ E L 1 )
mrs x4 , t e e c r32 _ e l 1
mrs x5 , t e e h b r32 _ e l 1
stp x4 , x5 , [ x3 ]
1 :
.endm
.macro restore_guest_32bit_state
skip_ 3 2 b i t _ s t a t e x3 , 1 f
add x3 , x2 , #C P U _ S P S R _ O F F S E T ( K V M _ S P S R _ A B T )
ldp x4 , x5 , [ x3 ]
ldp x6 , x7 , [ x3 , #16 ]
msr s p s r _ a b t , x4
msr s p s r _ u n d , x5
msr s p s r _ i r q , x6
msr s p s r _ f i q , x7
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( D A C R 32 _ E L 2 )
ldp x4 , x5 , [ x3 ]
2014-05-07 16:44:49 +04:00
ldr x6 , [ x3 , #16 ]
2013-02-07 14:52:10 +04:00
msr d a c r32 _ e l 2 , x4
msr i f s r32 _ e l 2 , x5
msr f p e x c32 _ e l 2 , x6
2014-05-07 16:44:49 +04:00
skip_ d e b u g _ s t a t e x8 , 2 f
ldr x7 , [ x3 , #24 ]
msr d b g v c r32 _ e l 2 , x7
2 :
2013-02-07 14:52:10 +04:00
skip_ t e e _ s t a t e x8 , 1 f
add x3 , x2 , #C P U _ S Y S R E G _ O F F S E T ( T E E C R 32 _ E L 1 )
ldp x4 , x5 , [ x3 ]
msr t e e c r32 _ e l 1 , x4
msr t e e h b r32 _ e l 1 , x5
1 :
.endm
2012-12-10 20:40:18 +04:00
.macro activate_traps
2013-08-09 21:19:11 +04:00
ldr x2 , [ x0 , #V C P U _ H C R _ E L 2 ]
msr h c r _ e l 2 , x2
2014-11-07 17:12:34 +03:00
mov x2 , #C P T R _ E L 2 _ T T A
2012-12-10 20:40:18 +04:00
msr c p t r _ e l 2 , x2
2014-11-07 17:12:34 +03:00
mov x2 , #( 1 < < 1 5 ) / / T r a p C P 1 5 C r =15
2012-12-10 20:40:18 +04:00
msr h s t r _ e l 2 , x2
mrs x2 , m d c r _ e l 2
and x2 , x2 , #M D C R _ E L 2 _ H P M N _ M A S K
orr x2 , x2 , #( M D C R _ E L 2 _ T P M | M D C R _ E L 2 _ T P M C R )
2014-04-24 13:32:03 +04:00
orr x2 , x2 , #( M D C R _ E L 2 _ T D R A | M D C R _ E L 2 _ T D O S A )
/ / Check f o r K V M _ A R M 6 4 _ D E B U G _ D I R T Y , a n d s e t d e b u g t o t r a p
/ / if n o t d i r t y .
ldr x3 , [ x0 , #V C P U _ D E B U G _ F L A G S ]
tbnz x3 , #K V M _ A R M 64 _ D E B U G _ D I R T Y _ S H I F T , 1 f
orr x2 , x2 , #M D C R _ E L 2 _ T D A
1 :
2012-12-10 20:40:18 +04:00
msr m d c r _ e l 2 , x2
.endm
.macro deactivate_traps
mov x2 , #H C R _ R W
msr h c r _ e l 2 , x2
msr c p t r _ e l 2 , x z r
msr h s t r _ e l 2 , x z r
mrs x2 , m d c r _ e l 2
and x2 , x2 , #M D C R _ E L 2 _ H P M N _ M A S K
msr m d c r _ e l 2 , x2
.endm
.macro activate_vm
ldr x1 , [ x0 , #V C P U _ K V M ]
kern_ h y p _ v a x1
ldr x2 , [ x1 , #K V M _ V T T B R ]
msr v t t b r _ e l 2 , x2
.endm
.macro deactivate_vm
msr v t t b r _ e l 2 , x z r
.endm
2012-12-07 21:54:54 +04:00
/ *
2013-06-21 14:57:56 +04:00
* Call i n t o t h e v g i c b a c k e n d f o r s t a t e s a v i n g
2012-12-07 21:54:54 +04:00
* /
.macro save_vgic_state
2013-06-21 14:57:56 +04:00
adr x24 , _ _ v g i c _ s r _ v e c t o r s
ldr x24 , [ x24 , V G I C _ S A V E _ F N ]
kern_ h y p _ v a x24
blr x24
2013-08-09 21:19:11 +04:00
mrs x24 , h c r _ e l 2
mov x25 , #H C R _ I N T _ O V E R R I D E
neg x25 , x25
and x24 , x24 , x25
msr h c r _ e l 2 , x24
2012-12-07 21:54:54 +04:00
.endm
/ *
2013-06-21 14:57:56 +04:00
* Call i n t o t h e v g i c b a c k e n d f o r s t a t e r e s t o r i n g
2012-12-07 21:54:54 +04:00
* /
.macro restore_vgic_state
2013-08-09 21:19:11 +04:00
mrs x24 , h c r _ e l 2
ldr x25 , [ x0 , #V C P U _ I R Q _ L I N E S ]
orr x24 , x24 , #H C R _ I N T _ O V E R R I D E
orr x24 , x24 , x25
msr h c r _ e l 2 , x24
2013-06-21 14:57:56 +04:00
adr x24 , _ _ v g i c _ s r _ v e c t o r s
ldr x24 , [ x24 , #V G I C _ R E S T O R E _ F N ]
kern_ h y p _ v a x24
blr x24
2012-12-07 21:54:54 +04:00
.endm
2012-12-07 21:52:03 +04:00
.macro save_timer_state
/ / x0 : vcpu p o i n t e r
ldr x2 , [ x0 , #V C P U _ K V M ]
kern_ h y p _ v a x2
ldr w3 , [ x2 , #K V M _ T I M E R _ E N A B L E D ]
cbz w3 , 1 f
mrs x3 , c n t v _ c t l _ e l 0
and x3 , x3 , #3
str w3 , [ x0 , #V C P U _ T I M E R _ C N T V _ C T L ]
bic x3 , x3 , #1 / / C l e a r E n a b l e
msr c n t v _ c t l _ e l 0 , x3
isb
mrs x3 , c n t v _ c v a l _ e l 0
str x3 , [ x0 , #V C P U _ T I M E R _ C N T V _ C V A L ]
1 :
/ / Allow p h y s i c a l t i m e r / c o u n t e r a c c e s s f o r t h e h o s t
mrs x2 , c n t h c t l _ e l 2
orr x2 , x2 , #3
msr c n t h c t l _ e l 2 , x2
/ / Clear c n t v o f f f o r t h e h o s t
msr c n t v o f f _ e l 2 , x z r
.endm
.macro restore_timer_state
/ / x0 : vcpu p o i n t e r
/ / Disallow p h y s i c a l t i m e r a c c e s s f o r t h e g u e s t
/ / Physical c o u n t e r a c c e s s i s a l l o w e d
mrs x2 , c n t h c t l _ e l 2
orr x2 , x2 , #1
bic x2 , x2 , #2
msr c n t h c t l _ e l 2 , x2
ldr x2 , [ x0 , #V C P U _ K V M ]
kern_ h y p _ v a x2
ldr w3 , [ x2 , #K V M _ T I M E R _ E N A B L E D ]
cbz w3 , 1 f
ldr x3 , [ x2 , #K V M _ T I M E R _ C N T V O F F ]
msr c n t v o f f _ e l 2 , x3
ldr x2 , [ x0 , #V C P U _ T I M E R _ C N T V _ C V A L ]
msr c n t v _ c v a l _ e l 0 , x2
isb
ldr w2 , [ x0 , #V C P U _ T I M E R _ C N T V _ C T L ]
and x2 , x2 , #3
msr c n t v _ c t l _ e l 0 , x2
1 :
.endm
2012-12-10 20:40:18 +04:00
__save_sysregs :
save_ s y s r e g s
ret
__restore_sysregs :
restore_ s y s r e g s
ret
2014-05-07 16:44:49 +04:00
__save_debug :
save_ d e b u g
ret
__restore_debug :
restore_ d e b u g
ret
2012-12-10 20:40:18 +04:00
__save_fpsimd :
save_ f p s i m d
ret
__restore_fpsimd :
restore_ f p s i m d
ret
/ *
* u6 4 _ _ k v m _ v c p u _ r u n ( s t r u c t k v m _ v c p u * v c p u ) ;
*
* This i s t h e w o r l d s w i t c h . T h e f i r s t h a l f o f t h e f u n c t i o n
* deals w i t h e n t e r i n g t h e g u e s t , a n d a n y t h i n g f r o m _ _ k v m _ v c p u _ r e t u r n
* to t h e e n d o f t h e f u n c t i o n d e a l s w i t h r e e n t e r i n g t h e h o s t .
* On t h e e n t e r p a t h , o n l y x0 ( v c p u p o i n t e r ) m u s t b e p r e s e r v e d u n t i l
* the l a s t m o m e n t . O n t h e e x i t p a t h , x0 ( v c p u p o i n t e r ) a n d x1 ( e x c e p t i o n
* code) m u s t b o t h b e p r e s e r v e d u n t i l t h e e p i l o g u e .
* In b o t h c a s e s , x2 p o i n t s t o t h e C P U c o n t e x t w e ' r e s a v i n g / r e s t o r i n g f r o m / t o .
* /
ENTRY( _ _ k v m _ v c p u _ r u n )
kern_ h y p _ v a x0
msr t p i d r _ e l 2 , x0 / / S a v e t h e v c p u r e g i s t e r
/ / Host c o n t e x t
ldr x2 , [ x0 , #V C P U _ H O S T _ C O N T E X T ]
kern_ h y p _ v a x2
save_ h o s t _ r e g s
bl _ _ s a v e _ f p s i m d
bl _ _ s a v e _ s y s r e g s
2014-05-07 16:44:49 +04:00
compute_ d e b u g _ s t a t e 1 f
bl _ _ s a v e _ d e b u g
1 :
2012-12-10 20:40:18 +04:00
activate_ t r a p s
activate_ v m
2012-12-07 21:54:54 +04:00
restore_ v g i c _ s t a t e
2012-12-07 21:52:03 +04:00
restore_ t i m e r _ s t a t e
2012-12-07 21:54:54 +04:00
2012-12-10 20:40:18 +04:00
/ / Guest c o n t e x t
add x2 , x0 , #V C P U _ C O N T E X T
bl _ _ r e s t o r e _ s y s r e g s
bl _ _ r e s t o r e _ f p s i m d
2014-05-07 16:44:49 +04:00
skip_ d e b u g _ s t a t e x3 , 1 f
bl _ _ r e s t o r e _ d e b u g
1 :
2013-02-07 14:52:10 +04:00
restore_ g u e s t _ 3 2 b i t _ s t a t e
2012-12-10 20:40:18 +04:00
restore_ g u e s t _ r e g s
/ / That' s i t , n o m o r e m e s s i n g a r o u n d .
eret
__kvm_vcpu_return :
/ / Assume x0 i s t h e v c p u p o i n t e r , x1 t h e r e t u r n c o d e
/ / Guest' s x0 - x3 a r e o n t h e s t a c k
/ / Guest c o n t e x t
add x2 , x0 , #V C P U _ C O N T E X T
save_ g u e s t _ r e g s
bl _ _ s a v e _ f p s i m d
bl _ _ s a v e _ s y s r e g s
2014-05-07 16:44:49 +04:00
skip_ d e b u g _ s t a t e x3 , 1 f
bl _ _ s a v e _ d e b u g
1 :
2013-02-07 14:52:10 +04:00
save_ g u e s t _ 3 2 b i t _ s t a t e
2012-12-10 20:40:18 +04:00
2012-12-07 21:52:03 +04:00
save_ t i m e r _ s t a t e
2012-12-07 21:54:54 +04:00
save_ v g i c _ s t a t e
2012-12-10 20:40:18 +04:00
deactivate_ t r a p s
deactivate_ v m
/ / Host c o n t e x t
ldr x2 , [ x0 , #V C P U _ H O S T _ C O N T E X T ]
kern_ h y p _ v a x2
bl _ _ r e s t o r e _ s y s r e g s
bl _ _ r e s t o r e _ f p s i m d
2014-05-07 16:44:49 +04:00
skip_ d e b u g _ s t a t e x3 , 1 f
/ / Clear t h e d i r t y f l a g f o r t h e n e x t r u n , a s a l l t h e s t a t e h a s
/ / already b e e n s a v e d . N o t e t h a t w e n u k e t h e w h o l e 6 4 b i t w o r d .
/ / If w e e v e r a d d m o r e f l a g s , w e ' l l h a v e t o b e m o r e c a r e f u l . . .
str x z r , [ x0 , #V C P U _ D E B U G _ F L A G S ]
bl _ _ r e s t o r e _ d e b u g
1 :
2012-12-10 20:40:18 +04:00
restore_ h o s t _ r e g s
mov x0 , x1
ret
END( _ _ k v m _ v c p u _ r u n )
/ / void _ _ k v m _ t l b _ f l u s h _ v m i d _ i p a ( s t r u c t k v m * k v m , p h y s _ a d d r _ t i p a ) ;
ENTRY( _ _ k v m _ t l b _ f l u s h _ v m i d _ i p a )
2013-06-11 21:05:25 +04:00
dsb i s h s t
2012-12-10 20:40:18 +04:00
kern_ h y p _ v a x0
ldr x2 , [ x0 , #K V M _ V T T B R ]
msr v t t b r _ e l 2 , x2
isb
/ *
* We c o u l d d o s o m u c h b e t t e r i f w e h a d t h e V A a s w e l l .
* Instead, w e i n v a l i d a t e S t a g e - 2 f o r t h i s I P A , a n d t h e
* whole o f S t a g e - 1 . W e e p . . .
* /
2015-01-11 16:10:10 +03:00
lsr x1 , x1 , #12
2012-12-10 20:40:18 +04:00
tlbi i p a s2 e 1 i s , x1
2014-05-02 19:24:14 +04:00
/ *
* We h a v e t o e n s u r e c o m p l e t i o n o f t h e i n v a l i d a t i o n a t S t a g e - 2 ,
* since a t a b l e w a l k o n a n o t h e r C P U c o u l d r e f i l l a T L B w i t h a
* complete ( S 1 + S 2 ) w a l k b a s e d o n t h e o l d S t a g e - 2 m a p p i n g i f
* the S t a g e - 1 i n v a l i d a t i o n h a p p e n e d f i r s t .
* /
dsb i s h
2012-12-10 20:40:18 +04:00
tlbi v m a l l e 1 i s
2014-05-02 19:24:14 +04:00
dsb i s h
2012-12-10 20:40:18 +04:00
isb
msr v t t b r _ e l 2 , x z r
ret
ENDPROC( _ _ k v m _ t l b _ f l u s h _ v m i d _ i p a )
ENTRY( _ _ k v m _ f l u s h _ v m _ c o n t e x t )
2013-06-11 21:05:25 +04:00
dsb i s h s t
2012-12-10 20:40:18 +04:00
tlbi a l l e 1 i s
ic i a l l u i s
2014-05-02 19:24:14 +04:00
dsb i s h
2012-12-10 20:40:18 +04:00
ret
ENDPROC( _ _ k v m _ f l u s h _ v m _ c o n t e x t )
2013-06-21 14:57:56 +04:00
/ / struct v g i c _ s r _ v e c t o r s _ _ v g i _ s r _ v e c t o r s ;
.align 3
ENTRY( _ _ v g i c _ s r _ v e c t o r s )
.skip VGIC_SR_VECTOR_SZ
ENDPROC( _ _ v g i c _ s r _ v e c t o r s )
2012-12-10 20:40:18 +04:00
__kvm_hyp_panic :
/ / Guess t h e c o n t e x t b y l o o k i n g a t V T T B R :
/ / If z e r o , t h e n w e ' r e a l r e a d y a h o s t .
/ / Otherwise r e s t o r e a m i n i m a l h o s t c o n t e x t b e f o r e p a n i c i n g .
mrs x0 , v t t b r _ e l 2
cbz x0 , 1 f
mrs x0 , t p i d r _ e l 2
deactivate_ t r a p s
deactivate_ v m
ldr x2 , [ x0 , #V C P U _ H O S T _ C O N T E X T ]
kern_ h y p _ v a x2
bl _ _ r e s t o r e _ s y s r e g s
1 : adr x0 , _ _ h y p _ p a n i c _ s t r
adr x1 , 2 f
ldp x2 , x3 , [ x1 ]
sub x0 , x0 , x2
add x0 , x0 , x3
mrs x1 , s p s r _ e l 2
mrs x2 , e l r _ e l 2
mrs x3 , e s r _ e l 2
mrs x4 , f a r _ e l 2
mrs x5 , h p f a r _ e l 2
mrs x6 , p a r _ e l 1
mrs x7 , t p i d r _ e l 2
mov l r , #( P S R _ F _ B I T | P S R _ I _ B I T | P S R _ A _ B I T | P S R _ D _ B I T | \
PSR_ M O D E _ E L 1 h )
msr s p s r _ e l 2 , l r
ldr l r , =panic
msr e l r _ e l 2 , l r
eret
.align 3
2 : .quad H Y P _ P A G E _ O F F S E T
.quad PAGE_OFFSET
ENDPROC( _ _ k v m _ h y p _ p a n i c )
__hyp_panic_str :
.ascii " HYP p a n i c : \ n P S : % 0 8 x P C : % p E S R : % p \ n F A R : % p H P F A R : % p P A R : % p \ n V C P U : % p \ n \ 0 "
.align 2
2014-02-26 22:47:36 +04:00
/ *
* u6 4 k v m _ c a l l _ h y p ( v o i d * h y p f n , . . . ) ;
*
* This i s n o t r e a l l y a v a r i a d i c f u n c t i o n i n t h e c l a s s i c C - w a y a n d c a r e m u s t
* be t a k e n w h e n c a l l i n g t h i s t o e n s u r e p a r a m e t e r s a r e p a s s e d i n r e g i s t e r s
* only, s i n c e t h e s t a c k w i l l c h a n g e b e t w e e n t h e c a l l e r a n d t h e c a l l e e .
*
* Call t h e f u n c t i o n w i t h t h e f i r s t a r g u m e n t c o n t a i n i n g a p o i n t e r t o t h e
* function y o u w i s h t o c a l l i n H y p m o d e , a n d s u b s e q u e n t a r g u m e n t s w i l l b e
* passed a s x0 , x1 , a n d x2 ( a m a x i m u m o f 3 a r g u m e n t s i n a d d i t i o n t o t h e
* function p o i n t e r c a n b e p a s s e d ) . T h e f u n c t i o n b e i n g c a l l e d m u s t b e m a p p e d
* in H y p m o d e ( s e e i n i t _ h y p _ m o d e i n a r c h / a r m / k v m / a r m . c ) . R e t u r n v a l u e s a r e
* passed i n r0 a n d r1 .
*
* A f u n c t i o n p o i n t e r w i t h a v a l u e o f 0 h a s a s p e c i a l m e a n i n g , a n d i s
* used t o i m p l e m e n t _ _ h y p _ g e t _ v e c t o r s i n t h e s a m e w a y a s i n
* arch/ a r m 6 4 / k e r n e l / h y p _ s t u b . S .
* /
2012-12-10 20:40:18 +04:00
ENTRY( k v m _ c a l l _ h y p )
hvc #0
ret
ENDPROC( k v m _ c a l l _ h y p )
.macro invalid_vector label, t a r g e t
.align 2
\ label :
b \ t a r g e t
ENDPROC( \ l a b e l )
.endm
/* None of these should ever happen */
invalid_ v e c t o r e l 2 t _ s y n c _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 2 t _ i r q _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 2 t _ f i q _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 2 t _ e r r o r _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 2 h _ s y n c _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 2 h _ i r q _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 2 h _ f i q _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 2 h _ e r r o r _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 1 _ s y n c _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 1 _ i r q _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 1 _ f i q _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
invalid_ v e c t o r e l 1 _ e r r o r _ i n v a l i d , _ _ k v m _ h y p _ p a n i c
el1_sync : / / Guest t r a p p e d i n t o E L 2
push x0 , x1
push x2 , x3
mrs x1 , e s r _ e l 2
lsr x2 , x1 , #E S R _ E L 2 _ E C _ S H I F T
cmp x2 , #E S R _ E L 2 _ E C _ H V C 6 4
b. n e e l 1 _ t r a p
mrs x3 , v t t b r _ e l 2 / / I f v t t b r i s v a l i d , t h e 6 4 b i t g u e s t
cbnz x3 , e l 1 _ t r a p / / c a l l e d H V C
/* Here, we're pretty sure the host called HVC. */
pop x2 , x3
pop x0 , x1
2014-02-26 22:47:36 +04:00
/* Check for __hyp_get_vectors */
cbnz x0 , 1 f
mrs x0 , v b a r _ e l 2
b 2 f
1 : push l r , x z r
2012-12-10 20:40:18 +04:00
/ *
* Compute t h e f u n c t i o n a d d r e s s i n E L 2 , a n d s h u f f l e t h e p a r a m e t e r s .
* /
kern_ h y p _ v a x0
mov l r , x0
mov x0 , x1
mov x1 , x2
mov x2 , x3
blr l r
pop l r , x z r
2014-02-26 22:47:36 +04:00
2 : eret
2012-12-10 20:40:18 +04:00
el1_trap :
/ *
* x1 : ESR
* x2 : ESR_ E C
* /
cmp x2 , #E S R _ E L 2 _ E C _ D A B T
mov x0 , #E S R _ E L 2 _ E C _ I A B T
ccmp x2 , x0 , #4 , n e
b. n e 1 f / / N o t a n a b o r t w e c a r e a b o u t
/* This is an abort. Check for permission fault */
and x2 , x1 , #E S R _ E L 2 _ F S C _ T Y P E
cmp x2 , #F S C _ P E R M
b. n e 1 f / / N o t a p e r m i s s i o n f a u l t
/ *
* Check f o r S t a g e - 1 p a g e t a b l e w a l k , w h i c h i s g u a r a n t e e d
* to g i v e a v a l i d H P F A R _ E L 2 .
* /
tbnz x1 , #7 , 1 f / / S 1 P T W i s s e t
2013-06-07 14:02:34 +04:00
/* Preserve PAR_EL1 */
mrs x3 , p a r _ e l 1
push x3 , x z r
2012-12-10 20:40:18 +04:00
/ *
* Permission f a u l t , H P F A R _ E L 2 i s i n v a l i d .
* Resolve t h e I P A t h e h a r d w a y u s i n g t h e g u e s t V A .
* Stage- 1 t r a n s l a t i o n a l r e a d y v a l i d a t e d t h e m e m o r y a c c e s s r i g h t s .
* As s u c h , w e c a n u s e t h e E L 1 t r a n s l a t i o n r e g i m e , a n d d o n ' t h a v e
* to d i s t i n g u i s h b e t w e e n E L 0 a n d E L 1 a c c e s s .
* /
mrs x2 , f a r _ e l 2
at s1 e 1 r , x2
isb
/* Read result */
mrs x3 , p a r _ e l 1
2013-06-07 14:02:34 +04:00
pop x0 , x z r / / R e s t o r e P A R _ E L 1 f r o m t h e s t a c k
msr p a r _ e l 1 , x0
2012-12-10 20:40:18 +04:00
tbnz x3 , #0 , 3 f / / B a i l o u t i f w e f a i l e d t h e t r a n s l a t i o n
ubfx x3 , x3 , #12 , #36 / / E x t r a c t I P A
lsl x3 , x3 , #4 / / a n d p r e s e n t i t l i k e H P F A R
b 2 f
1 : mrs x3 , h p f a r _ e l 2
mrs x2 , f a r _ e l 2
2 : mrs x0 , t p i d r _ e l 2
2014-06-12 20:30:09 +04:00
str w1 , [ x0 , #V C P U _ E S R _ E L 2 ]
2012-12-10 20:40:18 +04:00
str x2 , [ x0 , #V C P U _ F A R _ E L 2 ]
str x3 , [ x0 , #V C P U _ H P F A R _ E L 2 ]
mov x1 , #A R M _ E X C E P T I O N _ T R A P
b _ _ k v m _ v c p u _ r e t u r n
/ *
* Translation f a i l e d . J u s t r e t u r n t o t h e g u e s t a n d
* let i t f a u l t a g a i n . A n o t h e r C P U i s p r o b a b l y p l a y i n g
* behind o u r b a c k .
* /
3 : pop x2 , x3
pop x0 , x1
eret
el1_irq :
push x0 , x1
push x2 , x3
mrs x0 , t p i d r _ e l 2
mov x1 , #A R M _ E X C E P T I O N _ I R Q
b _ _ k v m _ v c p u _ r e t u r n
.ltorg
.align 11
ENTRY( _ _ k v m _ h y p _ v e c t o r )
ventry e l 2 t _ s y n c _ i n v a l i d / / S y n c h r o n o u s E L 2 t
ventry e l 2 t _ i r q _ i n v a l i d / / I R Q E L 2 t
ventry e l 2 t _ f i q _ i n v a l i d / / F I Q E L 2 t
ventry e l 2 t _ e r r o r _ i n v a l i d / / E r r o r E L 2 t
ventry e l 2 h _ s y n c _ i n v a l i d / / S y n c h r o n o u s E L 2 h
ventry e l 2 h _ i r q _ i n v a l i d / / I R Q E L 2 h
ventry e l 2 h _ f i q _ i n v a l i d / / F I Q E L 2 h
ventry e l 2 h _ e r r o r _ i n v a l i d / / E r r o r E L 2 h
ventry e l 1 _ s y n c / / S y n c h r o n o u s 6 4 - b i t E L 1
ventry e l 1 _ i r q / / I R Q 6 4 - b i t E L 1
ventry e l 1 _ f i q _ i n v a l i d / / F I Q 6 4 - b i t E L 1
ventry e l 1 _ e r r o r _ i n v a l i d / / E r r o r 6 4 - b i t E L 1
ventry e l 1 _ s y n c / / S y n c h r o n o u s 3 2 - b i t E L 1
ventry e l 1 _ i r q / / I R Q 3 2 - b i t E L 1
ventry e l 1 _ f i q _ i n v a l i d / / F I Q 3 2 - b i t E L 1
ventry e l 1 _ e r r o r _ i n v a l i d / / E r r o r 3 2 - b i t E L 1
ENDPROC( _ _ k v m _ h y p _ v e c t o r )
.popsection