Re: [RFC 08/55] KVM: arm64: Set virtual EL2 context depending on the guest exception level

2017-06-02 Thread Marc Zyngier
On 01/06/17 21:22, Bandan Das wrote:
> Jintack Lim  writes:
> 
>> From: Christoffer Dall 
>>
>> Set up virutal EL2 context to hardware if the guest exception level is
>> EL2.
>>
>> Signed-off-by: Christoffer Dall 
>> Signed-off-by: Jintack Lim 
>> ---
>>  arch/arm64/kvm/context.c | 32 ++--
>>  1 file changed, 26 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
>> index 320afc6..acb4b1e 100644
>> --- a/arch/arm64/kvm/context.c
>> +++ b/arch/arm64/kvm/context.c
>> @@ -25,10 +25,25 @@
>>  void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>>  {
>>  struct kvm_cpu_context *ctxt = >arch.ctxt;
>> +if (unlikely(vcpu_mode_el2(vcpu))) {
>> +ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
>>  
>> -ctxt->hw_pstate = *vcpu_cpsr(vcpu);
>> -ctxt->hw_sys_regs = ctxt->sys_regs;
>> -ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
>> +/*
>> + * We emulate virtual EL2 mode in hardware EL1 mode using the
>> + * same stack pointer mode as the guest expects.
>> + */
>> +if ((*vcpu_cpsr(vcpu) & PSR_MODE_MASK) == PSR_MODE_EL2h)
>> +ctxt->hw_pstate |= PSR_MODE_EL1h;
>> +else
>> +ctxt->hw_pstate |= PSR_MODE_EL1t;
>> +
> 
> I see vcpu_mode(el2) does
> return mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t;
> 
> I can't seem to find this, what's the difference between
> the modes: PSR_MODE_EL2h/EL2t ?

The difference is the stack pointer that is getting used. When the CPU
is at ELxh, it uses SPx at ELx. When at ELxt, it uses SP0 (the userspace
stack pointer). See the definition of SPSR_EL2 in the ARMv8 ARM.

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...


Re: [RFC 08/55] KVM: arm64: Set virtual EL2 context depending on the guest exception level

2017-06-02 Thread Marc Zyngier
On 01/06/17 21:22, Bandan Das wrote:
> Jintack Lim  writes:
> 
>> From: Christoffer Dall 
>>
>> Set up virutal EL2 context to hardware if the guest exception level is
>> EL2.
>>
>> Signed-off-by: Christoffer Dall 
>> Signed-off-by: Jintack Lim 
>> ---
>>  arch/arm64/kvm/context.c | 32 ++--
>>  1 file changed, 26 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
>> index 320afc6..acb4b1e 100644
>> --- a/arch/arm64/kvm/context.c
>> +++ b/arch/arm64/kvm/context.c
>> @@ -25,10 +25,25 @@
>>  void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>>  {
>>  struct kvm_cpu_context *ctxt = >arch.ctxt;
>> +if (unlikely(vcpu_mode_el2(vcpu))) {
>> +ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
>>  
>> -ctxt->hw_pstate = *vcpu_cpsr(vcpu);
>> -ctxt->hw_sys_regs = ctxt->sys_regs;
>> -ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
>> +/*
>> + * We emulate virtual EL2 mode in hardware EL1 mode using the
>> + * same stack pointer mode as the guest expects.
>> + */
>> +if ((*vcpu_cpsr(vcpu) & PSR_MODE_MASK) == PSR_MODE_EL2h)
>> +ctxt->hw_pstate |= PSR_MODE_EL1h;
>> +else
>> +ctxt->hw_pstate |= PSR_MODE_EL1t;
>> +
> 
> I see vcpu_mode(el2) does
> return mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t;
> 
> I can't seem to find this, what's the difference between
> the modes: PSR_MODE_EL2h/EL2t ?

The difference is the stack pointer that is getting used. When the CPU
is at ELxh, it uses SPx at ELx. When at ELxt, it uses SP0 (the userspace
stack pointer). See the definition of SPSR_EL2 in the ARMv8 ARM.

Thanks,

M.
-- 
Jazz is not dead. It just smells funny...


Re: [RFC 08/55] KVM: arm64: Set virtual EL2 context depending on the guest exception level

2017-06-01 Thread Bandan Das
Jintack Lim  writes:

> From: Christoffer Dall 
>
> Set up virutal EL2 context to hardware if the guest exception level is
> EL2.
>
> Signed-off-by: Christoffer Dall 
> Signed-off-by: Jintack Lim 
> ---
>  arch/arm64/kvm/context.c | 32 ++--
>  1 file changed, 26 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
> index 320afc6..acb4b1e 100644
> --- a/arch/arm64/kvm/context.c
> +++ b/arch/arm64/kvm/context.c
> @@ -25,10 +25,25 @@
>  void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *ctxt = >arch.ctxt;
> + if (unlikely(vcpu_mode_el2(vcpu))) {
> + ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
>  
> - ctxt->hw_pstate = *vcpu_cpsr(vcpu);
> - ctxt->hw_sys_regs = ctxt->sys_regs;
> - ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
> + /*
> +  * We emulate virtual EL2 mode in hardware EL1 mode using the
> +  * same stack pointer mode as the guest expects.
> +  */
> + if ((*vcpu_cpsr(vcpu) & PSR_MODE_MASK) == PSR_MODE_EL2h)
> + ctxt->hw_pstate |= PSR_MODE_EL1h;
> + else
> + ctxt->hw_pstate |= PSR_MODE_EL1t;
> +

I see vcpu_mode(el2) does
return mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t;

I can't seem to find this, what's the difference between
the modes: PSR_MODE_EL2h/EL2t ?

Bandan

> + ctxt->hw_sys_regs = ctxt->shadow_sys_regs;
> + ctxt->hw_sp_el1 = ctxt->el2_regs[SP_EL2];
> + } else {
> + ctxt->hw_pstate = *vcpu_cpsr(vcpu);
> + ctxt->hw_sys_regs = ctxt->sys_regs;
> + ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
> + }
>  }
>  
>  /**
> @@ -38,9 +53,14 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>  void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *ctxt = >arch.ctxt;
> -
> - *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
> - ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
> + if (unlikely(vcpu_mode_el2(vcpu))) {
> + *vcpu_cpsr(vcpu) &= PSR_MODE_MASK;
> + *vcpu_cpsr(vcpu) |= ctxt->hw_pstate & ~PSR_MODE_MASK;
> + ctxt->el2_regs[SP_EL2] = ctxt->hw_sp_el1;
> + } else {
> + *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
> + ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
> + }
>  }
>  
>  void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt)


Re: [RFC 08/55] KVM: arm64: Set virtual EL2 context depending on the guest exception level

2017-06-01 Thread Bandan Das
Jintack Lim  writes:

> From: Christoffer Dall 
>
> Set up virutal EL2 context to hardware if the guest exception level is
> EL2.
>
> Signed-off-by: Christoffer Dall 
> Signed-off-by: Jintack Lim 
> ---
>  arch/arm64/kvm/context.c | 32 ++--
>  1 file changed, 26 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
> index 320afc6..acb4b1e 100644
> --- a/arch/arm64/kvm/context.c
> +++ b/arch/arm64/kvm/context.c
> @@ -25,10 +25,25 @@
>  void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *ctxt = >arch.ctxt;
> + if (unlikely(vcpu_mode_el2(vcpu))) {
> + ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
>  
> - ctxt->hw_pstate = *vcpu_cpsr(vcpu);
> - ctxt->hw_sys_regs = ctxt->sys_regs;
> - ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
> + /*
> +  * We emulate virtual EL2 mode in hardware EL1 mode using the
> +  * same stack pointer mode as the guest expects.
> +  */
> + if ((*vcpu_cpsr(vcpu) & PSR_MODE_MASK) == PSR_MODE_EL2h)
> + ctxt->hw_pstate |= PSR_MODE_EL1h;
> + else
> + ctxt->hw_pstate |= PSR_MODE_EL1t;
> +

I see vcpu_mode(el2) does
return mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t;

I can't seem to find this, what's the difference between
the modes: PSR_MODE_EL2h/EL2t ?

Bandan

> + ctxt->hw_sys_regs = ctxt->shadow_sys_regs;
> + ctxt->hw_sp_el1 = ctxt->el2_regs[SP_EL2];
> + } else {
> + ctxt->hw_pstate = *vcpu_cpsr(vcpu);
> + ctxt->hw_sys_regs = ctxt->sys_regs;
> + ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
> + }
>  }
>  
>  /**
> @@ -38,9 +53,14 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>  void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *ctxt = >arch.ctxt;
> -
> - *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
> - ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
> + if (unlikely(vcpu_mode_el2(vcpu))) {
> + *vcpu_cpsr(vcpu) &= PSR_MODE_MASK;
> + *vcpu_cpsr(vcpu) |= ctxt->hw_pstate & ~PSR_MODE_MASK;
> + ctxt->el2_regs[SP_EL2] = ctxt->hw_sp_el1;
> + } else {
> + *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
> + ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
> + }
>  }
>  
>  void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt)


Re: [RFC 08/55] KVM: arm64: Set virtual EL2 context depending on the guest exception level

2017-02-22 Thread Christoffer Dall
On Mon, Jan 09, 2017 at 01:24:04AM -0500, Jintack Lim wrote:
> From: Christoffer Dall 
> 
> Set up virutal EL2 context to hardware if the guest exception level is
> EL2.
> 
> Signed-off-by: Christoffer Dall 
> Signed-off-by: Jintack Lim 
> ---
>  arch/arm64/kvm/context.c | 32 ++--
>  1 file changed, 26 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
> index 320afc6..acb4b1e 100644
> --- a/arch/arm64/kvm/context.c
> +++ b/arch/arm64/kvm/context.c
> @@ -25,10 +25,25 @@
>  void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *ctxt = >arch.ctxt;
> + if (unlikely(vcpu_mode_el2(vcpu))) {
> + ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
>  
> - ctxt->hw_pstate = *vcpu_cpsr(vcpu);
> - ctxt->hw_sys_regs = ctxt->sys_regs;
> - ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
> + /*
> +  * We emulate virtual EL2 mode in hardware EL1 mode using the
> +  * same stack pointer mode as the guest expects.
> +  */

I think this comment should either be deleted or explain why this works
as opposed to stating the obvious.  How about:

/*
 * We can emulate the guest's configuration of which
 * stack pointer to use when executing in virtual EL2 by
 * using the equivalent feature in EL1 to point to
 * either the EL1 or EL0 stack pointer.
 */

> + if ((*vcpu_cpsr(vcpu) & PSR_MODE_MASK) == PSR_MODE_EL2h)
> + ctxt->hw_pstate |= PSR_MODE_EL1h;
> + else
> + ctxt->hw_pstate |= PSR_MODE_EL1t;
> +
> + ctxt->hw_sys_regs = ctxt->shadow_sys_regs;
> + ctxt->hw_sp_el1 = ctxt->el2_regs[SP_EL2];
> + } else {
> + ctxt->hw_pstate = *vcpu_cpsr(vcpu);
> + ctxt->hw_sys_regs = ctxt->sys_regs;
> + ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
> + }
>  }
>  
>  /**
> @@ -38,9 +53,14 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>  void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *ctxt = >arch.ctxt;
> -
> - *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
> - ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
> + if (unlikely(vcpu_mode_el2(vcpu))) {
> + *vcpu_cpsr(vcpu) &= PSR_MODE_MASK;
> + *vcpu_cpsr(vcpu) |= ctxt->hw_pstate & ~PSR_MODE_MASK;
> + ctxt->el2_regs[SP_EL2] = ctxt->hw_sp_el1;
> + } else {
> + *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
> + ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
> + }
>  }
>  
>  void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt)
> -- 
> 1.9.1
> 
> 


Re: [RFC 08/55] KVM: arm64: Set virtual EL2 context depending on the guest exception level

2017-02-22 Thread Christoffer Dall
On Mon, Jan 09, 2017 at 01:24:04AM -0500, Jintack Lim wrote:
> From: Christoffer Dall 
> 
> Set up virutal EL2 context to hardware if the guest exception level is
> EL2.
> 
> Signed-off-by: Christoffer Dall 
> Signed-off-by: Jintack Lim 
> ---
>  arch/arm64/kvm/context.c | 32 ++--
>  1 file changed, 26 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
> index 320afc6..acb4b1e 100644
> --- a/arch/arm64/kvm/context.c
> +++ b/arch/arm64/kvm/context.c
> @@ -25,10 +25,25 @@
>  void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *ctxt = >arch.ctxt;
> + if (unlikely(vcpu_mode_el2(vcpu))) {
> + ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
>  
> - ctxt->hw_pstate = *vcpu_cpsr(vcpu);
> - ctxt->hw_sys_regs = ctxt->sys_regs;
> - ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
> + /*
> +  * We emulate virtual EL2 mode in hardware EL1 mode using the
> +  * same stack pointer mode as the guest expects.
> +  */

