All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoffer Dall <cdall@linaro.org>
To: Marc Zyngier <marc.zyngier@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org,
	kvmarm@lists.cs.columbia.edu
Subject: Re: [PATCH v2] KVM: arm/arm64: vgic-v3: De-optimize VMCR save/restore when emulating a GICv2
Date: Wed, 19 Apr 2017 16:45:16 +0200	[thread overview]
Message-ID: <20170419144516.GD4104@cbox> (raw)
In-Reply-To: <20170419111526.21073-1-marc.zyngier@arm.com>

On Wed, Apr 19, 2017 at 12:15:26PM +0100, Marc Zyngier wrote:
> When emulating a GICv2-on-GICv3, special care must be taken to only
> save/restore VMCR_EL2 when ICC_SRE_EL1.SRE is cleared. Otherwise,
> all Group-0 interrupts end-up being delivered as FIQ, which is
> probably not what the guest expects, as demonstrated here with
> an unhappy EFI:
> 
> 	FIQ Exception at 0x000000013BD21CC4
> 
> This means that we cannot perform the load/put trick when dealing
> with VMCR_EL2 (because the host has SRE set), and we have to deal
> with it in the world-switch.
> 
> Fortunately, this is not the most common case (modern guests should
> be able to deal with GICv3 directly), and the performance is not worse
> than what it was before the VMCR optimization.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Christoffer Dall <cdall@linaro.org>

I have applied both fixes.

Thanks,
-Christoffer

> ---
> * From v1:
>   - Move vgic_sre testing from vgic_{load,put} to vgic_v3_{load,put}
> 
>  virt/kvm/arm/hyp/vgic-v3-sr.c |  8 ++++++--
>  virt/kvm/arm/vgic/vgic-v3.c   | 11 +++++++++--
>  2 files changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
> index 3d0b1ddb6929..91922c1eddc8 100644
> --- a/virt/kvm/arm/hyp/vgic-v3-sr.c
> +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
> @@ -128,8 +128,10 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
>  	 * Make sure stores to the GIC via the memory mapped interface
>  	 * are now visible to the system register interface.
>  	 */
> -	if (!cpu_if->vgic_sre)
> +	if (!cpu_if->vgic_sre) {
>  		dsb(st);
> +		cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2);
> +	}
>  
>  	if (used_lrs) {
>  		int i;
> @@ -205,11 +207,13 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
>  	 * delivered as a FIQ to the guest, with potentially fatal
>  	 * consequences. So we must make sure that ICC_SRE_EL1 has
>  	 * been actually programmed with the value we want before
> -	 * starting to mess with the rest of the GIC.
> +	 * starting to mess with the rest of the GIC, and VMCR_EL2 in
> +	 * particular.
>  	 */
>  	if (!cpu_if->vgic_sre) {
>  		write_gicreg(0, ICC_SRE_EL1);
>  		isb();
> +		write_gicreg(cpu_if->vgic_vmcr, ICH_VMCR_EL2);
>  	}
>  
>  	val = read_gicreg(ICH_VTR_EL2);
> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
> index bc7010db9f4d..df1503650300 100644
> --- a/virt/kvm/arm/vgic/vgic-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-v3.c
> @@ -373,12 +373,19 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
>  {
>  	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
>  
> -	kvm_call_hyp(__vgic_v3_write_vmcr, cpu_if->vgic_vmcr);
> +	/*
> +	 * If dealing with a GICv2 emulation on GICv3, VMCR_EL2.VFIQen
> +	 * is dependent on ICC_SRE_EL1.SRE, and we have to perform the
> +	 * VMCR_EL2 save/restore in the world switch.
> +	 */
> +	if (likely(cpu_if->vgic_sre))
> +		kvm_call_hyp(__vgic_v3_write_vmcr, cpu_if->vgic_vmcr);
>  }
>  
>  void vgic_v3_put(struct kvm_vcpu *vcpu)
>  {
>  	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
>  
> -	cpu_if->vgic_vmcr = kvm_call_hyp(__vgic_v3_read_vmcr);
> +	if (likely(cpu_if->vgic_sre))
> +		cpu_if->vgic_vmcr = kvm_call_hyp(__vgic_v3_read_vmcr);
>  }
> -- 
> 2.11.0
> 

WARNING: multiple messages have this Message-ID (diff)
From: cdall@linaro.org (Christoffer Dall)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2] KVM: arm/arm64: vgic-v3: De-optimize VMCR save/restore when emulating a GICv2
Date: Wed, 19 Apr 2017 16:45:16 +0200	[thread overview]
Message-ID: <20170419144516.GD4104@cbox> (raw)
In-Reply-To: <20170419111526.21073-1-marc.zyngier@arm.com>

