aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Auger <eric.auger@linaro.org>2015-03-04 05:14:36 -0500
committerChristoffer Dall <christoffer.dall@linaro.org>2015-03-12 10:15:34 -0400
commit174178fed338edba66ab9580af0c5d9e1a4e5019 (patch)
treec290d6b6ae1464dd7dc72bfe63e0bb0553eac460
parent649cf73994e8ac69dfe3e7a35fba9acf051e7fe6 (diff)
KVM: arm/arm64: add irqfd support
This patch enables irqfd on arm/arm64. Both irqfd and resamplefd are supported. Injection is implemented in vgic.c without routing. This patch enables CONFIG_HAVE_KVM_EVENTFD and CONFIG_HAVE_KVM_IRQFD. KVM_CAP_IRQFD is now advertised. KVM_CAP_IRQFD_RESAMPLE capability automatically is advertised as soon as CONFIG_HAVE_KVM_IRQFD is set. Irqfd injection is restricted to SPI. The rationale behind not supporting PPI irqfd injection is that any device using a PPI would be a private-to-the-CPU device (timer for instance), so its state would have to be context-switched along with the VCPU and would require in-kernel wiring anyhow. It is not a relevant use case for irqfds. Signed-off-by: Eric Auger <eric.auger@linaro.org> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
-rw-r--r--Documentation/virtual/kvm/api.txt6
-rw-r--r--arch/arm/include/uapi/asm/kvm.h3
-rw-r--r--arch/arm/kvm/Kconfig2
-rw-r--r--arch/arm/kvm/Makefile2
-rw-r--r--arch/arm/kvm/arm.c1
-rw-r--r--arch/arm64/include/uapi/asm/kvm.h3
-rw-r--r--arch/arm64/kvm/Kconfig2
-rw-r--r--arch/arm64/kvm/Makefile2
-rw-r--r--virt/kvm/arm/vgic.c48
9 files changed, 66 insertions, 3 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index b112efc816f1..b265d8e50be0 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2234,7 +2234,7 @@ into the hash PTE second double word).
22344.75 KVM_IRQFD 22344.75 KVM_IRQFD
2235 2235
2236Capability: KVM_CAP_IRQFD 2236Capability: KVM_CAP_IRQFD
2237Architectures: x86 s390 2237Architectures: x86 s390 arm arm64
2238Type: vm ioctl 2238Type: vm ioctl
2239Parameters: struct kvm_irqfd (in) 2239Parameters: struct kvm_irqfd (in)
2240Returns: 0 on success, -1 on error 2240Returns: 0 on success, -1 on error
@@ -2260,6 +2260,10 @@ Note that closing the resamplefd is not sufficient to disable the
2260irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment 2260irqfd. The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment
2261and need not be specified with KVM_IRQFD_FLAG_DEASSIGN. 2261and need not be specified with KVM_IRQFD_FLAG_DEASSIGN.
2262 2262
2263On ARM/ARM64, the gsi field in the kvm_irqfd struct specifies the Shared
2264Peripheral Interrupt (SPI) index, such that the GIC interrupt ID is
2265given by gsi + 32.
2266
22634.76 KVM_PPC_ALLOCATE_HTAB 22674.76 KVM_PPC_ALLOCATE_HTAB
2264 2268
2265Capability: KVM_CAP_PPC_ALLOC_HTAB 2269Capability: KVM_CAP_PPC_ALLOC_HTAB
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index 0db25bc32864..2499867dd0d8 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -198,6 +198,9 @@ struct kvm_arch_memory_slot {
198/* Highest supported SPI, from VGIC_NR_IRQS */ 198/* Highest supported SPI, from VGIC_NR_IRQS */
199#define KVM_ARM_IRQ_GIC_MAX 127 199#define KVM_ARM_IRQ_GIC_MAX 127
200 200
201/* One single KVM irqchip, ie. the VGIC */
202#define KVM_NR_IRQCHIPS 1
203
201/* PSCI interface */ 204/* PSCI interface */
202#define KVM_PSCI_FN_BASE 0x95c1ba5e 205#define KVM_PSCI_FN_BASE 0x95c1ba5e
203#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) 206#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 83a448e8192b..f1f79d104309 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -28,6 +28,8 @@ config KVM
28 select KVM_GENERIC_DIRTYLOG_READ_PROTECT 28 select KVM_GENERIC_DIRTYLOG_READ_PROTECT
29 select SRCU 29 select SRCU
30 select MMU_NOTIFIER 30 select MMU_NOTIFIER
31 select HAVE_KVM_EVENTFD
32 select HAVE_KVM_IRQFD
31 depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER 33 depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
32 ---help--- 34 ---help---
33 Support hosting virtualized guest machines. 35 Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index 60be7be4c824..a093bf125ca8 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -15,7 +15,7 @@ AFLAGS_init.o := -Wa,-march=armv7-a$(plus_virt)
15AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt) 15AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt)
16 16
17KVM := ../../../virt/kvm 17KVM := ../../../virt/kvm
18kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o 18kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o
19 19
20obj-y += kvm-arm.o init.o interrupts.o 20obj-y += kvm-arm.o init.o interrupts.o
21obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o 21obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 5e893ebb9de7..cc96619f10a4 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -171,6 +171,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
171 int r; 171 int r;
172 switch (ext) { 172 switch (ext) {
173 case KVM_CAP_IRQCHIP: 173 case KVM_CAP_IRQCHIP:
174 case KVM_CAP_IRQFD:
174 case KVM_CAP_DEVICE_CTRL: 175 case KVM_CAP_DEVICE_CTRL:
175 case KVM_CAP_USER_MEMORY: 176 case KVM_CAP_USER_MEMORY:
176 case KVM_CAP_SYNC_MMU: 177 case KVM_CAP_SYNC_MMU:
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 3ef77a466018..c154c0b7eb60 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -191,6 +191,9 @@ struct kvm_arch_memory_slot {
191/* Highest supported SPI, from VGIC_NR_IRQS */ 191/* Highest supported SPI, from VGIC_NR_IRQS */
192#define KVM_ARM_IRQ_GIC_MAX 127 192#define KVM_ARM_IRQ_GIC_MAX 127
193 193
194/* One single KVM irqchip, ie. the VGIC */
195#define KVM_NR_IRQCHIPS 1
196
194/* PSCI interface */ 197/* PSCI interface */
195#define KVM_PSCI_FN_BASE 0x95c1ba5e 198#define KVM_PSCI_FN_BASE 0x95c1ba5e
196#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) 199#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 05f56ce6ee70..5105e297ed5f 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -28,6 +28,8 @@ config KVM
28 select KVM_ARM_HOST 28 select KVM_ARM_HOST
29 select KVM_GENERIC_DIRTYLOG_READ_PROTECT 29 select KVM_GENERIC_DIRTYLOG_READ_PROTECT
30 select SRCU 30 select SRCU
31 select HAVE_KVM_EVENTFD
32 select HAVE_KVM_IRQFD
31 ---help--- 33 ---help---
32 Support hosting virtualized guest machines. 34 Support hosting virtualized guest machines.
33 35
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index c92b26abc691..b22c6360a324 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -11,7 +11,7 @@ ARM=../../../arch/arm/kvm
11 11
12obj-$(CONFIG_KVM_ARM_HOST) += kvm.o 12obj-$(CONFIG_KVM_ARM_HOST) += kvm.o
13 13
14kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o 14kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o
15kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o 15kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o
16kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o 16kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o
17 17
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 897c849305db..c000e978c1fb 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -31,6 +31,7 @@
31#include <asm/kvm_emulate.h> 31#include <asm/kvm_emulate.h>
32#include <asm/kvm_arm.h> 32#include <asm/kvm_arm.h>
33#include <asm/kvm_mmu.h> 33#include <asm/kvm_mmu.h>
34#include <trace/events/kvm.h>
34 35
35/* 36/*
36 * How the whole thing works (courtesy of Christoffer Dall): 37 * How the whole thing works (courtesy of Christoffer Dall):
@@ -1083,6 +1084,7 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
1083 u32 status = vgic_get_interrupt_status(vcpu); 1084 u32 status = vgic_get_interrupt_status(vcpu);
1084 struct vgic_dist *dist = &vcpu->kvm->arch.vgic; 1085 struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
1085 bool level_pending = false; 1086 bool level_pending = false;
1087 struct kvm *kvm = vcpu->kvm;
1086 1088
1087 kvm_debug("STATUS = %08x\n", status); 1089 kvm_debug("STATUS = %08x\n", status);
1088 1090
@@ -1118,6 +1120,17 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
1118 */ 1120 */
1119 vgic_dist_irq_clear_soft_pend(vcpu, vlr.irq); 1121 vgic_dist_irq_clear_soft_pend(vcpu, vlr.irq);
1120 1122
1123 /*
1124 * kvm_notify_acked_irq calls kvm_set_irq()
1125 * to reset the IRQ level. Need to release the
1126 * lock for kvm_set_irq to grab it.
1127 */
1128 spin_unlock(&dist->lock);
1129
1130 kvm_notify_acked_irq(kvm, 0,
1131 vlr.irq - VGIC_NR_PRIVATE_IRQS);
1132 spin_lock(&dist->lock);
1133
1121 /* Any additional pending interrupt? */ 1134 /* Any additional pending interrupt? */
1122 if (vgic_dist_irq_get_level(vcpu, vlr.irq)) { 1135 if (vgic_dist_irq_get_level(vcpu, vlr.irq)) {
1123 vgic_cpu_irq_set(vcpu, vlr.irq); 1136 vgic_cpu_irq_set(vcpu, vlr.irq);
@@ -1913,3 +1926,38 @@ out_free_irq:
1913 free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus()); 1926 free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus());
1914 return ret; 1927 return ret;
1915} 1928}
1929
1930int kvm_irq_map_gsi(struct kvm *kvm,
1931 struct kvm_kernel_irq_routing_entry *entries,
1932 int gsi)
1933{
1934 return gsi;
1935}
1936
1937int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
1938{
1939 return pin;
1940}
1941
1942int kvm_set_irq(struct kvm *kvm, int irq_source_id,
1943 u32 irq, int level, bool line_status)
1944{
1945 unsigned int spi = irq + VGIC_NR_PRIVATE_IRQS;
1946
1947 trace_kvm_set_irq(irq, level, irq_source_id);
1948
1949 BUG_ON(!vgic_initialized(kvm));
1950
1951 if (spi > kvm->arch.vgic.nr_irqs)
1952 return -EINVAL;
1953 return kvm_vgic_inject_irq(kvm, 0, spi, level);
1954
1955}
1956
1957/* MSI not implemented yet */
1958int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
1959 struct kvm *kvm, int irq_source_id,
1960 int level, bool line_status)
1961{
1962 return 0;
1963}