I think this comment should either be deleted or explain why this works
as opposed to stating the obvious.  How about:

/*
 * We can emulate the guest's configuration of which
 * stack pointer to use when executing in virtual EL2 by
 * using the equivalent feature in EL1 to point to
 * either the EL1 or EL0 stack pointer.
 */

> + if ((*vcpu_cpsr(vcpu) & PSR_MODE_MASK) == PSR_MODE_EL2h)
> + ctxt->hw_pstate |= PSR_MODE_EL1h;
> + else
> + ctxt->hw_pstate |= PSR_MODE_EL1t;
> +
> + ctxt->hw_sys_regs = ctxt->shadow_sys_regs;
> + ctxt->hw_sp_el1 = ctxt->el2_regs[SP_EL2];
> + } else {
> + ctxt->hw_pstate = *vcpu_cpsr(vcpu);
> + ctxt->hw_sys_regs = ctxt->sys_regs;
> + ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
> + }
>  }
>  
>  /**
> @@ -38,9 +53,14 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
>  void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu)
>  {
>   struct kvm_cpu_context *ctxt = >arch.ctxt;
> -
> - *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
> - ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
> + if (unlikely(vcpu_mode_el2(vcpu))) {
> + *vcpu_cpsr(vcpu) &= PSR_MODE_MASK;
> + *vcpu_cpsr(vcpu) |= ctxt->hw_pstate & ~PSR_MODE_MASK;
> + ctxt->el2_regs[SP_EL2] = ctxt->hw_sp_el1;
> + } else {
> + *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
> + ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
> + }
>  }
>  
>  void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt)
> -- 
> 1.9.1
> 
> 


[RFC 08/55] KVM: arm64: Set virtual EL2 context depending on the guest exception level

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Set up virutal EL2 context to hardware if the guest exception level is
EL2.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/context.c | 32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
index 320afc6..acb4b1e 100644
--- a/arch/arm64/kvm/context.c
+++ b/arch/arm64/kvm/context.c
@@ -25,10 +25,25 @@
 void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
 {
struct kvm_cpu_context *ctxt = >arch.ctxt;
+   if (unlikely(vcpu_mode_el2(vcpu))) {
+   ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
 
-   ctxt->hw_pstate = *vcpu_cpsr(vcpu);
-   ctxt->hw_sys_regs = ctxt->sys_regs;
-   ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
+   /*
+* We emulate virtual EL2 mode in hardware EL1 mode using the
+* same stack pointer mode as the guest expects.
+*/
+   if ((*vcpu_cpsr(vcpu) & PSR_MODE_MASK) == PSR_MODE_EL2h)
+   ctxt->hw_pstate |= PSR_MODE_EL1h;
+   else
+   ctxt->hw_pstate |= PSR_MODE_EL1t;
+
+   ctxt->hw_sys_regs = ctxt->shadow_sys_regs;
+   ctxt->hw_sp_el1 = ctxt->el2_regs[SP_EL2];
+   } else {
+   ctxt->hw_pstate = *vcpu_cpsr(vcpu);
+   ctxt->hw_sys_regs = ctxt->sys_regs;
+   ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
+   }
 }
 
 /**
@@ -38,9 +53,14 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
 void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu)
 {
struct kvm_cpu_context *ctxt = >arch.ctxt;
-
-   *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
-   ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
+   if (unlikely(vcpu_mode_el2(vcpu))) {
+   *vcpu_cpsr(vcpu) &= PSR_MODE_MASK;
+   *vcpu_cpsr(vcpu) |= ctxt->hw_pstate & ~PSR_MODE_MASK;
+   ctxt->el2_regs[SP_EL2] = ctxt->hw_sp_el1;
+   } else {
+   *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
+   ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
+   }
 }
 
 void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt)
-- 
1.9.1




[RFC 08/55] KVM: arm64: Set virtual EL2 context depending on the guest exception level

2017-01-08 Thread Jintack Lim
From: Christoffer Dall 

Set up virutal EL2 context to hardware if the guest exception level is
EL2.

Signed-off-by: Christoffer Dall 
Signed-off-by: Jintack Lim 
---
 arch/arm64/kvm/context.c | 32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/context.c b/arch/arm64/kvm/context.c
index 320afc6..acb4b1e 100644
--- a/arch/arm64/kvm/context.c
+++ b/arch/arm64/kvm/context.c
@@ -25,10 +25,25 @@
 void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
 {
struct kvm_cpu_context *ctxt = >arch.ctxt;
+   if (unlikely(vcpu_mode_el2(vcpu))) {
+   ctxt->hw_pstate = *vcpu_cpsr(vcpu) & ~PSR_MODE_MASK;
 
-   ctxt->hw_pstate = *vcpu_cpsr(vcpu);
-   ctxt->hw_sys_regs = ctxt->sys_regs;
-   ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
+   /*
+* We emulate virtual EL2 mode in hardware EL1 mode using the
+* same stack pointer mode as the guest expects.
+*/
+   if ((*vcpu_cpsr(vcpu) & PSR_MODE_MASK) == PSR_MODE_EL2h)
+   ctxt->hw_pstate |= PSR_MODE_EL1h;
+   else
+   ctxt->hw_pstate |= PSR_MODE_EL1t;
+
+   ctxt->hw_sys_regs = ctxt->shadow_sys_regs;
+   ctxt->hw_sp_el1 = ctxt->el2_regs[SP_EL2];
+   } else {
+   ctxt->hw_pstate = *vcpu_cpsr(vcpu);
+   ctxt->hw_sys_regs = ctxt->sys_regs;
+   ctxt->hw_sp_el1 = ctxt->gp_regs.sp_el1;
+   }
 }
 
 /**
@@ -38,9 +53,14 @@ void kvm_arm_setup_shadow_state(struct kvm_vcpu *vcpu)
 void kvm_arm_restore_shadow_state(struct kvm_vcpu *vcpu)
 {
struct kvm_cpu_context *ctxt = >arch.ctxt;
-
-   *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
-   ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
+   if (unlikely(vcpu_mode_el2(vcpu))) {
+   *vcpu_cpsr(vcpu) &= PSR_MODE_MASK;
+   *vcpu_cpsr(vcpu) |= ctxt->hw_pstate & ~PSR_MODE_MASK;
+   ctxt->el2_regs[SP_EL2] = ctxt->hw_sp_el1;
+   } else {
+   *vcpu_cpsr(vcpu) = ctxt->hw_pstate;
+   ctxt->gp_regs.sp_el1 = ctxt->hw_sp_el1;
+   }
 }
 
 void kvm_arm_init_cpu_context(kvm_cpu_context_t *cpu_ctxt)
-- 
1.9.1