On Wed, Apr 19, 2017 at 12:15:26PM +0100, Marc Zyngier wrote:
> When emulating a GICv2-on-GICv3, special care must be taken to only
> save/restore VMCR_EL2 when ICC_SRE_EL1.SRE is cleared. Otherwise,
> all Group-0 interrupts end-up being delivered as FIQ, which is
> probably not what the guest expects, as demonstrated here with
> an unhappy EFI:
> 
> 	FIQ Exception at 0x000000013BD21CC4
> 
> This means that we cannot perform the load/put trick when dealing
> with VMCR_EL2 (because the host has SRE set), and we have to deal
> with it in the world-switch.
> 
> Fortunately, this is not the most common case (modern guests should
> be able to deal with GICv3 directly), and the performance is not worse
> than what it was before the VMCR optimization.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Reviewed-by: Christoffer Dall <cdall@linaro.org>

I have applied both fixes.

Thanks,
-Christoffer

> ---
> * From v1:
>   - Move vgic_sre testing from vgic_{load,put} to vgic_v3_{load,put}
> 
>  virt/kvm/arm/hyp/vgic-v3-sr.c |  8 ++++++--
>  virt/kvm/arm/vgic/vgic-v3.c   | 11 +++++++++--
>  2 files changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
> index 3d0b1ddb6929..91922c1eddc8 100644
> --- a/virt/kvm/arm/hyp/vgic-v3-sr.c
> +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
> @@ -128,8 +128,10 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
>  	 * Make sure stores to the GIC via the memory mapped interface
>  	 * are now visible to the system register interface.
>  	 */
> -	if (!cpu_if->vgic_sre)
> +	if (!cpu_if->vgic_sre) {
>  		dsb(st);
> +		cpu_if->vgic_vmcr = read_gicreg(ICH_VMCR_EL2);
> +	}
>  
>  	if (used_lrs) {
>  		int i;
> @@ -205,11 +207,13 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
>  	 * delivered as a FIQ to the guest, with potentially fatal
>  	 * consequences. So we must make sure that ICC_SRE_EL1 has
>  	 * been actually programmed with the value we want before
> -	 * starting to mess with the rest of the GIC.
> +	 * starting to mess with the rest of the GIC, and VMCR_EL2 in
> +	 * particular.
>  	 */
>  	if (!cpu_if->vgic_sre) {
>  		write_gicreg(0, ICC_SRE_EL1);
>  		isb();
> +		write_gicreg(cpu_if->vgic_vmcr, ICH_VMCR_EL2);
>  	}
>  
>  	val = read_gicreg(ICH_VTR_EL2);
> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
> index bc7010db9f4d..df1503650300 100644
> --- a/virt/kvm/arm/vgic/vgic-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-v3.c
> @@ -373,12 +373,19 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
>  {
>  	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
>  
> -	kvm_call_hyp(__vgic_v3_write_vmcr, cpu_if->vgic_vmcr);
> +	/*
> +	 * If dealing with a GICv2 emulation on GICv3, VMCR_EL2.VFIQen
> +	 * is dependent on ICC_SRE_EL1.SRE, and we have to perform the
> +	 * VMCR_EL2 save/restore in the world switch.
> +	 */
> +	if (likely(cpu_if->vgic_sre))
> +		kvm_call_hyp(__vgic_v3_write_vmcr, cpu_if->vgic_vmcr);
>  }
>  
>  void vgic_v3_put(struct kvm_vcpu *vcpu)
>  {
>  	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
>  
> -	cpu_if->vgic_vmcr = kvm_call_hyp(__vgic_v3_read_vmcr);
> +	if (likely(cpu_if->vgic_sre))
> +		cpu_if->vgic_vmcr = kvm_call_hyp(__vgic_v3_read_vmcr);
>  }
> -- 
> 2.11.0
> 

  reply	other threads:[~2017-04-19 14:42 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-19 11:15 [PATCH v2] KVM: arm/arm64: vgic-v3: De-optimize VMCR save/restore when emulating a GICv2 Marc Zyngier
2017-04-19 11:15 ` Marc Zyngier
2017-04-19 14:45 ` Christoffer Dall [this message]
2017-04-19 14:45   ` Christoffer Dall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170419144516.GD4104@cbox \
    --to=cdall@linaro.org \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=marc.zyngier@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.