aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2013-07-15 07:36:01 -0400
committerCornelia Huck <cornelia.huck@de.ibm.com>2014-03-21 08:42:49 -0400
commit841b91c584b6d1e2a2cb508bd2d0236cd37e1750 (patch)
tree0a2f1b2cfa471cefa22bc9c12628361ed2c0ac4c
parentd938dc55225a7212e7f31c5a8571da304cc3de16 (diff)
KVM: s390: adapter interrupt sources
Add a new interface to register/deregister sources of adapter interrupts identified by an unique id via the flic. Adapters may also be maskable and carry a list of pinned pages. These adapters will be used by irq routing later. Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
-rw-r--r--Documentation/virtual/kvm/devices/s390_flic.txt45
-rw-r--r--arch/s390/include/asm/kvm_host.h23
-rw-r--r--arch/s390/include/uapi/asm/kvm.h22
-rw-r--r--arch/s390/kvm/interrupt.c173
-rw-r--r--arch/s390/kvm/kvm-s390.c1
-rw-r--r--arch/s390/kvm/kvm-s390.h2
6 files changed, 265 insertions, 1 deletions
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..0d5235262707 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -19,6 +19,7 @@
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
@@ -245,6 +246,27 @@ struct kvm_vm_stat {
245struct kvm_arch_memory_slot { 246struct kvm_arch_memory_slot {
246}; 247};
247 248
249struct s390_map_info {
250 struct list_head list;
251 __u64 guest_addr;
252 __u64 addr;
253 struct page *page;
254};
255
256struct s390_io_adapter {
257 unsigned int id;
258 int isc;
259 bool maskable;
260 bool masked;
261 bool swap;
262 struct rw_semaphore maps_lock;
263 struct list_head maps;
264 atomic_t nr_maps;
265};
266
267#define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8)
268#define MAX_S390_ADAPTER_MAPS 256
269
248struct kvm_arch{ 270struct kvm_arch{
249 struct sca_block *sca; 271 struct sca_block *sca;
250 debug_info_t *dbf; 272 debug_info_t *dbf;
@@ -252,6 +274,7 @@ struct kvm_arch{
252 struct kvm_device *flic; 274 struct kvm_device *flic;
253 struct gmap *gmap; 275 struct gmap *gmap;
254 int css_support; 276 int css_support;
277 struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS];
255}; 278};
256 279
257#define KVM_HVA_ERR_BAD (-1UL) 280#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/interrupt.c b/arch/s390/kvm/interrupt.c
index 79d2e4fa9f9c..7ecef5a18e25 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)
@@ -1054,6 +1054,171 @@ static int enqueue_floating_irq(struct kvm_device *dev,
1054 return r; 1054 return r;
1055} 1055}
1056 1056
1057static struct s390_io_adapter *get_io_adapter(struct kvm *kvm, unsigned int id)
1058{
1059 if (id >= MAX_S390_IO_ADAPTERS)
1060 return NULL;
1061 return kvm->arch.adapters[id];
1062}
1063
1064static int register_io_adapter(struct kvm_device *dev,
1065 struct kvm_device_attr *attr)
1066{
1067 struct s390_io_adapter *adapter;
1068 struct kvm_s390_io_adapter adapter_info;
1069
1070 if (copy_from_user(&adapter_info,
1071 (void __user *)attr->addr, sizeof(adapter_info)))
1072 return -EFAULT;
1073
1074 if ((adapter_info.id >= MAX_S390_IO_ADAPTERS) ||
1075 (dev->kvm->arch.adapters[adapter_info.id] != NULL))
1076 return -EINVAL;
1077
1078 adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);