aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-08-04 07:59:56 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2016-08-04 07:59:56 -0400
commit6f49b2f3414622d3e41135a65dac98968956662b (patch)
treeefd4c358a40b9e6adb9dd35de3407bbf17bd2935
parentabe9efa79be02cf2ba27f643b214b07877bb050b (diff)
parent89581f06b2bc225f0c9822fa52e714aa2e3810dd (diff)
Merge tag 'kvm-arm-for-4.8-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/ARM Changes for v4.8 - Take 2 Includes GSI routing support to go along with the new VGIC and a small fix that has been cooking in -next for a while.
-rw-r--r--Documentation/virtual/kvm/api.txt46
-rw-r--r--arch/arm/kvm/Kconfig2
-rw-r--r--arch/arm/kvm/Makefile1
-rw-r--r--arch/arm/kvm/irq.h19
-rw-r--r--arch/arm64/kvm/Kconfig2
-rw-r--r--arch/arm64/kvm/Makefile1
-rw-r--r--arch/arm64/kvm/inject_fault.c12
-rw-r--r--arch/arm64/kvm/irq.h19
-rw-r--r--arch/x86/kvm/irq.h3
-rw-r--r--include/kvm/arm_vgic.h7
-rw-r--r--include/linux/kvm_host.h12
-rw-r--r--include/uapi/linux/kvm.h5
-rw-r--r--virt/kvm/arm/vgic/vgic-init.c4
-rw-r--r--virt/kvm/arm/vgic/vgic-irqfd.c116
-rw-r--r--virt/kvm/arm/vgic/vgic.c7
-rw-r--r--virt/kvm/irqchip.c28
16 files changed, 225 insertions, 59 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 5237e1b2fd66..da3c395ed174 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1433,13 +1433,16 @@ KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed.
14334.52 KVM_SET_GSI_ROUTING 14334.52 KVM_SET_GSI_ROUTING
1434 1434
1435Capability: KVM_CAP_IRQ_ROUTING 1435Capability: KVM_CAP_IRQ_ROUTING
1436Architectures: x86 s390 1436Architectures: x86 s390 arm arm64
1437Type: vm ioctl 1437Type: vm ioctl
1438Parameters: struct kvm_irq_routing (in) 1438Parameters: struct kvm_irq_routing (in)
1439Returns: 0 on success, -1 on error 1439Returns: 0 on success, -1 on error
1440 1440
1441Sets the GSI routing table entries, overwriting any previously set entries. 1441Sets the GSI routing table entries, overwriting any previously set entries.
1442 1442
1443On arm/arm64, GSI routing has the following limitation:
1444- GSI routing does not apply to KVM_IRQ_LINE but only to KVM_IRQFD.
1445
1443struct kvm_irq_routing { 1446struct kvm_irq_routing {
1444 __u32 nr; 1447 __u32 nr;
1445 __u32 flags; 1448 __u32 flags;
@@ -1468,7 +1471,13 @@ struct kvm_irq_routing_entry {
1468#define KVM_IRQ_ROUTING_S390_ADAPTER 3 1471#define KVM_IRQ_ROUTING_S390_ADAPTER 3
1469#define KVM_IRQ_ROUTING_HV_SINT 4 1472#define KVM_IRQ_ROUTING_HV_SINT 4
1470 1473
1471No flags are specified so far, the corresponding field must be set to zero. 1474flags:
1475- KVM_MSI_VALID_DEVID: used along with KVM_IRQ_ROUTING_MSI routing entry
1476 type, specifies that the devid field contains a valid value. The per-VM
1477 KVM_CAP_MSI_DEVID capability advertises the requirement to provide
1478 the device ID. If this capability is not available, userspace should
1479 never set the KVM_MSI_VALID_DEVID flag as the ioctl might fail.
1480- zero otherwise
1472 1481
1473struct kvm_irq_routing_irqchip { 1482struct kvm_irq_routing_irqchip {
1474 __u32 irqchip; 1483 __u32 irqchip;
@@ -1479,9 +1488,16 @@ struct kvm_irq_routing_msi {
1479 __u32 address_lo; 1488 __u32 address_lo;
1480 __u32 address_hi; 1489 __u32 address_hi;
1481 __u32 data; 1490 __u32 data;
1482 __u32 pad; 1491 union {
1492 __u32 pad;
1493 __u32 devid;
1494 };
1483}; 1495};
1484 1496
1497If KVM_MSI_VALID_DEVID is set, devid contains a unique device identifier
1498for the device that wrote the MSI message. For PCI, this is usually a
1499BFD identifier in the lower 16 bits.
1500
1485On x86, address_hi is ignored unless the KVM_X2APIC_API_USE_32BIT_IDS 1501On x86, address_hi is ignored unless the KVM_X2APIC_API_USE_32BIT_IDS
1486feature of KVM_CAP_X2APIC_API capability is enabled. If it is enabled, 1502feature of KVM_CAP_X2APIC_API capability is enabled. If it is enabled,
1487address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of 1503address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of
@@ -2199,14 +2215,14 @@ struct kvm_msi {
2199 __u8 pad[12]; 2215 __u8 pad[12];
2200}; 2216};
2201 2217
2202flags: KVM_MSI_VALID_DEVID: devid contains a valid value 2218flags: KVM_MSI_VALID_DEVID: devid contains a valid value. The per-VM
2203devid: If KVM_MSI_VALID_DEVID is set, contains a unique device identifier 2219 KVM_CAP_MSI_DEVID capability advertises the requirement to provide
2204 for the device that wrote the MSI message. 2220 the device ID. If this capability is not available, userspace
2205 For PCI, this is usually a BFD identifier in the lower 16 bits. 2221 should never set the KVM_MSI_VALID_DEVID flag as the ioctl might fail.
2206 2222
2207The per-VM KVM_CAP_MSI_DEVID capability advertises the need to provide 2223If KVM_MSI_VALID_DEVID is set, devid contains a unique device identifier
2208the device ID. If this capability is not set, userland cannot rely on 2224for the device that wrote the MSI message. For PCI, this is usually a
2209the kernel to allow the KVM_MSI_VALID_DEVID flag being set. 2225BFD identifier in the lower 16 bits.
2210 2226
2211On x86, address_hi is ignored unless the KVM_CAP_X2APIC_API capability is 2227On x86, address_hi is ignored unless the KVM_CAP_X2APIC_API capability is
2212enabled. If it is enabled, address_hi bits 31-8 provide bits 31-8 of the 2228enabled. If it is enabled, address_hi bits 31-8 provide bits 31-8 of the
@@ -2383,9 +2399,13 @@ Note that closing the resamplefd is not sufficient to disable the
2383irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment 2399irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment
2384and need not be specified with KVM_IRQFD_FLAG_DEASSIGN. 2400and need not be specified with KVM_IRQFD_FLAG_DEASSIGN.
2385 2401
2386On ARM/ARM64, the gsi field in the kvm_irqfd struct specifies the Shared 2402On arm/arm64, gsi routing being supported, the following can happen:
2387Peripheral Interrupt (SPI) index, such that the GIC interrupt ID is 2403- in case no routing entry is associated to this gsi, injection fails
2388given by gsi + 32. 2404- in case the gsi is associated to an irqchip routing entry,
2405 irqchip.pin + 32 corresponds to the injected SPI ID.
2406- in case the gsi is associated to an MSI routing entry, the MSI
2407 message and device ID are translated into an LPI (support restricted
2408 to GICv3 ITS in-kernel emulation).
2389 2409
23904.76 KVM_PPC_ALLOCATE_HTAB 24104.76 KVM_PPC_ALLOCATE_HTAB
2391 2411
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 95a000515e43..3e1cd0452d67 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -32,6 +32,8 @@ config KVM
32 select KVM_VFIO 32 select KVM_VFIO
33 select HAVE_KVM_EVENTFD 33 select HAVE_KVM_EVENTFD
34 select HAVE_KVM_IRQFD 34 select HAVE_KVM_IRQFD
35 select HAVE_KVM_IRQCHIP
36 select HAVE_KVM_IRQ_ROUTING
35 depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER 37 depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
36 ---help--- 38 ---help---
37 Support hosting virtualized guest machines. 39 Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index 5e28df80dca7..10d77a66cad5 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -29,4 +29,5 @@ obj-y += $(KVM)/arm/vgic/vgic-v2.o
29obj-y += $(KVM)/arm/vgic/vgic-mmio.o 29obj-y += $(KVM)/arm/vgic/vgic-mmio.o
30obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o 30obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
31obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o 31obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
32obj-y += $(KVM)/irqchip.o
32obj-y += $(KVM)/arm/arch_timer.o 33obj-y += $(KVM)/arm/arch_timer.o
diff --git a/arch/arm/kvm/irq.h b/arch/arm/kvm/irq.h
new file mode 100644
index 000000000000..b74099b905fd
--- /dev/null
+++ b/arch/arm/kvm/irq.h
@@ -0,0 +1,19 @@
1/*
2 * irq.h: in kernel interrupt controller related definitions
3 * Copyright (c) 2016 Red Hat, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This header is included by irqchip.c. However, on ARM, interrupt
10 * controller declarations are located in include/kvm/arm_vgic.h since
11 * they are mostly shared between arm and arm64.
12 */
13
14#ifndef __IRQ_H
15#define __IRQ_H
16
17#include <kvm/arm_vgic.h>
18
19#endif
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 9d2eff0b3ad3..9c9edc98d271 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -37,6 +37,8 @@ config KVM
37 select KVM_ARM_VGIC_V3 37 select KVM_ARM_VGIC_V3
38 select KVM_ARM_PMU if HW_PERF_EVENTS 38 select KVM_ARM_PMU if HW_PERF_EVENTS
39 select HAVE_KVM_MSI 39 select HAVE_KVM_MSI
40 select HAVE_KVM_IRQCHIP
41 select HAVE_KVM_IRQ_ROUTING
40 ---help--- 42 ---help---
41 Support hosting virtualized guest machines. 43 Support hosting virtualized guest machines.
42 We don't support KVM with 16K page tables yet, due to the multiple 44 We don't support KVM with 16K page tables yet, due to the multiple
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index a5b96642a9cb..695eb3c7ef41 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -30,5 +30,6 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v2.o
30kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v3.o 30kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v3.o
31kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-kvm-device.o 31kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-kvm-device.o
32kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-its.o 32kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-its.o
33kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/irqchip.o
33kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o 34kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
34kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o 35kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index e9e0e6db73f6..898c0e6aedd4 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -132,16 +132,14 @@ static u64 get_except_vector(struct kvm_vcpu *vcpu, enum exception_type type)
132static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr) 132static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr)
133{ 133{
134 unsigned long cpsr = *vcpu_cpsr(vcpu); 134 unsigned long cpsr = *vcpu_cpsr(vcpu);
135 bool is_aarch32; 135 bool is_aarch32 = vcpu_mode_is_32bit(vcpu);
136 u32 esr = 0; 136 u32 esr = 0;
137 137
138 is_aarch32 = vcpu_mode_is_32bit(vcpu);
139
140 *vcpu_spsr(vcpu) = cpsr;
141 *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); 138 *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu);
142
143 *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); 139 *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
140
144 *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; 141 *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
142 *vcpu_spsr(vcpu) = cpsr;
145 143
146 vcpu_sys_reg(vcpu, FAR_EL1) = addr; 144 vcpu_sys_reg(vcpu, FAR_EL1) = addr;
147 145
@@ -172,11 +170,11 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
172 unsigned long cpsr = *vcpu_cpsr(vcpu); 170 unsigned long cpsr = *vcpu_cpsr(vcpu);
173 u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT); 171 u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
174 172
175 *vcpu_spsr(vcpu) = cpsr;
176 *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu); 173 *vcpu_elr_el1(vcpu) = *vcpu_pc(vcpu);
177
178 *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); 174 *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync);
175
179 *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; 176 *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64;
177 *vcpu_spsr(vcpu) = cpsr;
180 178
181 /* 179 /*
182 * Build an unknown exception, depending on the instruction 180 * Build an unknown exception, depending on the instruction
diff --git a/arch/arm64/kvm/irq.h b/arch/arm64/kvm/irq.h
new file mode 100644
index 000000000000..b74099b905fd
--- /dev/null
+++ b/arch/arm64/kvm/irq.h
@@ -0,0 +1,19 @@
1/*
2 * irq.h: in kernel interrupt controller related definitions
3 * Copyright (c) 2016 Red Hat, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This header is included by irqchip.c. However, on ARM, interrupt
10 * controller declarations are located in include/kvm/arm_vgic.h since
11 * they are mostly shared between arm and arm64.
12 */
13
14#ifndef __IRQ_H
15#define __IRQ_H
16
17#include <kvm/arm_vgic.h>
18
19#endif
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 61ebdc13a29a..035731eb3897 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -120,4 +120,7 @@ void __kvm_migrate_timers(struct kvm_vcpu *vcpu);
120 120
121int apic_has_pending_timer(struct kvm_vcpu *vcpu); 121int apic_has_pending_timer(struct kvm_vcpu *vcpu);
122 122
123int kvm_setup_default_irq_routing(struct kvm *kvm);
124int kvm_setup_empty_irq_routing(struct kvm *kvm);
125
123#endif 126#endif
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 540da5149ba7..19b698ef3336 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -34,6 +34,7 @@
34#define VGIC_MAX_SPI 1019 34#define VGIC_MAX_SPI 1019
35#define VGIC_MAX_RESERVED 1023 35#define VGIC_MAX_RESERVED 1023
36#define VGIC_MIN_LPI 8192 36#define VGIC_MIN_LPI 8192
37#define KVM_IRQCHIP_NUM_PINS (1020 - 32)
37 38
38enum vgic_type { 39enum vgic_type {
39 VGIC_V2, /* Good ol' GICv2 */ 40 VGIC_V2, /* Good ol' GICv2 */
@@ -314,4 +315,10 @@ static inline int kvm_vgic_get_max_vcpus(void)
314 315
315int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); 316int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
316 317
318/**
319 * kvm_vgic_setup_default_irq_routing:
320 * Setup a default flat gsi routing table mapping all SPIs
321 */
322int kvm_vgic_setup_default_irq_routing(struct kvm *kvm);
323
317#endif /* __KVM_ARM_VGIC_H */ 324#endif /* __KVM_ARM_VGIC_H */
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index aafd702f3e21..01e908ac4a39 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -317,7 +317,13 @@ struct kvm_kernel_irq_routing_entry {
317 unsigned irqchip; 317 unsigned irqchip;
318 unsigned pin; 318 unsigned pin;
319 } irqchip; 319 } irqchip;
320 struct msi_msg msi; 320 struct {
321 u32 address_lo;
322 u32 address_hi;
323 u32 data;
324 u32 flags;
325 u32 devid;
326 } msi;
321 struct kvm_s390_adapter_int adapter; 327 struct kvm_s390_adapter_int adapter;
322 struct kvm_hv_sint hv_sint; 328 struct kvm_hv_sint hv_sint;
323 }; 329 };
@@ -1003,12 +1009,12 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)
1003 1009
1004#ifdef CONFIG_S390 1010#ifdef CONFIG_S390
1005#define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that... 1011#define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that...
1012#elif defined(CONFIG_ARM64)
1013#define KVM_MAX_IRQ_ROUTES 4096
1006#else 1014#else
1007#define KVM_MAX_IRQ_ROUTES 1024 1015#define KVM_MAX_IRQ_ROUTES 1024
1008#endif 1016#endif
1009 1017
1010int kvm_setup_default_irq_routing(struct kvm *kvm);
1011int kvm_setup_empty_irq_routing(struct kvm *kvm);
1012int kvm_set_irq_routing(struct kvm *kvm, 1018int kvm_set_irq_routing(struct kvm *kvm,
1013 const struct kvm_irq_routing_entry *entries, 1019 const struct kvm_irq_routing_entry *entries,
1014 unsigned nr, 1020 unsigned nr,
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index e98bb4cce639..300ef255d1e0 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -882,7 +882,10 @@ struct kvm_irq_routing_msi {
882 __u32 address_lo; 882 __u32 address_lo;
883 __u32 address_hi; 883 __u32 address_hi;
884 __u32 data; 884 __u32 data;
885 __u32 pad; 885 union {
886 __u32 pad;
887 __u32 devid;
888 };
886}; 889};
887 890
888struct kvm_irq_routing_s390_adapter { 891struct kvm_irq_routing_s390_adapter {
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
index 1e30ce08700d..fb4b0a79a950 100644
--- a/virt/kvm/arm/vgic/vgic-init.c
+++ b/virt/kvm/arm/vgic/vgic-init.c
@@ -264,6 +264,10 @@ int vgic_init(struct kvm *kvm)
264 kvm_for_each_vcpu(i, vcpu, kvm) 264 kvm_for_each_vcpu(i, vcpu, kvm)
265 kvm_vgic_vcpu_init(vcpu); 265 kvm_vgic_vcpu_init(vcpu);
266 266
267 ret = kvm_vgic_setup_default_irq_routing(kvm);
268 if (ret)
269 goto out;
270
267 dist->initialized = true; 271 dist->initialized = true;
268out: 272out:
269 return ret; 273 return ret;
diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c
index c675513270bb..b31a51a14efb 100644
--- a/virt/kvm/arm/vgic/vgic-irqfd.c
+++ b/virt/kvm/arm/vgic/vgic-irqfd.c
@@ -17,36 +17,116 @@
17#include <linux/kvm.h> 17#include <linux/kvm.h>
18#include <linux/kvm_host.h> 18#include <linux/kvm_host.h>
19#include <trace/events/kvm.h> 19#include <trace/events/kvm.h>
20#include <kvm/arm_vgic.h>
21#include "vgic.h"
20 22
21int kvm_irq_map_gsi(struct kvm *kvm, 23/**
22 struct kvm_kernel_irq_routing_entry *entries, 24 * vgic_irqfd_set_irq: inject the IRQ corresponding to the
23 int gsi) 25 * irqchip routing entry
26 *
27 * This is the entry point for irqfd IRQ injection
28 */
29static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e,
30 struct kvm *kvm, int irq_source_id,
31 int level, bool line_status)
24{ 32{
25 return 0; 33 unsigned int spi_id = e->irqchip.pin + VGIC_NR_PRIVATE_IRQS;
34
35 if (!vgic_valid_spi(kvm, spi_id))
36 return -EINVAL;
37 return kvm_vgic_inject_irq(kvm, 0, spi_id, level);
26} 38}
27 39
28int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned int irqchip, 40/**
29 unsigned int pin) 41 * kvm_set_routing_entry: populate a kvm routing entry
42 * from a user routing entry
43 *
44 * @kvm: the VM this entry is applied to
45 * @e: kvm kernel routing entry handle
46 * @ue: user api routing entry handle
47 * return 0 on success, -EINVAL on errors.
48 */
49#ifdef KVM_CAP_X2APIC_API
50int kvm_set_routing_entry(struct kvm *kvm,
51 struct kvm_kernel_irq_routing_entry *e,
52 const struct kvm_irq_routing_entry *ue)
53#else
54/* Remove this version and the ifdefery once merged into 4.8 */
55int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
56 const struct kvm_irq_routing_entry *ue)
57#endif
30{ 58{
31 return pin; 59 int r = -EINVAL;
60
61 switch (ue->type) {
62 case KVM_IRQ_ROUTING_IRQCHIP:
63 e->set = vgic_irqfd_set_irq;
64 e->irqchip.irqchip = ue->u.irqchip.irqchip;
65 e->irqchip.pin = ue->u.irqchip.pin;
66 if ((e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) ||
67 (e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
68 goto out;
69 break;
70 case KVM_IRQ_ROUTING_MSI:
71 e->set = kvm_set_msi;
72 e->msi.address_lo = ue->u.msi.address_lo;
73 e->msi.address_hi = ue->u.msi.address_hi;
74 e->msi.data = ue->u.msi.data;
75 e->msi.flags = ue->flags;
76 e->msi.devid = ue->u.msi.devid;
77 break;
78 default:
79 goto out;
80 }
81 r = 0;
82out:
83 return r;
32} 84}
33 85
34int kvm_set_irq(struct kvm *kvm, int irq_source_id, 86/**
35 u32 irq, int level, bool line_status) 87 * kvm_set_msi: inject the MSI corresponding to the
88 * MSI routing entry
89 *
90 * This is the entry point for irqfd MSI injection
91 * and userspace MSI injection.
92 */
93int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
94 struct kvm *kvm, int irq_source_id,
95 int level, bool line_status)
36{ 96{
37 unsigned int spi = irq + VGIC_NR_PRIVATE_IRQS; 97 struct kvm_msi msi;
38 98
39 trace_kvm_set_irq(irq, level, irq_source_id); 99 msi.address_lo = e->msi.address_lo;
100 msi.address_hi = e->msi.address_hi;
101 msi.data = e->msi.data;
102 msi.flags = e->msi.flags;
103 msi.devid = e->msi.devid;
40 104
41 BUG_ON(!vgic_initialized(kvm)); 105 if (!vgic_has_its(kvm))
106 return -ENODEV;
42 107
43 return kvm_vgic_inject_irq(kvm, 0, spi, level); 108 return vgic_its_inject_msi(kvm, &msi);
44} 109}
45 110
46/* MSI not implemented yet */ 111int kvm_vgic_setup_default_irq_routing(struct kvm *kvm)
47int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
48 struct kvm *kvm, int irq_source_id,
49 int level, bool line_status)
50{ 112{
51 return 0; 113 struct kvm_irq_routing_entry *entries;
114 struct vgic_dist *dist = &kvm->arch.vgic;
115 u32 nr = dist->nr_spis;
116 int i, ret;
117
118 entries = kcalloc(nr, sizeof(struct kvm_kernel_irq_routing_entry),
119 GFP_KERNEL);
120 if (!entries)
121 return -ENOMEM;
122
123 for (i = 0; i < nr; i++) {
124 entries[i].gsi = i;
125 entries[i].type = KVM_IRQ_ROUTING_IRQCHIP;
126 entries[i].u.irqchip.irqchip = 0;
127 entries[i].u.irqchip.pin = i;
128 }
129 ret = kvm_set_irq_routing(kvm, entries, nr, 0);
130 kfree(entries);
131 return ret;
52} 132}
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index 39f3358c6d91..e7aeac719e09 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -711,10 +711,3 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int virt_irq)
711 return map_is_active; 711 return map_is_active;
712} 712}
713 713
714int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
715{
716 if (vgic_has_its(kvm))
717 return vgic_its_inject_msi(kvm, msi);
718 else
719 return -ENODEV;
720}
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index df99e9c3b64d..3bcc9990adf7 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -62,12 +62,14 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
62{ 62{
63 struct kvm_kernel_irq_routing_entry route; 63 struct kvm_kernel_irq_routing_entry route;
64 64
65 if (!irqchip_in_kernel(kvm) || msi->flags != 0) 65 if (!irqchip_in_kernel(kvm) || (msi->flags & ~KVM_MSI_VALID_DEVID))
66 return -EINVAL; 66 return -EINVAL;
67 67
68 route.msi.address_lo = msi->address_lo; 68 route.msi.address_lo = msi->address_lo;
69 route.msi.address_hi = msi->address_hi; 69 route.msi.address_hi = msi->address_hi;
70 route.msi.data = msi->data; 70 route.msi.data = msi->data;
71 route.msi.flags = msi->flags;
72 route.msi.devid = msi->devid;
71 73
72 return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false); 74 return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false);
73} 75}
@@ -177,6 +179,7 @@ int kvm_set_irq_routing(struct kvm *kvm,
177 unsigned flags) 179 unsigned flags)
178{ 180{
179 struct kvm_irq_routing_table *new, *old; 181 struct kvm_irq_routing_table *new, *old;
182 struct kvm_kernel_irq_routing_entry *e;
180 u32 i, j, nr_rt_entries = 0; 183 u32 i, j, nr_rt_entries = 0;
181 int r; 184 int r;
182 185
@@ -200,23 +203,25 @@ int kvm_set_irq_routing(struct kvm *kvm,
200 new->chip[i][j] = -1; 203 new->chip[i][j] = -1;
201 204
202 for (i = 0; i < nr; ++i) { 205 for (i = 0; i < nr; ++i) {
203 struct kvm_kernel_irq_routing_entry *e;
204
205 r = -ENOMEM; 206 r = -ENOMEM;
206 e = kzalloc(sizeof(*e), GFP_KERNEL); 207 e = kzalloc(sizeof(*e), GFP_KERNEL);
207 if (!e) 208 if (!e)
208 goto out; 209 goto out;
209 210
210 r = -EINVAL; 211 r = -EINVAL;
211 if (ue->flags) { 212 switch (ue->type) {
212 kfree(e); 213 case KVM_IRQ_ROUTING_MSI:
213 goto out; 214 if (ue->flags & ~KVM_MSI_VALID_DEVID)
215 goto free_entry;
216 break;
217 default:
218 if (ue->flags)
219 goto free_entry;
220 break;
214 } 221 }
215 r = setup_routing_entry(kvm, new, e, ue); 222 r = setup_routing_entry(kvm, new, e, ue);
216 if (r) { 223 if (r)
217 kfree(e); 224 goto free_entry;
218 goto out;
219 }
220 ++ue; 225 ++ue;
221 } 226 }
222 227
@@ -233,7 +238,10 @@ int kvm_set_irq_routing(struct kvm *kvm,
233 238
234 new = old; 239 new = old;
235 r = 0; 240 r = 0;
241 goto out;
236 242
243free_entry:
244 kfree(e);
237out: 245out:
238 free_irq_routing_table(new); 246 free_irq_routing_table(new);
239 247