Limit the number of ID and priority bits supported based on the hardware capabilities when resetting the vcpu state. Signed-off-by: Sascha Bischoff Reviewed-by: Jonathan Cameron --- arch/arm64/kvm/vgic/vgic-init.c | 6 +++++- arch/arm64/kvm/vgic/vgic-v5.c | 30 ++++++++++++++++++++++++++++++ arch/arm64/kvm/vgic/vgic.h | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index bde5544b58b09..cad4e217a9f30 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -394,7 +394,11 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) static void kvm_vgic_vcpu_reset(struct kvm_vcpu *vcpu) { - if (kvm_vgic_global_state.type == VGIC_V2) + const struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + + if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V5) + vgic_v5_reset(vcpu); + else if (kvm_vgic_global_state.type == VGIC_V2) vgic_v2_reset(vcpu); else vgic_v3_reset(vcpu); diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c index f6b0879dd705a..c813f439ac9d2 100644 --- a/arch/arm64/kvm/vgic/vgic-v5.c +++ b/arch/arm64/kvm/vgic/vgic-v5.c @@ -56,6 +56,36 @@ int vgic_v5_probe(const struct gic_kvm_info *info) return 0; } +void vgic_v5_reset(struct kvm_vcpu *vcpu) +{ + u64 idr0; + + idr0 = read_sysreg_s(SYS_ICC_IDR0_EL1); + switch (FIELD_GET(ICC_IDR0_EL1_ID_BITS, idr0)) { + case ICC_IDR0_EL1_ID_BITS_16BITS: + vcpu->arch.vgic_cpu.num_id_bits = 16; + break; + case ICC_IDR0_EL1_ID_BITS_24BITS: + vcpu->arch.vgic_cpu.num_id_bits = 24; + break; + default: + pr_warn("unknown value for id_bits"); + vcpu->arch.vgic_cpu.num_id_bits = 16; + } + + switch (FIELD_GET(ICC_IDR0_EL1_PRI_BITS, idr0)) { + case ICC_IDR0_EL1_PRI_BITS_4BITS: + vcpu->arch.vgic_cpu.num_pri_bits = 4; + break; + case ICC_IDR0_EL1_PRI_BITS_5BITS: + vcpu->arch.vgic_cpu.num_pri_bits = 5; + break; + default: + pr_warn("unknown value for priority_bits"); + vcpu->arch.vgic_cpu.num_pri_bits = 4; + } +} + int vgic_v5_init(struct kvm *kvm) { struct kvm_vcpu *vcpu; diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index c7d7546415cb0..ba155020ea99c 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -364,6 +364,7 @@ void vgic_debug_destroy(struct kvm *kvm); int vgic_v5_probe(const struct gic_kvm_info *info); void vgic_v5_get_implemented_ppis(void); +void vgic_v5_reset(struct kvm_vcpu *vcpu); int vgic_v5_init(struct kvm *kvm); int vgic_v5_map_resources(struct kvm *kvm); void vgic_v5_set_ppi_ops(struct vgic_irq *irq); -- 2.34.1