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
next prev parent 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