aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-03-24 06:49:13 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-03-24 06:49:13 -0400
commitea2108c9308071ae41ae6f537724cb2734045943 (patch)
tree132b9c4130174a41e06ac73722cc85a418d3959b
parent673f7b4257a1fe7b181e1a1182ecc2b6b2b795f1 (diff)
parentf3f710bc64e121c10c67ce58c893d3bc8c72abe4 (diff)
Merge branch 'kvms390-irqfd' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-next
-rw-r--r--Documentation/virtual/kvm/api.txt27
-rw-r--r--Documentation/virtual/kvm/devices/s390_flic.txt45
-rw-r--r--arch/s390/include/asm/kvm_host.h32
-rw-r--r--arch/s390/include/uapi/asm/kvm.h22
-rw-r--r--arch/s390/kvm/Kconfig2
-rw-r--r--arch/s390/kvm/Makefile2
-rw-r--r--arch/s390/kvm/interrupt.c294
-rw-r--r--arch/s390/kvm/irq.h22
-rw-r--r--arch/s390/kvm/kvm-s390.c42
-rw-r--r--arch/s390/kvm/kvm-s390.h2
-rw-r--r--include/linux/kvm_host.h13
-rw-r--r--include/uapi/linux/kvm.h16
12 files changed, 511 insertions, 8 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 4714f282a43e..2cb1640a90ad 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -586,8 +586,8 @@ struct kvm_fpu {
586 586
5874.24 KVM_CREATE_IRQCHIP 5874.24 KVM_CREATE_IRQCHIP
588 588
589Capability: KVM_CAP_IRQCHIP 589Capability: KVM_CAP_IRQCHIP, KVM_CAP_S390_IRQCHIP (s390)
590Architectures: x86, ia64, ARM, arm64 590Architectures: x86, ia64, ARM, arm64, s390
591Type: vm ioctl 591Type: vm ioctl
592Parameters: none 592Parameters: none
593Returns: 0 on success, -1 on error 593Returns: 0 on success, -1 on error
@@ -596,7 +596,10 @@ Creates an interrupt controller model in the kernel. On x86, creates a virtual
596ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a 596ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a
597local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23 597local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23
598only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM/arm64, a GIC is 598only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM/arm64, a GIC is
599created. 599created. On s390, a dummy irq routing table is created.
600
601Note that on s390 the KVM_CAP_S390_IRQCHIP vm capability needs to be enabled
602before KVM_CREATE_IRQCHIP can be used.
600 603
601 604
6024.25 KVM_IRQ_LINE 6054.25 KVM_IRQ_LINE
@@ -932,9 +935,9 @@ documentation when it pops into existence).
932 935
9334.37 KVM_ENABLE_CAP 9364.37 KVM_ENABLE_CAP
934 937
935Capability: KVM_CAP_ENABLE_CAP 938Capability: KVM_CAP_ENABLE_CAP, KVM_CAP_ENABLE_CAP_VM
936Architectures: ppc, s390 939Architectures: ppc, s390
937Type: vcpu ioctl 940Type: vcpu ioctl, vm ioctl (with KVM_CAP_ENABLE_CAP_VM)
938Parameters: struct kvm_enable_cap (in) 941Parameters: struct kvm_enable_cap (in)
939Returns: 0 on success; -1 on error 942Returns: 0 on success; -1 on error
940 943
@@ -965,6 +968,8 @@ function properly, this is the place to put them.
965 __u8 pad[64]; 968 __u8 pad[64];
966}; 969};
967 970
971The vcpu ioctl should be used for vcpu-specific capabilities, the vm ioctl
972for vm-wide capabilities.
968 973
9694.38 KVM_GET_MP_STATE 9744.38 KVM_GET_MP_STATE
970 975
@@ -1334,7 +1339,7 @@ KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed.
13344.52 KVM_SET_GSI_ROUTING 13394.52 KVM_SET_GSI_ROUTING
1335 1340
1336Capability: KVM_CAP_IRQ_ROUTING 1341Capability: KVM_CAP_IRQ_ROUTING
1337Architectures: x86 ia64 1342Architectures: x86 ia64 s390
1338Type: vm ioctl 1343Type: vm ioctl
1339Parameters: struct kvm_irq_routing (in) 1344Parameters: struct kvm_irq_routing (in)
1340Returns: 0 on success, -1 on error 1345Returns: 0 on success, -1 on error
@@ -1357,6 +1362,7 @@ struct kvm_irq_routing_entry {
1357 union { 1362 union {
1358 struct kvm_irq_routing_irqchip irqchip; 1363 struct kvm_irq_routing_irqchip irqchip;
1359 struct kvm_irq_routing_msi msi; 1364 struct kvm_irq_routing_msi msi;
1365 struct kvm_irq_routing_s390_adapter adapter;
1360 __u32 pad[8]; 1366 __u32 pad[8];
1361 } u; 1367 } u;
1362}; 1368};
@@ -1364,6 +1370,7 @@ struct kvm_irq_routing_entry {
1364/* gsi routing entry types */ 1370/* gsi routing entry types */
1365#define KVM_IRQ_ROUTING_IRQCHIP 1 1371#define KVM_IRQ_ROUTING_IRQCHIP 1
1366#define KVM_IRQ_ROUTING_MSI 2 1372#define KVM_IRQ_ROUTING_MSI 2
1373#define KVM_IRQ_ROUTING_S390_ADAPTER 3
1367 1374
1368No flags are specified so far, the corresponding field must be set to zero. 1375No flags are specified so far, the corresponding field must be set to zero.
1369 1376
@@ -1379,6 +1386,14 @@ struct kvm_irq_routing_msi {
1379 __u32 pad; 1386 __u32 pad;
1380}; 1387};
1381 1388
1389struct kvm_irq_routing_s390_adapter {
1390 __u64 ind_addr;
1391 __u64 summary_addr;
1392 __u64 ind_offset;
1393 __u32 summary_offset;
1394 __u32 adapter_id;
1395};
1396
1382 1397
13834.53 KVM_ASSIGN_SET_MSIX_NR 13984.53 KVM_ASSIGN_SET_MSIX_NR
1384 1399
diff --git a/Documentation/virtual/kvm/devices/s390_flic.txt b/Documentation/virtual/kvm/devices/s390_flic.txt
index 410fa673e5b6..4ceef53164b0 100644
--- a/Documentation/virtual/kvm/devices/s390_flic.txt
+++ b/Documentation/virtual/kvm/devices/s390_flic.txt
@@ -12,6 +12,7 @@ FLIC provides support to
12- inspect currently pending interrupts (KVM_FLIC_GET_ALL_IRQS) 12- inspect currently pending interrupts (KVM_FLIC_GET_ALL_IRQS)
13- purge all pending floating interrupts (KVM_DEV_FLIC_CLEAR_IRQS) 13- purge all pending floating interrupts (KVM_DEV_FLIC_CLEAR_IRQS)
14- enable/disable for the guest transparent async page faults 14- enable/disable for the guest transparent async page faults
15- register and modify adapter interrupt sources (KVM_DEV_FLIC_ADAPTER_*)
15 16
16Groups: 17Groups:
17 KVM_DEV_FLIC_ENQUEUE 18 KVM_DEV_FLIC_ENQUEUE
@@ -44,3 +45,47 @@ Groups:
44 Disables async page faults for the guest and waits until already pending 45 Disables async page faults for the guest and waits until already pending
45 async page faults are done. This is necessary to trigger a completion interrupt 46 async page faults are done. This is necessary to trigger a completion interrupt
46 for every init interrupt before migrating the interrupt list. 47 for every init interrupt before migrating the interrupt list.
48
49 KVM_DEV_FLIC_ADAPTER_REGISTER
50 Register an I/O adapter interrupt source. Takes a kvm_s390_io_adapter
51 describing the adapter to register:
52
53struct kvm_s390_io_adapter {
54 __u32 id;
55 __u8 isc;
56 __u8 maskable;
57 __u8 swap;
58 __u8 pad;
59};
60
61 id contains the unique id for the adapter, isc the I/O interruption subclass
62 to use, maskable whether this adapter may be masked (interrupts turned off)
63 and swap whether the indicators need to be byte swapped.
64
65
66 KVM_DEV_FLIC_ADAPTER_MODIFY
67 Modifies attributes of an existing I/O adapter interrupt source. Takes
68 a kvm_s390_io_adapter_req specifiying the adapter and the operation:
69
70struct kvm_s390_io_adapter_req {
71 __u32 id;
72 __u8 type;
73 __u8 mask;
74 __u16 pad0;
75 __u64 addr;
76};
77
78 id specifies the adapter and type the operation. The supported operations
79 are:
80
81 KVM_S390_IO_ADAPTER_MASK
82 mask or unmask the adapter, as specified in mask
83
84 KVM_S390_IO_ADAPTER_MAP
85 perform a gmap translation for the guest address provided in addr,
86 pin a userspace page for the translated address and add it to the
87 list of mappings
88
89 KVM_S390_IO_ADAPTER_UNMAP
90 release a userspace page for the translated address specified in addr
91 from the list of mappings
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 734d302ba389..dd3933754d23 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -19,10 +19,19 @@
19#include <linux/kvm.h> 19#include <linux/kvm.h>
20#include <asm/debug.h> 20#include <asm/debug.h>
21#include <asm/cpu.h> 21#include <asm/cpu.h>
22#include <asm/isc.h>
22 23
23#define KVM_MAX_VCPUS 64 24#define KVM_MAX_VCPUS 64
24#define KVM_USER_MEM_SLOTS 32 25#define KVM_USER_MEM_SLOTS 32
25 26
27/*
28 * These seem to be used for allocating ->chip in the routing table,
29 * which we don't use. 4096 is an out-of-thin-air value. If we need
30 * to look at ->chip later on, we'll need to revisit this.
31 */
32#define KVM_NR_IRQCHIPS 1
33#define KVM_IRQCHIP_NUM_PINS 4096
34
26struct sca_entry { 35struct sca_entry {
27 atomic_t scn; 36 atomic_t scn;
28 __u32 reserved; 37 __u32 reserved;
@@ -245,6 +254,27 @@ struct kvm_vm_stat {
245struct kvm_arch_memory_slot { 254struct kvm_arch_memory_slot {
246}; 255};
247 256
257struct s390_map_info {
258 struct list_head list;
259 __u64 guest_addr;
260 __u64 addr;
261 struct page *page;
262};
263
264struct s390_io_adapter {
265 unsigned int id;
266 int isc;
267 bool maskable;
268 bool masked;
269 bool swap;
270 struct rw_semaphore maps_lock;
271 struct list_head maps;
272 atomic_t nr_maps;
273};
274
275#define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8)
276#define MAX_S390_ADAPTER_MAPS 256
277
248struct kvm_arch{ 278struct kvm_arch{
249 struct sca_block *sca; 279 struct sca_block *sca;
250 debug_info_t *dbf; 280 debug_info_t *dbf;
@@ -252,6 +282,8 @@ struct kvm_arch{
252 struct kvm_device *flic; 282 struct kvm_device *flic;
253 struct gmap *gmap; 283 struct gmap *gmap;
254 int css_support; 284 int css_support;
285 int use_irqchip;
286 struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS];
255}; 287};
256 288
257#define KVM_HVA_ERR_BAD (-1UL) 289#define KVM_HVA_ERR_BAD (-1UL)
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h
index 2f0ade24f96a..c003c6a73b1e 100644
--- a/arch/s390/include/uapi/asm/kvm.h
+++ b/arch/s390/include/uapi/asm/kvm.h
@@ -22,6 +22,8 @@
22#define KVM_DEV_FLIC_CLEAR_IRQS 3 22#define KVM_DEV_FLIC_CLEAR_IRQS 3
23#define KVM_DEV_FLIC_APF_ENABLE 4 23#define KVM_DEV_FLIC_APF_ENABLE 4
24#define KVM_DEV_FLIC_APF_DISABLE_WAIT 5 24#define KVM_DEV_FLIC_APF_DISABLE_WAIT 5
25#define KVM_DEV_FLIC_ADAPTER_REGISTER 6
26#define KVM_DEV_FLIC_ADAPTER_MODIFY 7
25/* 27/*
26 * We can have up to 4*64k pending subchannels + 8 adapter interrupts, 28 * We can have up to 4*64k pending subchannels + 8 adapter interrupts,
27 * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. 29 * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts.
@@ -32,6 +34,26 @@
32#define KVM_S390_MAX_FLOAT_IRQS 266250 34#define KVM_S390_MAX_FLOAT_IRQS 266250
33#define KVM_S390_FLIC_MAX_BUFFER 0x2000000 35#define KVM_S390_FLIC_MAX_BUFFER 0x2000000
34 36
37struct kvm_s390_io_adapter {
38 __u32 id;
39 __u8 isc;
40 __u8 maskable;
41 __u8 swap;
42 __u8 pad;
43};
44
45#define KVM_S390_IO_ADAPTER_MASK 1
46#define KVM_S390_IO_ADAPTER_MAP 2
47#define KVM_S390_IO_ADAPTER_UNMAP 3
48
49struct kvm_s390_io_adapter_req {
50 __u32 id;
51 __u8 type;
52 __u8 mask;
53 __u16 pad0;
54 __u64 addr;
55};
56
35/* for KVM_GET_REGS and KVM_SET_REGS */ 57/* for KVM_GET_REGS and KVM_SET_REGS */
36struct kvm_regs { 58struct kvm_regs {
37 /* general purpose regs for s390 */ 59 /* general purpose regs for s390 */
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index c8bacbcd2e5b..10d529ac9821 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -25,6 +25,8 @@ config KVM
25 select HAVE_KVM_EVENTFD 25 select HAVE_KVM_EVENTFD
26 select KVM_ASYNC_PF 26 select KVM_ASYNC_PF
27 select KVM_ASYNC_PF_SYNC 27 select KVM_ASYNC_PF_SYNC
28 select HAVE_KVM_IRQCHIP
29 select HAVE_KVM_IRQ_ROUTING
28 ---help--- 30 ---help---
29 Support hosting paravirtualized guest machines using the SIE 31 Support hosting paravirtualized guest machines using the SIE
30 virtualization capability on the mainframe. This should work 32 virtualization capability on the mainframe. This should work
diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile
index a47d2c355f68..d3adb37e93a4 100644
--- a/arch/s390/kvm/Makefile
+++ b/arch/s390/kvm/Makefile
@@ -7,7 +7,7 @@
7# as published by the Free Software Foundation. 7# as published by the Free Software Foundation.
8 8
9KVM := ../../../virt/kvm 9KVM := ../../../virt/kvm
10common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o 10common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o
11 11
12ccflags-y := -Ivirt/kvm -Iarch/s390/kvm 12ccflags-y := -Ivirt/kvm -Iarch/s390/kvm
13 13
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 79d2e4fa9f9c..2e2814eceb85 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * handling kvm guest interrupts 2 * handling kvm guest interrupts
3 * 3 *
4 * Copyright IBM Corp. 2008 4 * Copyright IBM Corp. 2008,2014
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -13,6 +13,7 @@
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/kvm_host.h> 14#include <linux/kvm_host.h>
15#include <linux/hrtimer.h> 15#include <linux/hrtimer.h>
16#include <linux/mmu_context.h>
16#include <linux/signal.h> 17#include <linux/signal.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
18#include <asm/asm-offsets.h> 19#include <asm/asm-offsets.h>
@@ -1054,6 +1055,171 @@ static int enqueue_floating_irq(struct kvm_device *dev,
1054 return r; 1055 return r;
1055} 1056}
1056 1057
1058static struct s390_io_adapter *get_io_adapter(struct kvm *kvm, unsigned int id)
1059{
1060 if (id >= MAX_S390_IO_ADAPTERS)
1061 return NULL;
1062 return kvm->arch.adapters[id];
1063}
1064
1065static int register_io_adapter(struct kvm_device *dev,
1066 struct kvm_device_attr *attr)
1067{
1068 struct s390_io_adapter *adapter;
1069 struct kvm_s390_io_adapter adapter_info;
1070
1071 if (copy_from_user(&adapter_info,
1072 (void __user *)attr->addr, sizeof(adapter_info)))
1073 return -EFAULT;
1074
1075 if ((adapter_info.id >= MAX_S390_IO_ADAPTERS) ||
1076 (dev->kvm->arch.adapters[adapter_info.id] != NULL))
1077 return -EINVAL;
1078
1079 adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
1080 if (!adapter)
1081 return -ENOMEM;
1082
1083 INIT_LIST_HEAD(&adapter->maps);
1084 init_rwsem(&adapter->maps_lock);
1085 atomic_set(&adapter->nr_maps, 0);
1086 adapter->id = adapter_info.id;
1087 adapter->isc = adapter_info.isc;
1088 adapter->maskable = adapter_info.maskable;
1089 adapter->masked = false;
1090 adapter->swap = adapter_info.swap;
1091 dev->kvm->arch.adapters[adapter->id] = adapter;
1092
1093 return 0;
1094}
1095
1096int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked)
1097{
1098 int ret;
1099 struct s390_io_adapter *adapter = get_io_adapter(kvm, id);
1100
1101 if (!adapter || !adapter->maskable)
1102 return -EINVAL;
1103 ret = adapter->masked;
1104 adapter->masked = masked;
1105 return ret;
1106}
1107
1108static int kvm_s390_adapter_map(struct kvm *kvm, unsigned int id, __u64 addr)
1109{
1110 struct s390_io_adapter *adapter = get_io_adapter(kvm, id);
1111 struct s390_map_info *map;
1112 int ret;
1113
1114 if (!adapter || !addr)
1115 return -EINVAL;
1116
1117 map = kzalloc(sizeof(*map), GFP_KERNEL);
1118 if (!map) {
1119 ret = -ENOMEM;
1120 goto out;
1121 }
1122 INIT_LIST_HEAD(&map->list);
1123 map->guest_addr = addr;
1124 map->addr = gmap_translate(addr, kvm->arch.gmap);
1125 if (map->addr == -EFAULT) {
1126 ret = -EFAULT;
1127 goto out;
1128 }
1129 ret = get_user_pages_fast(map->addr, 1, 1, &map->page);
1130 if (ret < 0)
1131 goto out;
1132 BUG_ON(ret != 1);
1133 down_write(&adapter->maps_lock);
1134 if (atomic_inc_return(&adapter->nr_maps) < MAX_S390_ADAPTER_MAPS) {
1135 list_add_tail(&map->list, &adapter->maps);
1136 ret = 0;
1137 } else {
1138 put_page(map->page);
1139 ret = -EINVAL;
1140 }
1141 up_write(&adapter->maps_lock);
1142out:
1143 if (ret)
1144 kfree(map);
1145 return ret;
1146}
1147
1148static int kvm_s390_adapter_unmap(struct kvm *kvm, unsigned int id, __u64 addr)
1149{
1150 struct s390_io_adapter *adapter = get_io_adapter(kvm, id);
1151 struct s390_map_info *map, *tmp;
1152 int found = 0;
1153
1154 if (!adapter || !addr)
1155 return -EINVAL;
1156
1157 down_write(&adapter->maps_lock);
1158 list_for_each_entry_safe(map, tmp, &adapter->maps, list) {
1159 if (map->guest_addr == addr) {
1160 found = 1;
1161 atomic_dec(&adapter->nr_maps);
1162 list_del(&map->list);
1163 put_page(map->page);
1164 kfree(map);
1165 break;
1166 }
1167 }
1168 up_write(&adapter->maps_lock);
1169
1170 return found ? 0 : -EINVAL;
1171}
1172
1173void kvm_s390_destroy_adapters(struct kvm *kvm)
1174{
1175 int i;
1176 struct s390_map_info *map, *tmp;
1177
1178 for (i = 0; i < MAX_S390_IO_ADAPTERS; i++) {
1179 if (!kvm->arch.adapters[i])
1180 continue;
1181 list_for_each_entry_safe(map, tmp,
1182 &kvm->arch.adapters[i]->maps, list) {
1183 list_del(&map->list);
1184 put_page(map->page);
1185 kfree(map);
1186 }
1187 kfree(kvm->arch.adapters[i]);
1188 }
1189}
1190
1191static int modify_io_adapter(struct kvm_device *dev,
1192 struct kvm_device_attr *attr)
1193{
1194 struct kvm_s390_io_adapter_req req;
1195 struct s390_io_adapter *adapter;
1196 int ret;
1197
1198 if (copy_from_user(&req, (void __user *)attr->addr, sizeof(req)))
1199 return -EFAULT;
1200
1201 adapter = get_io_adapter(dev->kvm, req.id);
1202 if (!adapter)
1203 return -EINVAL;
1204 switch (req.type) {
1205 case KVM_S390_IO_ADAPTER_MASK:
1206 ret = kvm_s390_mask_adapter(dev->kvm, req.id, req.mask);
1207 if (ret > 0)
1208 ret = 0;
1209 break;
1210 case KVM_S390_IO_ADAPTER_MAP:
1211 ret = kvm_s390_adapter_map(dev->kvm, req.id, req.addr);
1212 break;
1213 case KVM_S390_IO_ADAPTER_UNMAP:
1214 ret = kvm_s390_adapter_unmap(dev->kvm, req.id, req.addr);
1215 break;
1216 default:
1217 ret = -EINVAL;
1218 }
1219
1220 return ret;
1221}
1222
1057static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) 1223static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
1058{ 1224{
1059 int r = 0; 1225 int r = 0;
@@ -1082,6 +1248,12 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
1082 kvm_for_each_vcpu(i, vcpu, dev->kvm) 1248 kvm_for_each_vcpu(i, vcpu, dev->kvm)
1083 kvm_clear_async_pf_completion_queue(vcpu); 1249 kvm_clear_async_pf_completion_queue(vcpu);
1084 break; 1250 break;
1251 case KVM_DEV_FLIC_ADAPTER_REGISTER:
1252 r = register_io_adapter(dev, attr);
1253 break;
1254 case KVM_DEV_FLIC_ADAPTER_MODIFY:
1255 r = modify_io_adapter(dev, attr);
1256 break;
1085 default: 1257 default:
1086 r = -EINVAL; 1258 r = -EINVAL;
1087 } 1259 }
@@ -1113,3 +1285,123 @@ struct kvm_device_ops kvm_flic_ops = {
1113 .create = flic_create, 1285 .create = flic_create,
1114 .destroy = flic_destroy, 1286 .destroy = flic_destroy,
1115}; 1287};
1288
1289static unsigned long get_ind_bit(__u64 addr, unsigned long bit_nr, bool swap)
1290{
1291 unsigned long bit;
1292
1293 bit = bit_nr + (addr % PAGE_SIZE) * 8;
1294
1295 return swap ? (bit ^ (BITS_PER_LONG - 1)) : bit;
1296}
1297
1298static struct s390_map_info *get_map_info(struct s390_io_adapter *adapter,
1299 u64 addr)
1300{
1301 struct s390_map_info *map;
1302
1303 if (!adapter)
1304 return NULL;
1305
1306 list_for_each_entry(map, &adapter->maps, list) {
1307 if (map->guest_addr == addr)
1308 return map;
1309 }
1310 return NULL;
1311}
1312
1313static int adapter_indicators_set(struct kvm *kvm,
1314 struct s390_io_adapter *adapter,
1315 struct kvm_s390_adapter_int *adapter_int)
1316{
1317 unsigned long bit;
1318 int summary_set, idx;
1319 struct s390_map_info *info;
1320 void *map;
1321
1322 info = get_map_info(adapter, adapter_int->ind_addr);
1323 if (!info)
1324 return -1;
1325 map = page_address(info->page);
1326 bit = get_ind_bit(info->addr, adapter_int->ind_offset, adapter->swap);
1327 set_bit(bit, map);
1328 idx = srcu_read_lock(&kvm->srcu);
1329 mark_page_dirty(kvm, info->guest_addr >> PAGE_SHIFT);
1330 set_page_dirty_lock(info->page);
1331 info = get_map_info(adapter, adapter_int->summary_addr);
1332 if (!info) {
1333 srcu_read_unlock(&kvm->srcu, idx);
1334 return -1;
1335 }
1336 map = page_address(info->page);
1337 bit = get_ind_bit(info->addr, adapter_int->summary_offset,
1338 adapter->swap);
1339 summary_set = test_and_set_bit(bit, map);
1340 mark_page_dirty(kvm, info->guest_addr >> PAGE_SHIFT);
1341 set_page_dirty_lock(info->page);
1342 srcu_read_unlock(&kvm->srcu, idx);
1343 return summary_set ? 0 : 1;
1344}
1345
1346/*
1347 * < 0 - not injected due to error
1348 * = 0 - coalesced, summary indicator already active
1349 * > 0 - injected interrupt
1350 */
1351static int set_adapter_int(struct kvm_kernel_irq_routing_entry *e,
1352 struct kvm *kvm, int irq_source_id, int level,
1353 bool line_status)
1354{
1355 int ret;
1356 struct s390_io_adapter *adapter;
1357
1358 /* We're only interested in the 0->1 transition. */
1359 if (!level)
1360 return 0;
1361 adapter = get_io_adapter(kvm, e->adapter.adapter_id);
1362 if (!adapter)
1363 return -1;
1364 down_read(&adapter->maps_lock);
1365 ret = adapter_indicators_set(kvm, adapter, &e->adapter);
1366 up_read(&adapter->maps_lock);
1367 if ((ret > 0) && !adapter->masked) {
1368 struct kvm_s390_interrupt s390int = {
1369 .type = KVM_S390_INT_IO(1, 0, 0, 0),
1370 .parm = 0,
1371 .parm64 = (adapter->isc << 27) | 0x80000000,
1372 };
1373 ret = kvm_s390_inject_vm(kvm, &s390int);
1374 if (ret == 0)
1375 ret = 1;
1376 }
1377 return ret;
1378}
1379
1380int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
1381 struct kvm_kernel_irq_routing_entry *e,
1382 const struct kvm_irq_routing_entry *ue)
1383{
1384 int ret;
1385
1386 switch (ue->type) {
1387 case KVM_IRQ_ROUTING_S390_ADAPTER:
1388 e->set = set_adapter_int;
1389 e->adapter.summary_addr = ue->u.adapter.summary_addr;
1390 e->adapter.ind_addr = ue->u.adapter.ind_addr;
1391 e->adapter.summary_offset = ue->u.adapter.summary_offset;
1392 e->adapter.ind_offset = ue->u.adapter.ind_offset;
1393 e->adapter.adapter_id = ue->u.adapter.adapter_id;
1394 ret = 0;
1395 break;
1396 default:
1397 ret = -EINVAL;
1398 }
1399
1400 return ret;
1401}
1402
1403int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm,
1404 int irq_source_id, int level, bool line_status)
1405{
1406 return -EINVAL;
1407}
diff --git a/arch/s390/kvm/irq.h b/arch/s390/kvm/irq.h
new file mode 100644
index 000000000000..d98e4159643d
--- /dev/null
+++ b/arch/s390/kvm/irq.h
@@ -0,0 +1,22 @@
1/*
2 * s390 irqchip routines
3 *
4 * Copyright IBM Corp. 2014
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only)
8 * as published by the Free Software Foundation.
9 *
10 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
11 */
12#ifndef __KVM_IRQ_H
13#define __KVM_IRQ_H
14
15#include <linux/kvm_host.h>
16
17static inline int irqchip_in_kernel(struct kvm *kvm)
18{
19 return 1;
20}
21
22#endif
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 7337c577e949..ce5b659ec531 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -159,6 +159,7 @@ int kvm_dev_ioctl_check_extension(long ext)
159 case KVM_CAP_S390_CSS_SUPPORT: 159 case KVM_CAP_S390_CSS_SUPPORT:
160 case KVM_CAP_IOEVENTFD: 160 case KVM_CAP_IOEVENTFD:
161 case KVM_CAP_DEVICE_CTRL: 161 case KVM_CAP_DEVICE_CTRL:
162 case KVM_CAP_ENABLE_CAP_VM:
162 r = 1; 163 r = 1;
163 break; 164 break;
164 case KVM_CAP_NR_VCPUS: 165 case KVM_CAP_NR_VCPUS:
@@ -187,6 +188,25 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
187 return 0; 188 return 0;
188} 189}
189 190
191static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
192{
193 int r;
194
195 if (cap->flags)
196 return -EINVAL;
197
198 switch (cap->cap) {
199 case KVM_CAP_S390_IRQCHIP:
200 kvm->arch.use_irqchip = 1;
201 r = 0;
202 break;
203 default:
204 r = -EINVAL;
205 break;
206 }
207 return r;
208}
209
190long kvm_arch_vm_ioctl(struct file *filp, 210long kvm_arch_vm_ioctl(struct file *filp,
191 unsigned int ioctl, unsigned long arg) 211 unsigned int ioctl, unsigned long arg)
192{ 212{
@@ -204,6 +224,26 @@ long kvm_arch_vm_ioctl(struct file *filp,
204 r = kvm_s390_inject_vm(kvm, &s390int); 224 r = kvm_s390_inject_vm(kvm, &s390int);
205 break; 225 break;
206 } 226 }
227 case KVM_ENABLE_CAP: {
228 struct kvm_enable_cap cap;
229 r = -EFAULT;
230 if (copy_from_user(&cap, argp, sizeof(cap)))
231 break;
232 r = kvm_vm_ioctl_enable_cap(kvm, &cap);
233 break;
234 }
235 case KVM_CREATE_IRQCHIP: {
236 struct kvm_irq_routing_entry routing;
237
238 r = -EINVAL;
239 if (kvm->arch.use_irqchip) {
240 /* Set up dummy routing. */
241 memset(&routing, 0, sizeof(routing));
242 kvm_set_irq_routing(kvm, &routing, 0, 0);
243 r = 0;
244 }
245 break;
246 }
207 default: 247 default:
208 r = -ENOTTY; 248 r = -ENOTTY;
209 } 249 }
@@ -260,6 +300,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
260 } 300 }
261 301
262 kvm->arch.css_support = 0; 302 kvm->arch.css_support = 0;
303 kvm->arch.use_irqchip = 0;
263 304
264 return 0; 305 return 0;
265out_nogmap: 306out_nogmap:
@@ -319,6 +360,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
319 debug_unregister(kvm->arch.dbf); 360 debug_unregister(kvm->arch.dbf);
320 if (!kvm_is_ucontrol(kvm)) 361 if (!kvm_is_ucontrol(kvm))
321 gmap_free(kvm->arch.gmap); 362 gmap_free(kvm->arch.gmap);
363 kvm_s390_destroy_adapters(kvm);
322} 364}
323 365
324/* Section: vcpu related */ 366/* Section: vcpu related */
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index ed4750a5bc3c..5502cc951868 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -136,6 +136,7 @@ int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
136int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); 136int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
137struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, 137struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm,
138 u64 cr6, u64 schid); 138 u64 cr6, u64 schid);
139int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked);
139 140
140/* implemented in priv.c */ 141/* implemented in priv.c */
141int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); 142int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
@@ -162,5 +163,6 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu);
162/* implemented in interrupt.c */ 163/* implemented in interrupt.c */
163int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); 164int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu);
164int psw_extint_disabled(struct kvm_vcpu *vcpu); 165int psw_extint_disabled(struct kvm_vcpu *vcpu);
166void kvm_s390_destroy_adapters(struct kvm *kvm);
165 167
166#endif 168#endif
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 9816b68b085f..7d21cf9f4380 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -297,6 +297,14 @@ static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memsl
297 return ALIGN(memslot->npages, BITS_PER_LONG) / 8; 297 return ALIGN(memslot->npages, BITS_PER_LONG) / 8;
298} 298}
299 299
300struct kvm_s390_adapter_int {
301 u64 ind_addr;
302 u64 summary_addr;
303 u64 ind_offset;
304 u32 summary_offset;
305 u32 adapter_id;
306};
307
300struct kvm_kernel_irq_routing_entry { 308struct kvm_kernel_irq_routing_entry {
301 u32 gsi; 309 u32 gsi;
302 u32 type; 310 u32 type;
@@ -309,6 +317,7 @@ struct kvm_kernel_irq_routing_entry {
309 unsigned pin; 317 unsigned pin;
310 } irqchip; 318 } irqchip;
311 struct msi_msg msi; 319 struct msi_msg msi;
320 struct kvm_s390_adapter_int adapter;
312 }; 321 };
313 struct hlist_node link; 322 struct hlist_node link;
314}; 323};
@@ -913,7 +922,11 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)
913 922
914#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING 923#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
915 924
925#ifdef CONFIG_S390
926#define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that...
927#else
916#define KVM_MAX_IRQ_ROUTES 1024 928#define KVM_MAX_IRQ_ROUTES 1024
929#endif
917 930
918int kvm_setup_default_irq_routing(struct kvm *kvm); 931int kvm_setup_default_irq_routing(struct kvm *kvm);
919int kvm_set_irq_routing(struct kvm *kvm, 932int kvm_set_irq_routing(struct kvm *kvm,
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index a7518be31d53..a8f4ee5d2e82 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -741,6 +741,8 @@ struct kvm_ppc_smmu_info {
741#define KVM_CAP_EXT_EMUL_CPUID 95 741#define KVM_CAP_EXT_EMUL_CPUID 95
742#define KVM_CAP_HYPERV_TIME 96 742#define KVM_CAP_HYPERV_TIME 96
743#define KVM_CAP_IOAPIC_POLARITY_IGNORED 97 743#define KVM_CAP_IOAPIC_POLARITY_IGNORED 97
744#define KVM_CAP_ENABLE_CAP_VM 98
745#define KVM_CAP_S390_IRQCHIP 99
744 746
745#ifdef KVM_CAP_IRQ_ROUTING 747#ifdef KVM_CAP_IRQ_ROUTING
746 748
@@ -756,9 +758,18 @@ struct kvm_irq_routing_msi {
756 __u32 pad; 758 __u32 pad;
757}; 759};
758 760
761struct kvm_irq_routing_s390_adapter {
762 __u64 ind_addr;
763 __u64 summary_addr;
764 __u64 ind_offset;
765 __u32 summary_offset;
766 __u32 adapter_id;
767};
768
759/* gsi routing entry types */ 769/* gsi routing entry types */
760#define KVM_IRQ_ROUTING_IRQCHIP 1 770#define KVM_IRQ_ROUTING_IRQCHIP 1
761#define KVM_IRQ_ROUTING_MSI 2 771#define KVM_IRQ_ROUTING_MSI 2
772#define KVM_IRQ_ROUTING_S390_ADAPTER 3
762 773
763struct kvm_irq_routing_entry { 774struct kvm_irq_routing_entry {
764 __u32 gsi; 775 __u32 gsi;
@@ -768,6 +779,7 @@ struct kvm_irq_routing_entry {
768 union { 779 union {
769 struct kvm_irq_routing_irqchip irqchip; 780 struct kvm_irq_routing_irqchip irqchip;
770 struct kvm_irq_routing_msi msi; 781 struct kvm_irq_routing_msi msi;
782 struct kvm_irq_routing_s390_adapter adapter;
771 __u32 pad[8]; 783 __u32 pad[8];
772 } u; 784 } u;
773}; 785};
@@ -1076,6 +1088,10 @@ struct kvm_s390_ucas_mapping {
1076/* Available with KVM_CAP_DEBUGREGS */ 1088/* Available with KVM_CAP_DEBUGREGS */
1077#define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) 1089#define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs)
1078#define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) 1090#define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs)
1091/*
1092 * vcpu version available with KVM_ENABLE_CAP
1093 * vm version available with KVM_CAP_ENABLE_CAP_VM
1094 */
1079#define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) 1095#define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap)
1080/* Available with KVM_CAP_XSAVE */ 1096/* Available with KVM_CAP_XSAVE */
1081#define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave) 1097#define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave)