2016-01-05 18:40:51 +00:00
/ *
* Copyright ( C ) 2 0 1 6 - 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 m - o f f s e t s . h >
# include < a s m / k v m _ a r m . h >
2016-09-06 14:02:12 +01:00
# include < a s m / k v m _ a s m . h >
2016-01-05 18:40:51 +00:00
.arch_extension virt
.text
.pushsection .hyp .text , " ax"
# define U S R _ R E G S _ O F F S E T ( C P U _ C T X T _ G P _ R E G S + G P _ R E G S _ U S R )
/* int __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host) */
ENTRY( _ _ g u e s t _ e n t e r )
@ Save host registers
add r1 , r1 , #( U S R _ R E G S _ O F F S E T + S _ R 4 )
stm r1 ! , { r4 - r12 }
str l r , [ r1 , #4 ] @ Skip SP_usr (already saved)
@ Restore guest registers
add r0 , r0 , #( V C P U _ G U E S T _ C T X T + U S R _ R E G S _ O F F S E T + S _ R 0 )
ldr l r , [ r0 , #S _ L R ]
ldm r0 , { r0 - r12 }
clrex
eret
ENDPROC( _ _ g u e s t _ e n t e r )
ENTRY( _ _ g u e s t _ e x i t )
/ *
* return c o n v e n t i o n :
* guest r0 , r1 , r2 s a v e d o n t h e s t a c k
* r0 : vcpu p o i n t e r
* r1 : exception c o d e
* /
add r2 , r0 , #( V C P U _ G U E S T _ C T X T + U S R _ R E G S _ O F F S E T + S _ R 3 )
stm r2 ! , { r3 - r12 }
str l r , [ r2 , #4 ]
add r2 , r0 , #( V C P U _ G U E S T _ C T X T + U S R _ R E G S _ O F F S E T + S _ R 0 )
pop { r3 , r4 , r5 } @ r0, r1, r2
stm r2 , { r3 - r5 }
ldr r0 , [ r0 , #V C P U _ H O S T _ C T X T ]
add r0 , r0 , #( U S R _ R E G S _ O F F S E T + S _ R 4 )
ldm r0 ! , { r4 - r12 }
ldr l r , [ r0 , #4 ]
mov r0 , r1
2016-09-06 14:02:12 +01:00
mrs r1 , S P S R
mrs r2 , E L R _ h y p
mrc p15 , 4 , r3 , c5 , c2 , 0 @ HSR
/ *
* Force l o a d s a n d s t o r e s t o c o m p l e t e b e f o r e u n m a s k i n g a b o r t s
* and f o r c i n g t h e d e l i v e r y o f t h e e x c e p t i o n . T h i s g i v e s u s a
* single i n s t r u c t i o n w i n d o w , w h i c h t h e h a n d l e r w i l l t r y t o
* match.
* /
dsb s y
cpsie a
.global abort_guest_exit_start
abort_guest_exit_start :
isb
.global abort_guest_exit_end
abort_guest_exit_end :
/ *
* If w e t o o k a n a b o r t , r0 [ 3 1 ] w i l l b e s e t , a n d c m p w i l l s e t
* the N b i t i n P S T A T E .
* /
cmp r0 , #0
msrmi S P S R _ c x s f , r1
msrmi E L R _ h y p , r2
mcrmi p15 , 4 , r3 , c5 , c2 , 0 @ HSR
2016-01-05 18:40:51 +00:00
bx l r
ENDPROC( _ _ g u e s t _ e x i t )
2016-01-06 13:53:51 +00:00
/ *
* If V F P v3 s u p p o r t i s n o t a v a i l a b l e , t h e n w e w i l l n o t s w i t c h t h e V F P
* registers; however cp10 and cp11 accesses will still trap and fallback
* to t h e r e g u l a r c o p r o c e s s o r e m u l a t i o n c o d e , w h i c h c u r r e n t l y w i l l
* inject a n u n d e f i n e d e x c e p t i o n t o t h e g u e s t .
* /
# ifdef C O N F I G _ V F P v3
ENTRY( _ _ v f p _ g u e s t _ r e s t o r e )
push { r3 , r4 , l r }
@ NEON/VFP used. Turn on VFP access.
mrc p15 , 4 , r1 , c1 , c1 , 2 @ HCPTR
bic r1 , r1 , #( H C P T R _ T C P ( 10 ) | H C P T R _ T C P ( 1 1 ) )
mcr p15 , 4 , r1 , c1 , c1 , 2 @ HCPTR
isb
@ Switch VFP/NEON hardware state to the guest's
mov r4 , r0
ldr r0 , [ r0 , #V C P U _ H O S T _ C T X T ]
add r0 , r0 , #C P U _ C T X T _ V F P
bl _ _ v f p _ s a v e _ s t a t e
add r0 , r4 , #( V C P U _ G U E S T _ C T X T + C P U _ C T X T _ V F P )
bl _ _ v f p _ r e s t o r e _ s t a t e
pop { r3 , r4 , l r }
pop { r0 , r1 , r2 }
clrex
eret
ENDPROC( _ _ v f p _ g u e s t _ r e s t o r e )
# endif
2016-01-05 18:40:51 +00:00
.popsection