Linux KVM/arm64 development list
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@arm.com>
To: Christoffer Dall <cdall@kernel.org>,
	kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org
Cc: kvm@vger.kernel.org, Marc Zyngier <marc.zyngier@arm.com>,
	Yury Norov <ynorov@caviumnetworks.com>,
	Dave Martin <Dave.Martin@arm.com>,
	Shih-Wei Li <shihwei@cs.columbia.edu>
Subject: Re: [PATCH v5 36/40] KVM: arm/arm64: Handle VGICv2 save/restore from the main VGIC code
Date: Thu, 15 Mar 2018 15:54:32 +0000	[thread overview]
Message-ID: <b834474b-784a-6037-697b-ff7499364df6@arm.com> (raw)
In-Reply-To: <20180227113429.637-37-cdall@kernel.org>

Hi Christoffer,

On 27/02/18 11:34, Christoffer Dall wrote:
> From: Christoffer Dall <christoffer.dall@linaro.org>
> 
> We can program the GICv2 hypervisor control interface logic directly
> from the core vgic code and can instead do the save/restore directly
> from the flush/sync functions, which can lead to a number of future
> optimizations.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>

Reviewed-by: Julien Grall <julien.grall@arm.com>

Cheers,

> ---
> 
> Notes:
>      Changes since v1:
>       - Removed unnecessary kvm_hyp.h include
>       - Adapted the patch based on having gotten rid of storing the elrsr
>         prior to this patch.
>       - No longer change the interrupt handling of the maintenance interrupt
>         handler.  That seems to have been a leftover from an earlier version
>         of the timer patches where we were syncing the vgic state after
>         having enabled interrupts, leading to the maintenance interrupt firing.
>      
>         It may be possible to move the vgic sync function out to an
>         interrupts enabled section later on, which would require
>         re-introducing logic to disable the VGIC maintenance interrupt in the
>         maintenance interrupt handler, but we leave this for future work as
>         the immediate benefit is not clear.
> 
>   arch/arm/kvm/hyp/switch.c        |  4 ---
>   arch/arm64/include/asm/kvm_hyp.h |  2 --
>   arch/arm64/kvm/hyp/switch.c      |  4 ---
>   virt/kvm/arm/hyp/vgic-v2-sr.c    | 65 ----------------------------------------
>   virt/kvm/arm/vgic/vgic-v2.c      | 63 ++++++++++++++++++++++++++++++++++++++
>   virt/kvm/arm/vgic/vgic.c         | 19 +++++++++++-
>   virt/kvm/arm/vgic/vgic.h         |  3 ++
>   7 files changed, 84 insertions(+), 76 deletions(-)
> 
> diff --git a/arch/arm/kvm/hyp/switch.c b/arch/arm/kvm/hyp/switch.c
> index aac025783ee8..882b9b9e0077 100644
> --- a/arch/arm/kvm/hyp/switch.c
> +++ b/arch/arm/kvm/hyp/switch.c
> @@ -92,16 +92,12 @@ static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>   {
>   	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>   		__vgic_v3_save_state(vcpu);
> -	else
> -		__vgic_v2_save_state(vcpu);
>   }
>   
>   static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>   {
>   	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>   		__vgic_v3_restore_state(vcpu);
> -	else
> -		__vgic_v2_restore_state(vcpu);
>   }
>   
>   static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
> diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
> index 949f2e77ae58..febe417b8b4e 100644
> --- a/arch/arm64/include/asm/kvm_hyp.h
> +++ b/arch/arm64/include/asm/kvm_hyp.h
> @@ -120,8 +120,6 @@ typeof(orig) * __hyp_text fname(void)					\
>   	return val;							\
>   }
>   
> -void __vgic_v2_save_state(struct kvm_vcpu *vcpu);
> -void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
>   int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
>   
>   void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index 67c66b4e237e..31badf6e91e8 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -196,16 +196,12 @@ static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>   {
>   	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>   		__vgic_v3_save_state(vcpu);
> -	else
> -		__vgic_v2_save_state(vcpu);
>   }
>   
>   static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>   {
>   	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>   		__vgic_v3_restore_state(vcpu);
> -	else
> -		__vgic_v2_restore_state(vcpu);
>   }
>   
>   static bool __hyp_text __true_value(void)
> diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
> index a91b0d2b9249..0bbafdfd4adb 100644
> --- a/virt/kvm/arm/hyp/vgic-v2-sr.c
> +++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
> @@ -23,71 +23,6 @@
>   #include <asm/kvm_hyp.h>
>   #include <asm/kvm_mmu.h>
>   
> -static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
> -{
> -	struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
> -	u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs;
> -	u64 elrsr;
> -	int i;
> -
> -	elrsr = readl_relaxed(base + GICH_ELRSR0);
> -	if (unlikely(used_lrs > 32))
> -		elrsr |= ((u64)readl_relaxed(base + GICH_ELRSR1)) << 32;
> -
> -	for (i = 0; i < used_lrs; i++) {
> -		if (elrsr & (1UL << i))
> -			cpu_if->vgic_lr[i] &= ~GICH_LR_STATE;
> -		else
> -			cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
> -
> -		writel_relaxed(0, base + GICH_LR0 + (i * 4));
> -	}
> -}
> -
> -/* vcpu is already in the HYP VA space */
> -void __hyp_text __vgic_v2_save_state(struct kvm_vcpu *vcpu)
> -{
> -	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
> -	struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
> -	struct vgic_dist *vgic = &kvm->arch.vgic;
> -	void __iomem *base = kern_hyp_va(vgic->vctrl_base);
> -	u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs;
> -
> -	if (!base)
> -		return;
> -
> -	if (used_lrs) {
> -		cpu_if->vgic_apr = readl_relaxed(base + GICH_APR);
> -		save_lrs(vcpu, base);
> -		writel_relaxed(0, base + GICH_HCR);
> -	} else {
> -		cpu_if->vgic_apr = 0;
> -	}
> -}
> -
> -/* vcpu is already in the HYP VA space */
> -void __hyp_text __vgic_v2_restore_state(struct kvm_vcpu *vcpu)
> -{
> -	struct kvm *kvm = kern_hyp_va(vcpu->kvm);
> -	struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
> -	struct vgic_dist *vgic = &kvm->arch.vgic;
> -	void __iomem *base = kern_hyp_va(vgic->vctrl_base);
> -	int i;
> -	u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs;
> -
> -	if (!base)
> -		return;
> -
> -	if (used_lrs) {
> -		writel_relaxed(cpu_if->vgic_hcr, base + GICH_HCR);
> -		writel_relaxed(cpu_if->vgic_apr, base + GICH_APR);
> -		for (i = 0; i < used_lrs; i++) {
> -			writel_relaxed(cpu_if->vgic_lr[i],
> -				       base + GICH_LR0 + (i * 4));
> -		}
> -	}
> -}
> -
>   #ifdef CONFIG_ARM64
>   /*
>    * __vgic_v2_perform_cpuif_access -- perform a GICV access on behalf of the
> diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
> index bb305d49cfdd..1e5f3eb6973d 100644
> --- a/virt/kvm/arm/vgic/vgic-v2.c
> +++ b/virt/kvm/arm/vgic/vgic-v2.c
> @@ -421,6 +421,69 @@ int vgic_v2_probe(const struct gic_kvm_info *info)
>   	return ret;
>   }
>   
> +static void save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
> +{
> +	struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
> +	u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs;
> +	u64 elrsr;
> +	int i;
> +
> +	elrsr = readl_relaxed(base + GICH_ELRSR0);
> +	if (unlikely(used_lrs > 32))
> +		elrsr |= ((u64)readl_relaxed(base + GICH_ELRSR1)) << 32;
> +
> +	for (i = 0; i < used_lrs; i++) {
> +		if (elrsr & (1UL << i))
> +			cpu_if->vgic_lr[i] &= ~GICH_LR_STATE;
> +		else
> +			cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
> +
> +		writel_relaxed(0, base + GICH_LR0 + (i * 4));
> +	}
> +}
> +
> +void vgic_v2_save_state(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	struct vgic_dist *vgic = &kvm->arch.vgic;
> +	struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
> +	void __iomem *base = vgic->vctrl_base;
> +	u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs;
> +
> +	if (!base)
> +		return;
> +
> +	if (used_lrs) {
> +		cpu_if->vgic_apr = readl_relaxed(base + GICH_APR);
> +		save_lrs(vcpu, base);
> +		writel_relaxed(0, base + GICH_HCR);
> +	} else {
> +		cpu_if->vgic_apr = 0;
> +	}
> +}
> +
> +void vgic_v2_restore_state(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	struct vgic_dist *vgic = &kvm->arch.vgic;
> +	struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
> +	void __iomem *base = vgic->vctrl_base;
> +	u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs;
> +	int i;
> +
> +	if (!base)
> +		return;
> +
> +	if (used_lrs) {
> +		writel_relaxed(cpu_if->vgic_hcr, base + GICH_HCR);
> +		writel_relaxed(cpu_if->vgic_apr, base + GICH_APR);
> +		for (i = 0; i < used_lrs; i++) {
> +			writel_relaxed(cpu_if->vgic_lr[i],
> +				       base + GICH_LR0 + (i * 4));
> +		}
> +	}
> +}
> +
>   void vgic_v2_load(struct kvm_vcpu *vcpu)
>   {
>   	struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
> index c7c5ef190afa..12e2a28f437e 100644
> --- a/virt/kvm/arm/vgic/vgic.c
> +++ b/virt/kvm/arm/vgic/vgic.c
> @@ -749,11 +749,19 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
>   		vgic_clear_lr(vcpu, count);
>   }
>   
> +static inline void vgic_save_state(struct kvm_vcpu *vcpu)
> +{
> +	if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> +		vgic_v2_save_state(vcpu);
> +}
> +
>   /* Sync back the hardware VGIC state into our emulation after a guest's run. */
>   void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
>   {
>   	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>   
> +	vgic_save_state(vcpu);
> +
>   	WARN_ON(vgic_v4_sync_hwstate(vcpu));
>   
>   	/* An empty ap_list_head implies used_lrs == 0 */
> @@ -765,6 +773,12 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
>   	vgic_prune_ap_list(vcpu);
>   }
>   
> +static inline void vgic_restore_state(struct kvm_vcpu *vcpu)
> +{
> +	if (!static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> +		vgic_v2_restore_state(vcpu);
> +}
> +
>   /* Flush our emulation state into the GIC hardware before entering the guest. */
>   void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
>   {
> @@ -780,13 +794,16 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
>   	 * this.
>   	 */
>   	if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head))
> -		return;
> +		goto out;
>   
>   	DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());
>   
>   	spin_lock(&vcpu->arch.vgic_cpu.ap_list_lock);
>   	vgic_flush_lr_state(vcpu);
>   	spin_unlock(&vcpu->arch.vgic_cpu.ap_list_lock);
> +
> +out:
> +	vgic_restore_state(vcpu);
>   }
>   
>   void kvm_vgic_load(struct kvm_vcpu *vcpu)
> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
> index 12c37b89f7a3..89b9547fba27 100644
> --- a/virt/kvm/arm/vgic/vgic.h
> +++ b/virt/kvm/arm/vgic/vgic.h
> @@ -176,6 +176,9 @@ void vgic_v2_init_lrs(void);
>   void vgic_v2_load(struct kvm_vcpu *vcpu);
>   void vgic_v2_put(struct kvm_vcpu *vcpu);
>   
> +void vgic_v2_save_state(struct kvm_vcpu *vcpu);
> +void vgic_v2_restore_state(struct kvm_vcpu *vcpu);
> +
>   static inline void vgic_get_irq_kref(struct vgic_irq *irq)
>   {
>   	if (irq->intid < VGIC_MIN_LPI)
> 

-- 
Julien Grall

  reply	other threads:[~2018-03-15 15:47 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-27 11:33 [PATCH v5 00/40] Optimize KVM/ARM for VHE systems Christoffer Dall
2018-02-27 11:33 ` [PATCH v5 01/40] KVM: arm/arm64: Avoid vcpu_load for other vcpu ioctls than KVM_RUN Christoffer Dall
2018-03-07 13:01   ` Marc Zyngier
2018-02-27 11:33 ` [PATCH v5 02/40] KVM: arm/arm64: Move vcpu_load call after kvm_vcpu_first_run_init Christoffer Dall
2018-02-27 11:33 ` [PATCH v5 03/40] KVM: arm64: Avoid storing the vcpu pointer on the stack Christoffer Dall
2018-03-05 11:08   ` Julien Grall
2018-02-27 11:33 ` [PATCH v5 04/40] KVM: arm64: Rework hyp_panic for VHE and non-VHE Christoffer Dall
2018-02-27 11:33 ` [PATCH v5 05/40] KVM: arm64: Move HCR_INT_OVERRIDE to default HCR_EL2 guest flag Christoffer Dall
2018-02-27 11:33 ` [PATCH v5 06/40] KVM: arm/arm64: Get rid of vcpu->arch.irq_lines Christoffer Dall
2018-02-27 11:33 ` [PATCH v5 07/40] KVM: arm/arm64: Add kvm_vcpu_load_sysregs and kvm_vcpu_put_sysregs Christoffer Dall
2018-02-27 11:33 ` [PATCH v5 08/40] KVM: arm/arm64: Introduce vcpu_el1_is_32bit Christoffer Dall
2018-02-27 11:33 ` [PATCH v5 09/40] KVM: arm64: Move debug dirty flag calculation out of world switch Christoffer Dall
2018-02-27 11:33 ` [PATCH v5 10/40] KVM: arm64: Slightly improve debug save/restore functions Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 11/40] KVM: arm64: Improve debug register save/restore flow Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 12/40] KVM: arm64: Factor out fault info population and gic workarounds Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 13/40] KVM: arm64: Introduce VHE-specific kvm_vcpu_run Christoffer Dall
2018-02-27 13:35   ` Andrew Jones
2018-02-27 11:34 ` [PATCH v5 14/40] KVM: arm64: Remove kern_hyp_va() use in VHE switch function Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 15/40] KVM: arm64: Don't deactivate VM on VHE systems Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 16/40] KVM: arm64: Remove noop calls to timer save/restore from VHE switch Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 17/40] KVM: arm64: Move userspace system registers into separate function Christoffer Dall
2018-03-05 12:59   ` Julien Grall
2018-02-27 11:34 ` [PATCH v5 18/40] KVM: arm64: Rewrite sysreg alternatives to static keys Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 19/40] KVM: arm64: Introduce separate VHE/non-VHE sysreg save/restore functions Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 20/40] KVM: arm/arm64: Remove leftover comment from kvm_vcpu_run_vhe Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 21/40] KVM: arm64: Unify non-VHE host/guest sysreg save and restore functions Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 22/40] KVM: arm64: Don't save the host ELR_EL2 and SPSR_EL2 on VHE systems Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 23/40] KVM: arm64: Change 32-bit handling of VM system registers Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 24/40] KVM: arm64: Rewrite system register accessors to read/write functions Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 25/40] KVM: arm64: Introduce framework for accessing deferred sysregs Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 26/40] KVM: arm/arm64: Prepare to handle deferred save/restore of SPSR_EL1 Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 27/40] KVM: arm64: Prepare to handle deferred save/restore of ELR_EL1 Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 28/40] KVM: arm64: Defer saving/restoring 64-bit sysregs to vcpu load/put on VHE Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 29/40] KVM: arm64: Prepare to handle deferred save/restore of 32-bit registers Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 30/40] KVM: arm64: Defer saving/restoring 32-bit sysregs to vcpu load/put Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 31/40] KVM: arm64: Move common VHE/non-VHE trap config in separate functions Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 32/40] KVM: arm64: Directly call VHE and non-VHE FPSIMD enabled functions Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 33/40] KVM: arm64: Configure c15, PMU, and debug register traps on cpu load/put for VHE Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 34/40] KVM: arm64: Cleanup __activate_traps and __deactive_traps for VHE and non-VHE Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 35/40] KVM: arm/arm64: Get rid of vgic_elrsr Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 36/40] KVM: arm/arm64: Handle VGICv2 save/restore from the main VGIC code Christoffer Dall
2018-03-15 15:54   ` Julien Grall [this message]
2018-02-27 11:34 ` [PATCH v5 37/40] KVM: arm/arm64: Move arm64-only vgic-v2-sr.c file to arm64 Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 38/40] KVM: arm/arm64: Handle VGICv3 save/restore from the main VGIC code on VHE Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 39/40] KVM: arm/arm64: Move VGIC APR save/restore to vgic put/load Christoffer Dall
2018-02-27 11:34 ` [PATCH v5 40/40] KVM: arm/arm64: Avoid VGICv3 save/restore on VHE with no IRQs 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=b834474b-784a-6037-697b-ff7499364df6@arm.com \
    --to=julien.grall@arm.com \
    --cc=Dave.Martin@arm.com \
    --cc=cdall@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=marc.zyngier@arm.com \
    --cc=shihwei@cs.columbia.edu \
    --cc=ynorov@caviumnetworks.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox