// SPDX-License-Identifier: GPL-2.0-only #include #include #include "vgic.h" /* * Probe for a vGICv5 compatible interrupt controller, returning 0 on success. * Currently only supports GICv3-based VMs on a GICv5 host, and hence only * registers a VGIC_V3 device. */ int vgic_v5_probe(const struct gic_kvm_info *info) { u64 ich_vtr_el2; int ret; if (!info->has_gcie_v3_compat) return -ENODEV; kvm_vgic_global_state.type = VGIC_V5; kvm_vgic_global_state.has_gcie_v3_compat = true; /* We only support v3 compat mode - use vGICv3 limits */ kvm_vgic_global_state.max_gic_vcpus = VGIC_V3_MAX_CPUS; kvm_vgic_global_state.vcpu_base = 0; kvm_vgic_global_state.vctrl_base = NULL; kvm_vgic_global_state.can_emulate_gicv2 = false; kvm_vgic_global_state.has_gicv4 = false; kvm_vgic_global_state.has_gicv4_1 = false; ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_gic_config); kvm_vgic_global_state.ich_vtr_el2 = (u32)ich_vtr_el2; /* * The ListRegs field is 5 bits, but there is an architectural * maximum of 16 list registers. Just ignore bit 4... */ kvm_vgic_global_state.nr_lr = (ich_vtr_el2 & 0xf) + 1; ret = kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V3); if (ret) { kvm_err("Cannot register GICv3-legacy KVM device.\n"); return ret; } static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif); kvm_info("GCIE legacy system register CPU interface\n"); return 0; }