]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - virt/kvm/arm/vgic/vgic.c
KVM: arm/arm64: vgic: Cap SPIs to the VM-defined maximum
[mirror_ubuntu-bionic-kernel.git] / virt / kvm / arm / vgic / vgic.c
index 96a498871fa0fb19bbbe84b4439c04e8d9642105..b75a6566f626a9e04825bdaf41889e63ae6f07d3 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 #include <linux/list_sort.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
+#include <linux/nospec.h>
 
 #include "vgic.h"
 
@@ -105,12 +106,16 @@ struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu,
                              u32 intid)
 {
        /* SGIs and PPIs */
-       if (intid <= VGIC_MAX_PRIVATE)
+       if (intid <= VGIC_MAX_PRIVATE) {
+               intid = array_index_nospec(intid, VGIC_MAX_PRIVATE + 1);
                return &vcpu->arch.vgic_cpu.private_irqs[intid];
+       }
 
        /* SPIs */
-       if (intid <= VGIC_MAX_SPI)
+       if (intid < (kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) {
+               intid = array_index_nospec(intid, kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS);
                return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS];
+       }
 
        /* LPIs */
        if (intid >= VGIC_MIN_LPI)