aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2016-07-22 12:20:42 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2016-07-22 13:52:03 -0400
commit995a0ee9809b6948bb7bfea77f129fe1d5157cc1 (patch)
treeaa87eb8de3f3e111b9dcc4b470a24a660cd6bb8a
parent180ae7b1182344ca617d8b5200306b02a6b5075d (diff)
KVM: arm/arm64: Enable MSI routing
Up to now, only irqchip routing entries could be set. This patch adds the capability to insert MSI routing entries. For ARM64, let's also increase KVM_MAX_IRQ_ROUTES to 4096: this include SPI irqchip routes plus MSI routes. In the future this might be extended. Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--Documentation/virtual/kvm/api.txt3
-rw-r--r--include/linux/kvm_host.h2
-rw-r--r--virt/kvm/arm/vgic/vgic-irqfd.c8
-rw-r--r--virt/kvm/irqchip.c24
4 files changed, 28 insertions, 9 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 7e5f9afcc693..7a04216d7278 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2381,6 +2381,9 @@ On arm/arm64, gsi routing being supported, the following can happen:
2381- in case no routing entry is associated to this gsi, injection fails 2381- in case no routing entry is associated to this gsi, injection fails
2382- in case the gsi is associated to an irqchip routing entry, 2382- in case the gsi is associated to an irqchip routing entry,
2383 irqchip.pin + 32 corresponds to the injected SPI ID. 2383 irqchip.pin + 32 corresponds to the injected SPI ID.
2384- in case the gsi is associated to an MSI routing entry, the MSI
2385 message and device ID are translated into an LPI (support restricted
2386 to GICv3 ITS in-kernel emulation).
2384 2387
23854.76 KVM_PPC_ALLOCATE_HTAB 23884.76 KVM_PPC_ALLOCATE_HTAB
2386 2389
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index a7eb5c48251e..a318c3b21608 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1048,6 +1048,8 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)
1048 1048
1049#ifdef CONFIG_S390 1049#ifdef CONFIG_S390
1050#define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that... 1050#define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that...
1051#elif defined(CONFIG_ARM64)
1052#define KVM_MAX_IRQ_ROUTES 4096
1051#else 1053#else
1052#define KVM_MAX_IRQ_ROUTES 1024 1054#define KVM_MAX_IRQ_ROUTES 1024
1053#endif 1055#endif
diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c
index 6e84d530d9f7..683a589711b0 100644
--- a/virt/kvm/arm/vgic/vgic-irqfd.c
+++ b/virt/kvm/arm/vgic/vgic-irqfd.c
@@ -59,6 +59,14 @@ int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
59 (e->irqchip.irqchip >= KVM_NR_IRQCHIPS)) 59 (e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
60 goto out; 60 goto out;
61 break; 61 break;
62 case KVM_IRQ_ROUTING_MSI:
63 e->set = kvm_set_msi;
64 e->msi.address_lo = ue->u.msi.address_lo;
65 e->msi.address_hi = ue->u.msi.address_hi;
66 e->msi.data = ue->u.msi.data;
67 e->msi.flags = ue->flags;
68 e->msi.devid = ue->u.msi.devid;
69 break;
62 default: 70 default:
63 goto out; 71 goto out;
64 } 72 }
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index 0c000546aedc..c6202199e505 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -178,6 +178,7 @@ int kvm_set_irq_routing(struct kvm *kvm,
178 unsigned flags) 178 unsigned flags)
179{ 179{
180 struct kvm_irq_routing_table *new, *old; 180 struct kvm_irq_routing_table *new, *old;
181 struct kvm_kernel_irq_routing_entry *e;
181 u32 i, j, nr_rt_entries = 0; 182 u32 i, j, nr_rt_entries = 0;
182 int r; 183 int r;
183 184
@@ -201,23 +202,25 @@ int kvm_set_irq_routing(struct kvm *kvm,
201 new->chip[i][j] = -1; 202 new->chip[i][j] = -1;
202 203
203 for (i = 0; i < nr; ++i) { 204 for (i = 0; i < nr; ++i) {
204 struct kvm_kernel_irq_routing_entry *e;
205
206 r = -ENOMEM; 205 r = -ENOMEM;
207 e = kzalloc(sizeof(*e), GFP_KERNEL); 206 e = kzalloc(sizeof(*e), GFP_KERNEL);
208 if (!e) 207 if (!e)
209 goto out; 208 goto out;
210 209
211 r = -EINVAL; 210 r = -EINVAL;
212 if (ue->flags) { 211 switch (ue->type) {
213 kfree(e); 212 case KVM_IRQ_ROUTING_MSI:
214 goto out; 213 if (ue->flags & ~KVM_MSI_VALID_DEVID)
214 goto free_entry;
215 break;
216 default:
217 if (ue->flags)
218 goto free_entry;
219 break;
215 } 220 }
216 r = setup_routing_entry(new, e, ue); 221 r = setup_routing_entry(new, e, ue);
217 if (r) { 222 if (r)
218 kfree(e); 223 goto free_entry;
219 goto out;
220 }
221 ++ue; 224 ++ue;
222 } 225 }
223 226
@@ -234,7 +237,10 @@ int kvm_set_irq_routing(struct kvm *kvm,
234 237
235 new = old; 238 new = old;
236 r = 0; 239 r = 0;
240 goto out;
237 241
242free_entry:
243 kfree(e);
238out: 244out:
239 free_irq_routing_table(new); 245 free_irq_routing_table(new);
240 246