diff options
| -rw-r--r-- | Documentation/virtual/kvm/api.txt | 27 | ||||
| -rw-r--r-- | Documentation/virtual/kvm/devices/s390_flic.txt | 45 | ||||
| -rw-r--r-- | arch/s390/include/asm/kvm_host.h | 32 | ||||
| -rw-r--r-- | arch/s390/include/uapi/asm/kvm.h | 22 | ||||
| -rw-r--r-- | arch/s390/kvm/Kconfig | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/Makefile | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 294 | ||||
| -rw-r--r-- | arch/s390/kvm/irq.h | 22 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 42 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.h | 2 | ||||
| -rw-r--r-- | include/linux/kvm_host.h | 13 | ||||
| -rw-r--r-- | include/uapi/linux/kvm.h | 16 |
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 | ||
| 587 | 4.24 KVM_CREATE_IRQCHIP | 587 | 4.24 KVM_CREATE_IRQCHIP |
| 588 | 588 | ||
| 589 | Capability: KVM_CAP_IRQCHIP | 589 | Capability: KVM_CAP_IRQCHIP, KVM_CAP_S390_IRQCHIP (s390) |
| 590 | Architectures: x86, ia64, ARM, arm64 | 590 | Architectures: x86, ia64, ARM, arm64, s390 |
| 591 | Type: vm ioctl | 591 | Type: vm ioctl |
| 592 | Parameters: none | 592 | Parameters: none |
| 593 | Returns: 0 on success, -1 on error | 593 | Returns: 0 on success, -1 on error |
| @@ -596,7 +596,10 @@ Creates an interrupt controller model in the kernel. On x86, creates a virtual | |||
| 596 | ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a | 596 | ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a |
| 597 | local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23 | 597 | local APIC. IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23 |
| 598 | only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM/arm64, a GIC is | 598 | only go to the IOAPIC. On ia64, a IOSAPIC is created. On ARM/arm64, a GIC is |
| 599 | created. | 599 | created. On s390, a dummy irq routing table is created. |
| 600 | |||
| 601 | Note that on s390 the KVM_CAP_S390_IRQCHIP vm capability needs to be enabled | ||
| 602 | before KVM_CREATE_IRQCHIP can be used. | ||
| 600 | 603 | ||
| 601 | 604 | ||
| 602 | 4.25 KVM_IRQ_LINE | 605 | 4.25 KVM_IRQ_LINE |
| @@ -932,9 +935,9 @@ documentation when it pops into existence). | |||
| 932 | 935 | ||
| 933 | 4.37 KVM_ENABLE_CAP | 936 | 4.37 KVM_ENABLE_CAP |
| 934 | 937 | ||
| 935 | Capability: KVM_CAP_ENABLE_CAP | 938 | Capability: KVM_CAP_ENABLE_CAP, KVM_CAP_ENABLE_CAP_VM |
| 936 | Architectures: ppc, s390 | 939 | Architectures: ppc, s390 |
| 937 | Type: vcpu ioctl | 940 | Type: vcpu ioctl, vm ioctl (with KVM_CAP_ENABLE_CAP_VM) |
| 938 | Parameters: struct kvm_enable_cap (in) | 941 | Parameters: struct kvm_enable_cap (in) |
| 939 | Returns: 0 on success; -1 on error | 942 | Returns: 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 | ||
| 971 | The vcpu ioctl should be used for vcpu-specific capabilities, the vm ioctl | ||
| 972 | for vm-wide capabilities. | ||
| 968 | 973 | ||
| 969 | 4.38 KVM_GET_MP_STATE | 974 | 4.38 KVM_GET_MP_STATE |
| 970 | 975 | ||
| @@ -1334,7 +1339,7 @@ KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed. | |||
| 1334 | 4.52 KVM_SET_GSI_ROUTING | 1339 | 4.52 KVM_SET_GSI_ROUTING |
| 1335 | 1340 | ||
| 1336 | Capability: KVM_CAP_IRQ_ROUTING | 1341 | Capability: KVM_CAP_IRQ_ROUTING |
| 1337 | Architectures: x86 ia64 | 1342 | Architectures: x86 ia64 s390 |
| 1338 | Type: vm ioctl | 1343 | Type: vm ioctl |
| 1339 | Parameters: struct kvm_irq_routing (in) | 1344 | Parameters: struct kvm_irq_routing (in) |
| 1340 | Returns: 0 on success, -1 on error | 1345 | Returns: 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 | ||
| 1368 | No flags are specified so far, the corresponding field must be set to zero. | 1375 | No 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 | ||
| 1389 | struct 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 | ||
| 1383 | 4.53 KVM_ASSIGN_SET_MSIX_NR | 1398 | 4.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 | ||
| 16 | Groups: | 17 | Groups: |
| 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 | |||
| 53 | struct 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 | |||
| 70 | struct 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 | |||
| 26 | struct sca_entry { | 35 | struct sca_entry { |
| 27 | atomic_t scn; | 36 | atomic_t scn; |
| 28 | __u32 reserved; | 37 | __u32 reserved; |
| @@ -245,6 +254,27 @@ struct kvm_vm_stat { | |||
| 245 | struct kvm_arch_memory_slot { | 254 | struct kvm_arch_memory_slot { |
| 246 | }; | 255 | }; |
| 247 | 256 | ||
| 257 | struct s390_map_info { | ||
| 258 | struct list_head list; | ||
| 259 | __u64 guest_addr; | ||
| 260 | __u64 addr; | ||
| 261 | struct page *page; | ||
| 262 | }; | ||
| 263 | |||
| 264 | struct 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 | |||
| 248 | struct kvm_arch{ | 278 | struct 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 | ||
| 37 | struct 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 | |||
| 49 | struct 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 */ |
| 36 | struct kvm_regs { | 58 | struct 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 | ||
| 9 | KVM := ../../../virt/kvm | 9 | KVM := ../../../virt/kvm |
| 10 | common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o | 10 | common-objs = $(KVM)/kvm_main.o $(KVM)/eventfd.o $(KVM)/async_pf.o $(KVM)/irqchip.o |
| 11 | 11 | ||
| 12 | ccflags-y := -Ivirt/kvm -Iarch/s390/kvm | 12 | ccflags-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 | ||
| 1058 | static 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 | |||
| 1065 | static 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 | |||
| 1096 | int 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 | |||
| 1108 | static 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); | ||
| 1142 | out: | ||
| 1143 | if (ret) | ||
| 1144 | kfree(map); | ||
| 1145 | return ret; | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | static 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 | |||
| 1173 | void 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 | |||
| 1191 | static 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 | |||
| 1057 | static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) | 1223 | static 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 | |||
| 1289 | static 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 | |||
| 1298 | static 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 | |||
| 1313 | static 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 | */ | ||
| 1351 | static 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 | |||
| 1380 | int 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 | |||
| 1403 | int 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 | |||
| 17 | static 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 | ||
| 191 | static 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 | |||
| 190 | long kvm_arch_vm_ioctl(struct file *filp, | 210 | long 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; |
| 265 | out_nogmap: | 306 | out_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, | |||
| 136 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); | 136 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); |
| 137 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, | 137 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, |
| 138 | u64 cr6, u64 schid); | 138 | u64 cr6, u64 schid); |
| 139 | int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked); | ||
| 139 | 140 | ||
| 140 | /* implemented in priv.c */ | 141 | /* implemented in priv.c */ |
| 141 | int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); | 142 | int 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 */ |
| 163 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); | 164 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); |
| 164 | int psw_extint_disabled(struct kvm_vcpu *vcpu); | 165 | int psw_extint_disabled(struct kvm_vcpu *vcpu); |
| 166 | void 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 | ||
| 300 | struct 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 | |||
| 300 | struct kvm_kernel_irq_routing_entry { | 308 | struct 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 | ||
| 918 | int kvm_setup_default_irq_routing(struct kvm *kvm); | 931 | int kvm_setup_default_irq_routing(struct kvm *kvm); |
| 919 | int kvm_set_irq_routing(struct kvm *kvm, | 932 | int 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 | ||
| 761 | struct 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 | ||
| 763 | struct kvm_irq_routing_entry { | 774 | struct 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) |
