Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2015, 2016 ARM Ltd.
0004  */
0005 
0006 #include <linux/kvm.h>
0007 #include <linux/kvm_host.h>
0008 #include <trace/events/kvm.h>
0009 #include <kvm/arm_vgic.h>
0010 #include "vgic.h"
0011 
0012 /**
0013  * vgic_irqfd_set_irq: inject the IRQ corresponding to the
0014  * irqchip routing entry
0015  *
0016  * This is the entry point for irqfd IRQ injection
0017  */
0018 static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e,
0019             struct kvm *kvm, int irq_source_id,
0020             int level, bool line_status)
0021 {
0022     unsigned int spi_id = e->irqchip.pin + VGIC_NR_PRIVATE_IRQS;
0023 
0024     if (!vgic_valid_spi(kvm, spi_id))
0025         return -EINVAL;
0026     return kvm_vgic_inject_irq(kvm, 0, spi_id, level, NULL);
0027 }
0028 
0029 /**
0030  * kvm_set_routing_entry: populate a kvm routing entry
0031  * from a user routing entry
0032  *
0033  * @kvm: the VM this entry is applied to
0034  * @e: kvm kernel routing entry handle
0035  * @ue: user api routing entry handle
0036  * return 0 on success, -EINVAL on errors.
0037  */
0038 int kvm_set_routing_entry(struct kvm *kvm,
0039               struct kvm_kernel_irq_routing_entry *e,
0040               const struct kvm_irq_routing_entry *ue)
0041 {
0042     int r = -EINVAL;
0043 
0044     switch (ue->type) {
0045     case KVM_IRQ_ROUTING_IRQCHIP:
0046         e->set = vgic_irqfd_set_irq;
0047         e->irqchip.irqchip = ue->u.irqchip.irqchip;
0048         e->irqchip.pin = ue->u.irqchip.pin;
0049         if ((e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) ||
0050             (e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
0051             goto out;
0052         break;
0053     case KVM_IRQ_ROUTING_MSI:
0054         e->set = kvm_set_msi;
0055         e->msi.address_lo = ue->u.msi.address_lo;
0056         e->msi.address_hi = ue->u.msi.address_hi;
0057         e->msi.data = ue->u.msi.data;
0058         e->msi.flags = ue->flags;
0059         e->msi.devid = ue->u.msi.devid;
0060         break;
0061     default:
0062         goto out;
0063     }
0064     r = 0;
0065 out:
0066     return r;
0067 }
0068 
0069 static void kvm_populate_msi(struct kvm_kernel_irq_routing_entry *e,
0070                  struct kvm_msi *msi)
0071 {
0072     msi->address_lo = e->msi.address_lo;
0073     msi->address_hi = e->msi.address_hi;
0074     msi->data = e->msi.data;
0075     msi->flags = e->msi.flags;
0076     msi->devid = e->msi.devid;
0077 }
0078 /**
0079  * kvm_set_msi: inject the MSI corresponding to the
0080  * MSI routing entry
0081  *
0082  * This is the entry point for irqfd MSI injection
0083  * and userspace MSI injection.
0084  */
0085 int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
0086         struct kvm *kvm, int irq_source_id,
0087         int level, bool line_status)
0088 {
0089     struct kvm_msi msi;
0090 
0091     if (!vgic_has_its(kvm))
0092         return -ENODEV;
0093 
0094     if (!level)
0095         return -1;
0096 
0097     kvm_populate_msi(e, &msi);
0098     return vgic_its_inject_msi(kvm, &msi);
0099 }
0100 
0101 /**
0102  * kvm_arch_set_irq_inatomic: fast-path for irqfd injection
0103  */
0104 int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
0105                   struct kvm *kvm, int irq_source_id, int level,
0106                   bool line_status)
0107 {
0108     if (!level)
0109         return -EWOULDBLOCK;
0110 
0111     switch (e->type) {
0112     case KVM_IRQ_ROUTING_MSI: {
0113         struct kvm_msi msi;
0114 
0115         if (!vgic_has_its(kvm))
0116             break;
0117 
0118         kvm_populate_msi(e, &msi);
0119         return vgic_its_inject_cached_translation(kvm, &msi);
0120     }
0121 
0122     case KVM_IRQ_ROUTING_IRQCHIP:
0123         /*
0124          * Injecting SPIs is always possible in atomic context
0125          * as long as the damn vgic is initialized.
0126          */
0127         if (unlikely(!vgic_initialized(kvm)))
0128             break;
0129         return vgic_irqfd_set_irq(e, kvm, irq_source_id, 1, line_status);
0130     }
0131 
0132     return -EWOULDBLOCK;
0133 }
0134 
0135 int kvm_vgic_setup_default_irq_routing(struct kvm *kvm)
0136 {
0137     struct kvm_irq_routing_entry *entries;
0138     struct vgic_dist *dist = &kvm->arch.vgic;
0139     u32 nr = dist->nr_spis;
0140     int i, ret;
0141 
0142     entries = kcalloc(nr, sizeof(*entries), GFP_KERNEL_ACCOUNT);
0143     if (!entries)
0144         return -ENOMEM;
0145 
0146     for (i = 0; i < nr; i++) {
0147         entries[i].gsi = i;
0148         entries[i].type = KVM_IRQ_ROUTING_IRQCHIP;
0149         entries[i].u.irqchip.irqchip = 0;
0150         entries[i].u.irqchip.pin = i;
0151     }
0152     ret = kvm_set_irq_routing(kvm, entries, nr, 0);
0153     kfree(entries);
0154     return ret;
0155 }