[PATCH 35/37] KVM: arm/arm64: Get rid of vgic_elrsr
Yury Norov
ynorov at caviumnetworks.com
Sun Nov 26 06:39:02 PST 2017
On Thu, Oct 12, 2017 at 12:41:39PM +0200, Christoffer Dall wrote:
> There is really no need to store the vgic_elrsr on the VGIC data
> structures as the only need we have for the elrsr is to figure out if an
> LR is inavtive when we save the VGIC state upon returning from the
> guest. We can might as well store this in a temporary local variable.
>
> This also gets rid of the endianness conversion in the VGIC save
> function, which is completely unnecessary and would actually result in
> incorrect functionality on big-endian systems,
Does it mean that existing code in mainline is broken for BE systems?
If so, I think that it should be fixed in separated patch...
> because we are only using
> typed values here and not converting pointers and reading different
> types here.
>
> Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
> ---
> include/kvm/arm_vgic.h | 2 --
> virt/kvm/arm/hyp/vgic-v3-sr.c | 6 +++---
> virt/kvm/arm/vgic/vgic-v2.c | 33 +++++++--------------------------
> virt/kvm/arm/vgic/vgic-v3.c | 1 -
> 4 files changed, 10 insertions(+), 32 deletions(-)
>
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 34dba51..79c9e67 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -237,7 +237,6 @@ struct vgic_dist {
> struct vgic_v2_cpu_if {
> u32 vgic_hcr;
> u32 vgic_vmcr;
> - u64 vgic_elrsr; /* Saved only */
> u32 vgic_apr;
> u32 vgic_lr[VGIC_V2_MAX_LRS];
> };
> @@ -246,7 +245,6 @@ struct vgic_v3_cpu_if {
> u32 vgic_hcr;
> u32 vgic_vmcr;
> u32 vgic_sre; /* Restored only, change ignored */
> - u32 vgic_elrsr; /* Saved only */
> u32 vgic_ap0r[4];
> u32 vgic_ap1r[4];
> u64 vgic_lr[VGIC_V3_MAX_LRS];
> diff --git a/virt/kvm/arm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
> index 91728fa..05548b2 100644
> --- a/virt/kvm/arm/hyp/vgic-v3-sr.c
> +++ b/virt/kvm/arm/hyp/vgic-v3-sr.c
> @@ -222,15 +222,16 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
> if (used_lrs) {
> int i;
> u32 nr_pre_bits;
> + u32 elrsr;
>
> - cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2);
> + elrsr = read_gicreg(ICH_ELSR_EL2);
>
> write_gicreg(0, ICH_HCR_EL2);
> val = read_gicreg(ICH_VTR_EL2);
> nr_pre_bits = vtr_to_nr_pre_bits(val);
>
> for (i = 0; i < used_lrs; i++) {
> - if (cpu_if->vgic_elrsr & (1 << i))
> + if (elrsr & (1 << i))
Same comments as to patch 28. Here should be test_bit(), I think.
And if it's possible, for set bits in elrsr it's simpler not to write
~ICH_LR_STATE to cpu_if->vgic_lr, but directly to IO memory in
__vgic_v3_restore_state().
> cpu_if->vgic_lr[i] &= ~ICH_LR_STATE;
> else
> cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
> @@ -261,7 +262,6 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
> if (static_branch_unlikely(&vgic_v3_cpuif_trap))
> write_gicreg(0, ICH_HCR_EL2);
>
> - cpu_if->vgic_elrsr = 0xffff;
> cpu_if->vgic_ap0r[0] = 0;
> cpu_if->vgic_ap0r[1] = 0;
> cpu_if->vgic_ap0r[2] = 0;
> diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
> index 259079b..df7e03b 100644
> --- a/virt/kvm/arm/vgic/vgic-v2.c
> +++ b/virt/kvm/arm/vgic/vgic-v2.c
> @@ -247,7 +247,6 @@ void vgic_v2_enable(struct kvm_vcpu *vcpu)
> * anyway.
> */
> vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0;
> - vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr = ~0;
>
> /* Get the show on the road... */
> vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN;
> @@ -404,33 +403,19 @@ int vgic_v2_probe(const struct gic_kvm_info *info)
> return ret;
> }
>
> -static void save_elrsr(struct kvm_vcpu *vcpu, void __iomem *base)
> -{
> - struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
> - int nr_lr = kvm_vgic_global_state.nr_lr;
> - u32 elrsr0, elrsr1;
> -
> - elrsr0 = readl_relaxed(base + GICH_ELRSR0);
> - if (unlikely(nr_lr > 32))
> - elrsr1 = readl_relaxed(base + GICH_ELRSR1);
> - else
> - elrsr1 = 0;
> -
> -#ifdef CONFIG_CPU_BIG_ENDIAN
> - cpu_if->vgic_elrsr = ((u64)elrsr0 << 32) | elrsr1;
> -#else
> - cpu_if->vgic_elrsr = ((u64)elrsr1 << 32) | elrsr0;
> -#endif
> -}
> -
> static void save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
> {
> struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
> - int i;
> u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs;
Not to this patch, but anyway, what for to reserve u64 for used_lrs
here and in struct vgic_cpu, when maximum value for it is 64?
> + u64 elrsr;
> + int i;
Nit. What for you move 'int i' declaration?
> +
> + 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 (cpu_if->vgic_elrsr & (1UL << i))
> + if (elrsr & (1UL << i))
test_bit()
> cpu_if->vgic_lr[i] &= ~GICH_LR_STATE;
> else
> cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
> @@ -452,13 +437,9 @@ void vgic_v2_save_state(struct kvm_vcpu *vcpu)
>
> if (used_lrs) {
> cpu_if->vgic_apr = readl_relaxed(base + GICH_APR);
> -
> - save_elrsr(vcpu, base);
> save_lrs(vcpu, base);
> -
> writel_relaxed(0, base + GICH_HCR);
> } else {
> - cpu_if->vgic_elrsr = ~0UL;
> cpu_if->vgic_apr = 0;
> }
> }
> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
> index 863351c..0900649 100644
> --- a/virt/kvm/arm/vgic/vgic-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-v3.c
> @@ -237,7 +237,6 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
> * anyway.
> */
> vgic_v3->vgic_vmcr = 0;
> - vgic_v3->vgic_elrsr = ~0;
>
> /*
> * If we are emulating a GICv3, we do it in an non-GICv2-compatible
> --
> 2.9.0
More information about the linux-arm-kernel
mailing list