Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'vfio-ccw-for-martin' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/vfio-ccw into features

Pull vfio-ccw branch to add the basic channel I/O passthrough
intrastructure based on vfio.

The focus is on supporting dasd-eckd(cu_type/dev_type = 0x3990/0x3390)
as the target device.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

+2417 -46
+2
Documentation/s390/00-INDEX
··· 22 22 - HiperSockets Bridge Port Support. 23 23 s390dbf.txt 24 24 - information on using the s390 debug feature. 25 + vfio-ccw.txt 26 + information on the vfio-ccw I/O subchannel driver. 25 27 zfcpdump.txt 26 28 - information on the s390 SCSI dump tool.
+303
Documentation/s390/vfio-ccw.txt
··· 1 + vfio-ccw: the basic infrastructure 2 + ================================== 3 + 4 + Introduction 5 + ------------ 6 + 7 + Here we describe the vfio support for I/O subchannel devices for 8 + Linux/s390. Motivation for vfio-ccw is to passthrough subchannels to a 9 + virtual machine, while vfio is the means. 10 + 11 + Different than other hardware architectures, s390 has defined a unified 12 + I/O access method, which is so called Channel I/O. It has its own access 13 + patterns: 14 + - Channel programs run asynchronously on a separate (co)processor. 15 + - The channel subsystem will access any memory designated by the caller 16 + in the channel program directly, i.e. there is no iommu involved. 17 + Thus when we introduce vfio support for these devices, we realize it 18 + with a mediated device (mdev) implementation. The vfio mdev will be 19 + added to an iommu group, so as to make itself able to be managed by the 20 + vfio framework. And we add read/write callbacks for special vfio I/O 21 + regions to pass the channel programs from the mdev to its parent device 22 + (the real I/O subchannel device) to do further address translation and 23 + to perform I/O instructions. 24 + 25 + This document does not intend to explain the s390 I/O architecture in 26 + every detail. More information/reference could be found here: 27 + - A good start to know Channel I/O in general: 28 + https://en.wikipedia.org/wiki/Channel_I/O 29 + - s390 architecture: 30 + s390 Principles of Operation manual (IBM Form. No. SA22-7832) 31 + - The existing Qemu code which implements a simple emulated channel 32 + subsystem could also be a good reference. It makes it easier to follow 33 + the flow. 34 + qemu/hw/s390x/css.c 35 + 36 + For vfio mediated device framework: 37 + - Documentation/vfio-mediated-device.txt 38 + 39 + Motivation of vfio-ccw 40 + ---------------------- 41 + 42 + Currently, a guest virtualized via qemu/kvm on s390 only sees 43 + paravirtualized virtio devices via the "Virtio Over Channel I/O 44 + (virtio-ccw)" transport. This makes virtio devices discoverable via 45 + standard operating system algorithms for handling channel devices. 46 + 47 + However this is not enough. On s390 for the majority of devices, which 48 + use the standard Channel I/O based mechanism, we also need to provide 49 + the functionality of passing through them to a Qemu virtual machine. 50 + This includes devices that don't have a virtio counterpart (e.g. tape 51 + drives) or that have specific characteristics which guests want to 52 + exploit. 53 + 54 + For passing a device to a guest, we want to use the same interface as 55 + everybody else, namely vfio. Thus, we would like to introduce vfio 56 + support for channel devices. And we would like to name this new vfio 57 + device "vfio-ccw". 58 + 59 + Access patterns of CCW devices 60 + ------------------------------ 61 + 62 + s390 architecture has implemented a so called channel subsystem, that 63 + provides a unified view of the devices physically attached to the 64 + systems. Though the s390 hardware platform knows about a huge variety of 65 + different peripheral attachments like disk devices (aka. DASDs), tapes, 66 + communication controllers, etc. They can all be accessed by a well 67 + defined access method and they are presenting I/O completion a unified 68 + way: I/O interruptions. 69 + 70 + All I/O requires the use of channel command words (CCWs). A CCW is an 71 + instruction to a specialized I/O channel processor. A channel program is 72 + a sequence of CCWs which are executed by the I/O channel subsystem. To 73 + issue a channel program to the channel subsystem, it is required to 74 + build an operation request block (ORB), which can be used to point out 75 + the format of the CCW and other control information to the system. The 76 + operating system signals the I/O channel subsystem to begin executing 77 + the channel program with a SSCH (start sub-channel) instruction. The 78 + central processor is then free to proceed with non-I/O instructions 79 + until interrupted. The I/O completion result is received by the 80 + interrupt handler in the form of interrupt response block (IRB). 81 + 82 + Back to vfio-ccw, in short: 83 + - ORBs and channel programs are built in guest kernel (with guest 84 + physical addresses). 85 + - ORBs and channel programs are passed to the host kernel. 86 + - Host kernel translates the guest physical addresses to real addresses 87 + and starts the I/O with issuing a privileged Channel I/O instruction 88 + (e.g SSCH). 89 + - channel programs run asynchronously on a separate processor. 90 + - I/O completion will be signaled to the host with I/O interruptions. 91 + And it will be copied as IRB to user space to pass it back to the 92 + guest. 93 + 94 + Physical vfio ccw device and its child mdev 95 + ------------------------------------------- 96 + 97 + As mentioned above, we realize vfio-ccw with a mdev implementation. 98 + 99 + Channel I/O does not have IOMMU hardware support, so the physical 100 + vfio-ccw device does not have an IOMMU level translation or isolation. 101 + 102 + Sub-channel I/O instructions are all privileged instructions, When 103 + handling the I/O instruction interception, vfio-ccw has the software 104 + policing and translation how the channel program is programmed before 105 + it gets sent to hardware. 106 + 107 + Within this implementation, we have two drivers for two types of 108 + devices: 109 + - The vfio_ccw driver for the physical subchannel device. 110 + This is an I/O subchannel driver for the real subchannel device. It 111 + realizes a group of callbacks and registers to the mdev framework as a 112 + parent (physical) device. As a consequence, mdev provides vfio_ccw a 113 + generic interface (sysfs) to create mdev devices. A vfio mdev could be 114 + created by vfio_ccw then and added to the mediated bus. It is the vfio 115 + device that added to an IOMMU group and a vfio group. 116 + vfio_ccw also provides an I/O region to accept channel program 117 + request from user space and store I/O interrupt result for user 118 + space to retrieve. To notify user space an I/O completion, it offers 119 + an interface to setup an eventfd fd for asynchronous signaling. 120 + 121 + - The vfio_mdev driver for the mediated vfio ccw device. 122 + This is provided by the mdev framework. It is a vfio device driver for 123 + the mdev that created by vfio_ccw. 124 + It realize a group of vfio device driver callbacks, adds itself to a 125 + vfio group, and registers itself to the mdev framework as a mdev 126 + driver. 127 + It uses a vfio iommu backend that uses the existing map and unmap 128 + ioctls, but rather than programming them into an IOMMU for a device, 129 + it simply stores the translations for use by later requests. This 130 + means that a device programmed in a VM with guest physical addresses 131 + can have the vfio kernel convert that address to process virtual 132 + address, pin the page and program the hardware with the host physical 133 + address in one step. 134 + For a mdev, the vfio iommu backend will not pin the pages during the 135 + VFIO_IOMMU_MAP_DMA ioctl. Mdev framework will only maintain a database 136 + of the iova<->vaddr mappings in this operation. And they export a 137 + vfio_pin_pages and a vfio_unpin_pages interfaces from the vfio iommu 138 + backend for the physical devices to pin and unpin pages by demand. 139 + 140 + Below is a high Level block diagram. 141 + 142 + +-------------+ 143 + | | 144 + | +---------+ | mdev_register_driver() +--------------+ 145 + | | Mdev | +<-----------------------+ | 146 + | | bus | | | vfio_mdev.ko | 147 + | | driver | +----------------------->+ |<-> VFIO user 148 + | +---------+ | probe()/remove() +--------------+ APIs 149 + | | 150 + | MDEV CORE | 151 + | MODULE | 152 + | mdev.ko | 153 + | +---------+ | mdev_register_device() +--------------+ 154 + | |Physical | +<-----------------------+ | 155 + | | device | | | vfio_ccw.ko |<-> subchannel 156 + | |interface| +----------------------->+ | device 157 + | +---------+ | callback +--------------+ 158 + +-------------+ 159 + 160 + The process of how these work together. 161 + 1. vfio_ccw.ko drives the physical I/O subchannel, and registers the 162 + physical device (with callbacks) to mdev framework. 163 + When vfio_ccw probing the subchannel device, it registers device 164 + pointer and callbacks to the mdev framework. Mdev related file nodes 165 + under the device node in sysfs would be created for the subchannel 166 + device, namely 'mdev_create', 'mdev_destroy' and 167 + 'mdev_supported_types'. 168 + 2. Create a mediated vfio ccw device. 169 + Use the 'mdev_create' sysfs file, we need to manually create one (and 170 + only one for our case) mediated device. 171 + 3. vfio_mdev.ko drives the mediated ccw device. 172 + vfio_mdev is also the vfio device drvier. It will probe the mdev and 173 + add it to an iommu_group and a vfio_group. Then we could pass through 174 + the mdev to a guest. 175 + 176 + vfio-ccw I/O region 177 + ------------------- 178 + 179 + An I/O region is used to accept channel program request from user 180 + space and store I/O interrupt result for user space to retrieve. The 181 + defination of the region is: 182 + 183 + struct ccw_io_region { 184 + #define ORB_AREA_SIZE 12 185 + __u8 orb_area[ORB_AREA_SIZE]; 186 + #define SCSW_AREA_SIZE 12 187 + __u8 scsw_area[SCSW_AREA_SIZE]; 188 + #define IRB_AREA_SIZE 96 189 + __u8 irb_area[IRB_AREA_SIZE]; 190 + __u32 ret_code; 191 + } __packed; 192 + 193 + While starting an I/O request, orb_area should be filled with the 194 + guest ORB, and scsw_area should be filled with the SCSW of the Virtual 195 + Subchannel. 196 + 197 + irb_area stores the I/O result. 198 + 199 + ret_code stores a return code for each access of the region. 200 + 201 + vfio-ccw patches overview 202 + ------------------------- 203 + 204 + For now, our patches are rebased on the latest mdev implementation. 205 + vfio-ccw follows what vfio-pci did on the s390 paltform and uses 206 + vfio-iommu-type1 as the vfio iommu backend. It's a good start to launch 207 + the code review for vfio-ccw. Note that the implementation is far from 208 + complete yet; but we'd like to get feedback for the general 209 + architecture. 210 + 211 + * CCW translation APIs 212 + - Description: 213 + These introduce a group of APIs (start with 'cp_') to do CCW 214 + translation. The CCWs passed in by a user space program are 215 + organized with their guest physical memory addresses. These APIs 216 + will copy the CCWs into the kernel space, and assemble a runnable 217 + kernel channel program by updating the guest physical addresses with 218 + their corresponding host physical addresses. 219 + - Patches: 220 + vfio: ccw: introduce channel program interfaces 221 + 222 + * vfio_ccw device driver 223 + - Description: 224 + The following patches utilizes the CCW translation APIs and introduce 225 + vfio_ccw, which is the driver for the I/O subchannel devices you want 226 + to pass through. 227 + vfio_ccw implements the following vfio ioctls: 228 + VFIO_DEVICE_GET_INFO 229 + VFIO_DEVICE_GET_IRQ_INFO 230 + VFIO_DEVICE_GET_REGION_INFO 231 + VFIO_DEVICE_RESET 232 + VFIO_DEVICE_SET_IRQS 233 + This provides an I/O region, so that the user space program can pass a 234 + channel program to the kernel, to do further CCW translation before 235 + issuing them to a real device. 236 + This also provides the SET_IRQ ioctl to setup an event notifier to 237 + notify the user space program the I/O completion in an asynchronous 238 + way. 239 + - Patches: 240 + vfio: ccw: basic implementation for vfio_ccw driver 241 + vfio: ccw: introduce ccw_io_region 242 + vfio: ccw: realize VFIO_DEVICE_GET_REGION_INFO ioctl 243 + vfio: ccw: realize VFIO_DEVICE_RESET ioctl 244 + vfio: ccw: realize VFIO_DEVICE_G(S)ET_IRQ_INFO ioctls 245 + 246 + The user of vfio-ccw is not limited to Qemu, while Qemu is definitely a 247 + good example to get understand how these patches work. Here is a little 248 + bit more detail how an I/O request triggered by the Qemu guest will be 249 + handled (without error handling). 250 + 251 + Explanation: 252 + Q1-Q7: Qemu side process. 253 + K1-K5: Kernel side process. 254 + 255 + Q1. Get I/O region info during initialization. 256 + Q2. Setup event notifier and handler to handle I/O completion. 257 + 258 + ... ... 259 + 260 + Q3. Intercept a ssch instruction. 261 + Q4. Write the guest channel program and ORB to the I/O region. 262 + K1. Copy from guest to kernel. 263 + K2. Translate the guest channel program to a host kernel space 264 + channel program, which becomes runnable for a real device. 265 + K3. With the necessary information contained in the orb passed in 266 + by Qemu, issue the ccwchain to the device. 267 + K4. Return the ssch CC code. 268 + Q5. Return the CC code to the guest. 269 + 270 + ... ... 271 + 272 + K5. Interrupt handler gets the I/O result and write the result to 273 + the I/O region. 274 + K6. Signal Qemu to retrieve the result. 275 + Q6. Get the signal and event handler reads out the result from the I/O 276 + region. 277 + Q7. Update the irb for the guest. 278 + 279 + Limitations 280 + ----------- 281 + 282 + The current vfio-ccw implementation focuses on supporting basic commands 283 + needed to implement block device functionality (read/write) of DASD/ECKD 284 + device only. Some commands may need special handling in the future, for 285 + example, anything related to path grouping. 286 + 287 + DASD is a kind of storage device. While ECKD is a data recording format. 288 + More information for DASD and ECKD could be found here: 289 + https://en.wikipedia.org/wiki/Direct-access_storage_device 290 + https://en.wikipedia.org/wiki/Count_key_data 291 + 292 + Together with the corresponding work in Qemu, we can bring the passed 293 + through DASD/ECKD device online in a guest now and use it as a block 294 + device. 295 + 296 + Reference 297 + --------- 298 + 1. ESA/s390 Principles of Operation manual (IBM Form. No. SA22-7832) 299 + 2. ESA/390 Common I/O Device Commands manual (IBM Form. No. SA22-7204) 300 + 3. https://en.wikipedia.org/wiki/Channel_I/O 301 + 4. Documentation/s390/cds.txt 302 + 5. Documentation/vfio.txt 303 + 6. Documentation/vfio-mediated-device.txt
+10
MAINTAINERS
··· 10860 10860 S: Supported 10861 10861 F: drivers/iommu/s390-iommu.c 10862 10862 10863 + S390 VFIO-CCW DRIVER 10864 + M: Cornelia Huck <cornelia.huck@de.ibm.com> 10865 + M: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 10866 + L: linux-s390@vger.kernel.org 10867 + L: kvm@vger.kernel.org 10868 + S: Supported 10869 + F: drivers/s390/cio/vfio_ccw* 10870 + F: Documentation/s390/vfio-ccw.txt 10871 + F: include/uapi/linux/vfio_ccw.h 10872 + 10863 10873 S3C24XX SD/MMC Driver 10864 10874 M: Ben Dooks <ben-linux@fluff.org> 10865 10875 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+10
arch/s390/Kconfig
··· 682 682 To compile this driver as a module, choose M here: the 683 683 module will be called eadm_sch. 684 684 685 + config VFIO_CCW 686 + def_tristate n 687 + prompt "Support for VFIO-CCW subchannels" 688 + depends on S390_CCW_IOMMU && VFIO_MDEV 689 + help 690 + This driver allows usage of I/O subchannels via VFIO-CCW. 691 + 692 + To compile this driver as a module, choose M here: the 693 + module will be called vfio_ccw. 694 + 685 695 endmenu 686 696 687 697 menu "Dump support"
+18
arch/s390/include/asm/cio.h
··· 33 33 __u32 cda; 34 34 } __attribute__ ((packed,aligned(8))); 35 35 36 + /** 37 + * struct ccw0 - channel command word 38 + * @cmd_code: command code 39 + * @cda: data address 40 + * @flags: flags, like IDA addressing, etc. 41 + * @reserved: will be ignored 42 + * @count: byte count 43 + * 44 + * The format-0 ccw structure. 45 + */ 46 + struct ccw0 { 47 + __u8 cmd_code; 48 + __u32 cda : 24; 49 + __u8 flags; 50 + __u8 reserved; 51 + __u16 count; 52 + } __packed __aligned(8); 53 + 36 54 #define CCW_FLAG_DC 0x80 37 55 #define CCW_FLAG_CC 0x40 38 56 #define CCW_FLAG_SLI 0x20
+1
arch/s390/include/asm/isc.h
··· 16 16 #define CONSOLE_ISC 1 /* console I/O subchannel */ 17 17 #define EADM_SCH_ISC 4 /* EADM subchannels */ 18 18 #define CHSC_SCH_ISC 7 /* CHSC subchannels */ 19 + #define VFIO_CCW_ISC IO_SCH_ISC /* VFIO-CCW I/O subchannels */ 19 20 /* Adapter interrupts. */ 20 21 #define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */ 21 22 #define PCI_ISC 2 /* PCI I/O subchannels */
+8
drivers/iommu/Kconfig
··· 327 327 help 328 328 Support for the IOMMU API for s390 PCI devices. 329 329 330 + config S390_CCW_IOMMU 331 + bool "S390 CCW IOMMU Support" 332 + depends on S390 && CCW 333 + select IOMMU_API 334 + help 335 + Enables bits of IOMMU API required by VFIO. The iommu_ops 336 + is not implemented as it is not necessary for VFIO. 337 + 330 338 config MTK_IOMMU 331 339 bool "MTK IOMMU Support" 332 340 depends on ARM || ARM64
+3
drivers/s390/cio/Makefile
··· 17 17 18 18 qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_setup.o 19 19 obj-$(CONFIG_QDIO) += qdio.o 20 + 21 + vfio_ccw-objs += vfio_ccw_drv.o vfio_ccw_cp.o vfio_ccw_ops.o vfio_ccw_fsm.o 22 + obj-$(CONFIG_VFIO_CCW) += vfio_ccw.o
+69
drivers/s390/cio/cio.c
··· 170 170 return ccode; 171 171 } 172 172 } 173 + EXPORT_SYMBOL_GPL(cio_start_key); 173 174 174 175 int 175 176 cio_start (struct subchannel *sch, struct ccw1 *cpa, __u8 lpm) 176 177 { 177 178 return cio_start_key(sch, cpa, lpm, PAGE_DEFAULT_KEY); 178 179 } 180 + EXPORT_SYMBOL_GPL(cio_start); 179 181 180 182 /* 181 183 * resume suspended I/O operation ··· 210 208 return -ENODEV; 211 209 } 212 210 } 211 + EXPORT_SYMBOL_GPL(cio_resume); 213 212 214 213 /* 215 214 * halt I/O operation ··· 244 241 return -ENODEV; 245 242 } 246 243 } 244 + EXPORT_SYMBOL_GPL(cio_halt); 247 245 248 246 /* 249 247 * Clear I/O operation ··· 275 271 return -ENODEV; 276 272 } 277 273 } 274 + EXPORT_SYMBOL_GPL(cio_clear); 278 275 279 276 /* 280 277 * Function: cio_cancel ··· 313 308 return -ENODEV; 314 309 } 315 310 } 311 + EXPORT_SYMBOL_GPL(cio_cancel); 316 312 313 + /** 314 + * cio_cancel_halt_clear - Cancel running I/O by performing cancel, halt 315 + * and clear ordinally if subchannel is valid. 316 + * @sch: subchannel on which to perform the cancel_halt_clear operation 317 + * @iretry: the number of the times remained to retry the next operation 318 + * 319 + * This should be called repeatedly since halt/clear are asynchronous 320 + * operations. We do one try with cio_cancel, three tries with cio_halt, 321 + * 255 tries with cio_clear. The caller should initialize @iretry with 322 + * the value 255 for its first call to this, and keep using the same 323 + * @iretry in the subsequent calls until it gets a non -EBUSY return. 324 + * 325 + * Returns 0 if device now idle, -ENODEV for device not operational, 326 + * -EBUSY if an interrupt is expected (either from halt/clear or from a 327 + * status pending), and -EIO if out of retries. 328 + */ 329 + int cio_cancel_halt_clear(struct subchannel *sch, int *iretry) 330 + { 331 + int ret; 332 + 333 + if (cio_update_schib(sch)) 334 + return -ENODEV; 335 + if (!sch->schib.pmcw.ena) 336 + /* Not operational -> done. */ 337 + return 0; 338 + /* Stage 1: cancel io. */ 339 + if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) && 340 + !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { 341 + if (!scsw_is_tm(&sch->schib.scsw)) { 342 + ret = cio_cancel(sch); 343 + if (ret != -EINVAL) 344 + return ret; 345 + } 346 + /* 347 + * Cancel io unsuccessful or not applicable (transport mode). 348 + * Continue with asynchronous instructions. 349 + */ 350 + *iretry = 3; /* 3 halt retries. */ 351 + } 352 + /* Stage 2: halt io. */ 353 + if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { 354 + if (*iretry) { 355 + *iretry -= 1; 356 + ret = cio_halt(sch); 357 + if (ret != -EBUSY) 358 + return (ret == 0) ? -EBUSY : ret; 359 + } 360 + /* Halt io unsuccessful. */ 361 + *iretry = 255; /* 255 clear retries. */ 362 + } 363 + /* Stage 3: clear io. */ 364 + if (*iretry) { 365 + *iretry -= 1; 366 + ret = cio_clear(sch); 367 + return (ret == 0) ? -EBUSY : ret; 368 + } 369 + /* Function was unsuccessful */ 370 + return -EIO; 371 + } 372 + EXPORT_SYMBOL_GPL(cio_cancel_halt_clear); 317 373 318 374 static void cio_apply_config(struct subchannel *sch, struct schib *schib) 319 375 { ··· 448 382 } 449 383 return ret; 450 384 } 385 + EXPORT_SYMBOL_GPL(cio_commit_config); 451 386 452 387 /** 453 388 * cio_update_schib - Perform stsch and update schib if subchannel is valid. ··· 1054 987 return cio_start_handle_notoper(sch, lpm); 1055 988 } 1056 989 } 990 + EXPORT_SYMBOL_GPL(cio_tm_start_key); 1057 991 1058 992 /** 1059 993 * cio_tm_intrg - perform interrogate function ··· 1080 1012 return -ENODEV; 1081 1013 } 1082 1014 } 1015 + EXPORT_SYMBOL_GPL(cio_tm_intrg);
+1
drivers/s390/cio/cio.h
··· 123 123 extern int cio_disable_subchannel (struct subchannel *); 124 124 extern int cio_cancel (struct subchannel *); 125 125 extern int cio_clear (struct subchannel *); 126 + extern int cio_cancel_halt_clear(struct subchannel *, int *); 126 127 extern int cio_resume (struct subchannel *); 127 128 extern int cio_halt (struct subchannel *); 128 129 extern int cio_start (struct subchannel *, struct ccw1 *, __u8);
+8 -46
drivers/s390/cio/device_fsm.c
··· 124 124 add_timer(&cdev->private->timer); 125 125 } 126 126 127 - /* 128 - * Cancel running i/o. This is called repeatedly since halt/clear are 129 - * asynchronous operations. We do one try with cio_cancel, two tries 130 - * with cio_halt, 255 tries with cio_clear. If everythings fails panic. 131 - * Returns 0 if device now idle, -ENODEV for device not operational and 132 - * -EBUSY if an interrupt is expected (either from halt/clear or from a 133 - * status pending). 134 - */ 135 127 int 136 128 ccw_device_cancel_halt_clear(struct ccw_device *cdev) 137 129 { ··· 131 139 int ret; 132 140 133 141 sch = to_subchannel(cdev->dev.parent); 134 - if (cio_update_schib(sch)) 135 - return -ENODEV; 136 - if (!sch->schib.pmcw.ena) 137 - /* Not operational -> done. */ 138 - return 0; 139 - /* Stage 1: cancel io. */ 140 - if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) && 141 - !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { 142 - if (!scsw_is_tm(&sch->schib.scsw)) { 143 - ret = cio_cancel(sch); 144 - if (ret != -EINVAL) 145 - return ret; 146 - } 147 - /* cancel io unsuccessful or not applicable (transport mode). 148 - * Continue with asynchronous instructions. */ 149 - cdev->private->iretry = 3; /* 3 halt retries. */ 150 - } 151 - if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { 152 - /* Stage 2: halt io. */ 153 - if (cdev->private->iretry) { 154 - cdev->private->iretry--; 155 - ret = cio_halt(sch); 156 - if (ret != -EBUSY) 157 - return (ret == 0) ? -EBUSY : ret; 158 - } 159 - /* halt io unsuccessful. */ 160 - cdev->private->iretry = 255; /* 255 clear retries. */ 161 - } 162 - /* Stage 3: clear io. */ 163 - if (cdev->private->iretry) { 164 - cdev->private->iretry--; 165 - ret = cio_clear (sch); 166 - return (ret == 0) ? -EBUSY : ret; 167 - } 168 - /* Function was unsuccessful */ 169 - CIO_MSG_EVENT(0, "0.%x.%04x: could not stop I/O\n", 170 - cdev->private->dev_id.ssid, cdev->private->dev_id.devno); 171 - return -EIO; 142 + ret = cio_cancel_halt_clear(sch, &cdev->private->iretry); 143 + 144 + if (ret == -EIO) 145 + CIO_MSG_EVENT(0, "0.%x.%04x: could not stop I/O\n", 146 + cdev->private->dev_id.ssid, 147 + cdev->private->dev_id.devno); 148 + 149 + return ret; 172 150 } 173 151 174 152 void ccw_device_update_sense_data(struct ccw_device *cdev)
+842
drivers/s390/cio/vfio_ccw_cp.c
··· 1 + /* 2 + * channel program interfaces 3 + * 4 + * Copyright IBM Corp. 2017 5 + * 6 + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 7 + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> 8 + */ 9 + 10 + #include <linux/mm.h> 11 + #include <linux/slab.h> 12 + #include <linux/iommu.h> 13 + #include <linux/vfio.h> 14 + #include <asm/idals.h> 15 + 16 + #include "vfio_ccw_cp.h" 17 + 18 + /* 19 + * Max length for ccw chain. 20 + * XXX: Limit to 256, need to check more? 21 + */ 22 + #define CCWCHAIN_LEN_MAX 256 23 + 24 + struct pfn_array { 25 + unsigned long pa_iova; 26 + unsigned long *pa_iova_pfn; 27 + unsigned long *pa_pfn; 28 + int pa_nr; 29 + }; 30 + 31 + struct pfn_array_table { 32 + struct pfn_array *pat_pa; 33 + int pat_nr; 34 + }; 35 + 36 + struct ccwchain { 37 + struct list_head next; 38 + struct ccw1 *ch_ccw; 39 + /* Guest physical address of the current chain. */ 40 + u64 ch_iova; 41 + /* Count of the valid ccws in chain. */ 42 + int ch_len; 43 + /* Pinned PAGEs for the original data. */ 44 + struct pfn_array_table *ch_pat; 45 + }; 46 + 47 + /* 48 + * pfn_array_pin() - pin user pages in memory 49 + * @pa: pfn_array on which to perform the operation 50 + * @mdev: the mediated device to perform pin/unpin operations 51 + * 52 + * Attempt to pin user pages in memory. 53 + * 54 + * Usage of pfn_array: 55 + * @pa->pa_iova starting guest physical I/O address. Assigned by caller. 56 + * @pa->pa_iova_pfn array that stores PFNs of the pages need to pin. Allocated 57 + * by caller. 58 + * @pa->pa_pfn array that receives PFNs of the pages pinned. Allocated by 59 + * caller. 60 + * @pa->pa_nr number of pages from @pa->pa_iova to pin. Assigned by 61 + * caller. 62 + * number of pages pinned. Assigned by callee. 63 + * 64 + * Returns: 65 + * Number of pages pinned on success. 66 + * If @pa->pa_nr is 0 or negative, returns 0. 67 + * If no pages were pinned, returns -errno. 68 + */ 69 + static int pfn_array_pin(struct pfn_array *pa, struct device *mdev) 70 + { 71 + int i, ret; 72 + 73 + if (pa->pa_nr <= 0) { 74 + pa->pa_nr = 0; 75 + return 0; 76 + } 77 + 78 + pa->pa_iova_pfn[0] = pa->pa_iova >> PAGE_SHIFT; 79 + for (i = 1; i < pa->pa_nr; i++) 80 + pa->pa_iova_pfn[i] = pa->pa_iova_pfn[i - 1] + 1; 81 + 82 + ret = vfio_pin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr, 83 + IOMMU_READ | IOMMU_WRITE, pa->pa_pfn); 84 + 85 + if (ret > 0 && ret != pa->pa_nr) { 86 + vfio_unpin_pages(mdev, pa->pa_iova_pfn, ret); 87 + pa->pa_nr = 0; 88 + return 0; 89 + } 90 + 91 + return ret; 92 + } 93 + 94 + /* Unpin the pages before releasing the memory. */ 95 + static void pfn_array_unpin_free(struct pfn_array *pa, struct device *mdev) 96 + { 97 + vfio_unpin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr); 98 + pa->pa_nr = 0; 99 + kfree(pa->pa_iova_pfn); 100 + } 101 + 102 + /* Alloc memory for PFNs, then pin pages with them. */ 103 + static int pfn_array_alloc_pin(struct pfn_array *pa, struct device *mdev, 104 + u64 iova, unsigned int len) 105 + { 106 + int ret = 0; 107 + 108 + if (!len || pa->pa_nr) 109 + return -EINVAL; 110 + 111 + pa->pa_iova = iova; 112 + 113 + pa->pa_nr = ((iova & ~PAGE_MASK) + len + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 114 + if (!pa->pa_nr) 115 + return -EINVAL; 116 + 117 + pa->pa_iova_pfn = kcalloc(pa->pa_nr, 118 + sizeof(*pa->pa_iova_pfn) + 119 + sizeof(*pa->pa_pfn), 120 + GFP_KERNEL); 121 + if (unlikely(!pa->pa_iova_pfn)) 122 + return -ENOMEM; 123 + pa->pa_pfn = pa->pa_iova_pfn + pa->pa_nr; 124 + 125 + ret = pfn_array_pin(pa, mdev); 126 + 127 + if (ret > 0) 128 + return ret; 129 + else if (!ret) 130 + ret = -EINVAL; 131 + 132 + kfree(pa->pa_iova_pfn); 133 + 134 + return ret; 135 + } 136 + 137 + static int pfn_array_table_init(struct pfn_array_table *pat, int nr) 138 + { 139 + pat->pat_pa = kcalloc(nr, sizeof(*pat->pat_pa), GFP_KERNEL); 140 + if (unlikely(ZERO_OR_NULL_PTR(pat->pat_pa))) { 141 + pat->pat_nr = 0; 142 + return -ENOMEM; 143 + } 144 + 145 + pat->pat_nr = nr; 146 + 147 + return 0; 148 + } 149 + 150 + static void pfn_array_table_unpin_free(struct pfn_array_table *pat, 151 + struct device *mdev) 152 + { 153 + int i; 154 + 155 + for (i = 0; i < pat->pat_nr; i++) 156 + pfn_array_unpin_free(pat->pat_pa + i, mdev); 157 + 158 + if (pat->pat_nr) { 159 + kfree(pat->pat_pa); 160 + pat->pat_pa = NULL; 161 + pat->pat_nr = 0; 162 + } 163 + } 164 + 165 + static bool pfn_array_table_iova_pinned(struct pfn_array_table *pat, 166 + unsigned long iova) 167 + { 168 + struct pfn_array *pa = pat->pat_pa; 169 + unsigned long iova_pfn = iova >> PAGE_SHIFT; 170 + int i, j; 171 + 172 + for (i = 0; i < pat->pat_nr; i++, pa++) 173 + for (j = 0; j < pa->pa_nr; j++) 174 + if (pa->pa_iova_pfn[i] == iova_pfn) 175 + return true; 176 + 177 + return false; 178 + } 179 + /* Create the list idal words for a pfn_array_table. */ 180 + static inline void pfn_array_table_idal_create_words( 181 + struct pfn_array_table *pat, 182 + unsigned long *idaws) 183 + { 184 + struct pfn_array *pa; 185 + int i, j, k; 186 + 187 + /* 188 + * Idal words (execept the first one) rely on the memory being 4k 189 + * aligned. If a user virtual address is 4K aligned, then it's 190 + * corresponding kernel physical address will also be 4K aligned. Thus 191 + * there will be no problem here to simply use the phys to create an 192 + * idaw. 193 + */ 194 + k = 0; 195 + for (i = 0; i < pat->pat_nr; i++) { 196 + pa = pat->pat_pa + i; 197 + for (j = 0; j < pa->pa_nr; j++) { 198 + idaws[k] = pa->pa_pfn[j] << PAGE_SHIFT; 199 + if (k == 0) 200 + idaws[k] += pa->pa_iova & (PAGE_SIZE - 1); 201 + k++; 202 + } 203 + } 204 + } 205 + 206 + 207 + /* 208 + * Within the domain (@mdev), copy @n bytes from a guest physical 209 + * address (@iova) to a host physical address (@to). 210 + */ 211 + static long copy_from_iova(struct device *mdev, 212 + void *to, u64 iova, 213 + unsigned long n) 214 + { 215 + struct pfn_array pa = {0}; 216 + u64 from; 217 + int i, ret; 218 + unsigned long l, m; 219 + 220 + ret = pfn_array_alloc_pin(&pa, mdev, iova, n); 221 + if (ret <= 0) 222 + return ret; 223 + 224 + l = n; 225 + for (i = 0; i < pa.pa_nr; i++) { 226 + from = pa.pa_pfn[i] << PAGE_SHIFT; 227 + m = PAGE_SIZE; 228 + if (i == 0) { 229 + from += iova & (PAGE_SIZE - 1); 230 + m -= iova & (PAGE_SIZE - 1); 231 + } 232 + 233 + m = min(l, m); 234 + memcpy(to + (n - l), (void *)from, m); 235 + 236 + l -= m; 237 + if (l == 0) 238 + break; 239 + } 240 + 241 + pfn_array_unpin_free(&pa, mdev); 242 + 243 + return l; 244 + } 245 + 246 + static long copy_ccw_from_iova(struct channel_program *cp, 247 + struct ccw1 *to, u64 iova, 248 + unsigned long len) 249 + { 250 + struct ccw0 ccw0; 251 + struct ccw1 *pccw1; 252 + int ret; 253 + int i; 254 + 255 + ret = copy_from_iova(cp->mdev, to, iova, len * sizeof(struct ccw1)); 256 + if (ret) 257 + return ret; 258 + 259 + if (!cp->orb.cmd.fmt) { 260 + pccw1 = to; 261 + for (i = 0; i < len; i++) { 262 + ccw0 = *(struct ccw0 *)pccw1; 263 + if ((pccw1->cmd_code & 0x0f) == CCW_CMD_TIC) { 264 + pccw1->cmd_code = CCW_CMD_TIC; 265 + pccw1->flags = 0; 266 + pccw1->count = 0; 267 + } else { 268 + pccw1->cmd_code = ccw0.cmd_code; 269 + pccw1->flags = ccw0.flags; 270 + pccw1->count = ccw0.count; 271 + } 272 + pccw1->cda = ccw0.cda; 273 + pccw1++; 274 + } 275 + } 276 + 277 + return ret; 278 + } 279 + 280 + /* 281 + * Helpers to operate ccwchain. 282 + */ 283 + #define ccw_is_test(_ccw) (((_ccw)->cmd_code & 0x0F) == 0) 284 + 285 + #define ccw_is_noop(_ccw) ((_ccw)->cmd_code == CCW_CMD_NOOP) 286 + 287 + #define ccw_is_tic(_ccw) ((_ccw)->cmd_code == CCW_CMD_TIC) 288 + 289 + #define ccw_is_idal(_ccw) ((_ccw)->flags & CCW_FLAG_IDA) 290 + 291 + 292 + #define ccw_is_chain(_ccw) ((_ccw)->flags & (CCW_FLAG_CC | CCW_FLAG_DC)) 293 + 294 + static struct ccwchain *ccwchain_alloc(struct channel_program *cp, int len) 295 + { 296 + struct ccwchain *chain; 297 + void *data; 298 + size_t size; 299 + 300 + /* Make ccw address aligned to 8. */ 301 + size = ((sizeof(*chain) + 7L) & -8L) + 302 + sizeof(*chain->ch_ccw) * len + 303 + sizeof(*chain->ch_pat) * len; 304 + chain = kzalloc(size, GFP_DMA | GFP_KERNEL); 305 + if (!chain) 306 + return NULL; 307 + 308 + data = (u8 *)chain + ((sizeof(*chain) + 7L) & -8L); 309 + chain->ch_ccw = (struct ccw1 *)data; 310 + 311 + data = (u8 *)(chain->ch_ccw) + sizeof(*chain->ch_ccw) * len; 312 + chain->ch_pat = (struct pfn_array_table *)data; 313 + 314 + chain->ch_len = len; 315 + 316 + list_add_tail(&chain->next, &cp->ccwchain_list); 317 + 318 + return chain; 319 + } 320 + 321 + static void ccwchain_free(struct ccwchain *chain) 322 + { 323 + list_del(&chain->next); 324 + kfree(chain); 325 + } 326 + 327 + /* Free resource for a ccw that allocated memory for its cda. */ 328 + static void ccwchain_cda_free(struct ccwchain *chain, int idx) 329 + { 330 + struct ccw1 *ccw = chain->ch_ccw + idx; 331 + 332 + if (!ccw->count) 333 + return; 334 + 335 + kfree((void *)(u64)ccw->cda); 336 + } 337 + 338 + /* Unpin the pages then free the memory resources. */ 339 + static void cp_unpin_free(struct channel_program *cp) 340 + { 341 + struct ccwchain *chain, *temp; 342 + int i; 343 + 344 + list_for_each_entry_safe(chain, temp, &cp->ccwchain_list, next) { 345 + for (i = 0; i < chain->ch_len; i++) { 346 + pfn_array_table_unpin_free(chain->ch_pat + i, 347 + cp->mdev); 348 + ccwchain_cda_free(chain, i); 349 + } 350 + ccwchain_free(chain); 351 + } 352 + } 353 + 354 + /** 355 + * ccwchain_calc_length - calculate the length of the ccw chain. 356 + * @iova: guest physical address of the target ccw chain 357 + * @cp: channel_program on which to perform the operation 358 + * 359 + * This is the chain length not considering any TICs. 360 + * You need to do a new round for each TIC target. 361 + * 362 + * Returns: the length of the ccw chain or -errno. 363 + */ 364 + static int ccwchain_calc_length(u64 iova, struct channel_program *cp) 365 + { 366 + struct ccw1 *ccw, *p; 367 + int cnt; 368 + 369 + /* 370 + * Copy current chain from guest to host kernel. 371 + * Currently the chain length is limited to CCWCHAIN_LEN_MAX (256). 372 + * So copying 2K is enough (safe). 373 + */ 374 + p = ccw = kcalloc(CCWCHAIN_LEN_MAX, sizeof(*ccw), GFP_KERNEL); 375 + if (!ccw) 376 + return -ENOMEM; 377 + 378 + cnt = copy_ccw_from_iova(cp, ccw, iova, CCWCHAIN_LEN_MAX); 379 + if (cnt) { 380 + kfree(ccw); 381 + return cnt; 382 + } 383 + 384 + cnt = 0; 385 + do { 386 + cnt++; 387 + 388 + if ((!ccw_is_chain(ccw)) && (!ccw_is_tic(ccw))) 389 + break; 390 + 391 + ccw++; 392 + } while (cnt < CCWCHAIN_LEN_MAX + 1); 393 + 394 + if (cnt == CCWCHAIN_LEN_MAX + 1) 395 + cnt = -EINVAL; 396 + 397 + kfree(p); 398 + return cnt; 399 + } 400 + 401 + static int tic_target_chain_exists(struct ccw1 *tic, struct channel_program *cp) 402 + { 403 + struct ccwchain *chain; 404 + u32 ccw_head, ccw_tail; 405 + 406 + list_for_each_entry(chain, &cp->ccwchain_list, next) { 407 + ccw_head = chain->ch_iova; 408 + ccw_tail = ccw_head + (chain->ch_len - 1) * sizeof(struct ccw1); 409 + 410 + if ((ccw_head <= tic->cda) && (tic->cda <= ccw_tail)) 411 + return 1; 412 + } 413 + 414 + return 0; 415 + } 416 + 417 + static int ccwchain_loop_tic(struct ccwchain *chain, 418 + struct channel_program *cp); 419 + 420 + static int ccwchain_handle_tic(struct ccw1 *tic, struct channel_program *cp) 421 + { 422 + struct ccwchain *chain; 423 + int len, ret; 424 + 425 + /* May transfer to an existing chain. */ 426 + if (tic_target_chain_exists(tic, cp)) 427 + return 0; 428 + 429 + /* Get chain length. */ 430 + len = ccwchain_calc_length(tic->cda, cp); 431 + if (len < 0) 432 + return len; 433 + 434 + /* Need alloc a new chain for this one. */ 435 + chain = ccwchain_alloc(cp, len); 436 + if (!chain) 437 + return -ENOMEM; 438 + chain->ch_iova = tic->cda; 439 + 440 + /* Copy the new chain from user. */ 441 + ret = copy_ccw_from_iova(cp, chain->ch_ccw, tic->cda, len); 442 + if (ret) { 443 + ccwchain_free(chain); 444 + return ret; 445 + } 446 + 447 + /* Loop for tics on this new chain. */ 448 + return ccwchain_loop_tic(chain, cp); 449 + } 450 + 451 + /* Loop for TICs. */ 452 + static int ccwchain_loop_tic(struct ccwchain *chain, struct channel_program *cp) 453 + { 454 + struct ccw1 *tic; 455 + int i, ret; 456 + 457 + for (i = 0; i < chain->ch_len; i++) { 458 + tic = chain->ch_ccw + i; 459 + 460 + if (!ccw_is_tic(tic)) 461 + continue; 462 + 463 + ret = ccwchain_handle_tic(tic, cp); 464 + if (ret) 465 + return ret; 466 + } 467 + 468 + return 0; 469 + } 470 + 471 + static int ccwchain_fetch_tic(struct ccwchain *chain, 472 + int idx, 473 + struct channel_program *cp) 474 + { 475 + struct ccw1 *ccw = chain->ch_ccw + idx; 476 + struct ccwchain *iter; 477 + u32 ccw_head, ccw_tail; 478 + 479 + list_for_each_entry(iter, &cp->ccwchain_list, next) { 480 + ccw_head = iter->ch_iova; 481 + ccw_tail = ccw_head + (iter->ch_len - 1) * sizeof(struct ccw1); 482 + 483 + if ((ccw_head <= ccw->cda) && (ccw->cda <= ccw_tail)) { 484 + ccw->cda = (__u32) (addr_t) (iter->ch_ccw + 485 + (ccw->cda - ccw_head)); 486 + return 0; 487 + } 488 + } 489 + 490 + return -EFAULT; 491 + } 492 + 493 + static int ccwchain_fetch_direct(struct ccwchain *chain, 494 + int idx, 495 + struct channel_program *cp) 496 + { 497 + struct ccw1 *ccw; 498 + struct pfn_array_table *pat; 499 + unsigned long *idaws; 500 + int idaw_nr; 501 + 502 + ccw = chain->ch_ccw + idx; 503 + 504 + /* 505 + * Pin data page(s) in memory. 506 + * The number of pages actually is the count of the idaws which will be 507 + * needed when translating a direct ccw to a idal ccw. 508 + */ 509 + pat = chain->ch_pat + idx; 510 + if (pfn_array_table_init(pat, 1)) 511 + return -ENOMEM; 512 + idaw_nr = pfn_array_alloc_pin(pat->pat_pa, cp->mdev, 513 + ccw->cda, ccw->count); 514 + if (idaw_nr < 0) 515 + return idaw_nr; 516 + 517 + /* Translate this direct ccw to a idal ccw. */ 518 + idaws = kcalloc(idaw_nr, sizeof(*idaws), GFP_DMA | GFP_KERNEL); 519 + if (!idaws) { 520 + pfn_array_table_unpin_free(pat, cp->mdev); 521 + return -ENOMEM; 522 + } 523 + ccw->cda = (__u32) virt_to_phys(idaws); 524 + ccw->flags |= CCW_FLAG_IDA; 525 + 526 + pfn_array_table_idal_create_words(pat, idaws); 527 + 528 + return 0; 529 + } 530 + 531 + static int ccwchain_fetch_idal(struct ccwchain *chain, 532 + int idx, 533 + struct channel_program *cp) 534 + { 535 + struct ccw1 *ccw; 536 + struct pfn_array_table *pat; 537 + unsigned long *idaws; 538 + u64 idaw_iova; 539 + unsigned int idaw_nr, idaw_len; 540 + int i, ret; 541 + 542 + ccw = chain->ch_ccw + idx; 543 + 544 + /* Calculate size of idaws. */ 545 + ret = copy_from_iova(cp->mdev, &idaw_iova, ccw->cda, sizeof(idaw_iova)); 546 + if (ret) 547 + return ret; 548 + idaw_nr = idal_nr_words((void *)(idaw_iova), ccw->count); 549 + idaw_len = idaw_nr * sizeof(*idaws); 550 + 551 + /* Pin data page(s) in memory. */ 552 + pat = chain->ch_pat + idx; 553 + ret = pfn_array_table_init(pat, idaw_nr); 554 + if (ret) 555 + return ret; 556 + 557 + /* Translate idal ccw to use new allocated idaws. */ 558 + idaws = kzalloc(idaw_len, GFP_DMA | GFP_KERNEL); 559 + if (!idaws) { 560 + ret = -ENOMEM; 561 + goto out_unpin; 562 + } 563 + 564 + ret = copy_from_iova(cp->mdev, idaws, ccw->cda, idaw_len); 565 + if (ret) 566 + goto out_free_idaws; 567 + 568 + ccw->cda = virt_to_phys(idaws); 569 + 570 + for (i = 0; i < idaw_nr; i++) { 571 + idaw_iova = *(idaws + i); 572 + if (IS_ERR_VALUE(idaw_iova)) { 573 + ret = -EFAULT; 574 + goto out_free_idaws; 575 + } 576 + 577 + ret = pfn_array_alloc_pin(pat->pat_pa + i, cp->mdev, 578 + idaw_iova, 1); 579 + if (ret < 0) 580 + goto out_free_idaws; 581 + } 582 + 583 + pfn_array_table_idal_create_words(pat, idaws); 584 + 585 + return 0; 586 + 587 + out_free_idaws: 588 + kfree(idaws); 589 + out_unpin: 590 + pfn_array_table_unpin_free(pat, cp->mdev); 591 + return ret; 592 + } 593 + 594 + /* 595 + * Fetch one ccw. 596 + * To reduce memory copy, we'll pin the cda page in memory, 597 + * and to get rid of the cda 2G limitiaion of ccw1, we'll translate 598 + * direct ccws to idal ccws. 599 + */ 600 + static int ccwchain_fetch_one(struct ccwchain *chain, 601 + int idx, 602 + struct channel_program *cp) 603 + { 604 + struct ccw1 *ccw = chain->ch_ccw + idx; 605 + 606 + if (ccw_is_test(ccw) || ccw_is_noop(ccw)) 607 + return 0; 608 + 609 + if (ccw_is_tic(ccw)) 610 + return ccwchain_fetch_tic(chain, idx, cp); 611 + 612 + if (ccw_is_idal(ccw)) 613 + return ccwchain_fetch_idal(chain, idx, cp); 614 + 615 + return ccwchain_fetch_direct(chain, idx, cp); 616 + } 617 + 618 + /** 619 + * cp_init() - allocate ccwchains for a channel program. 620 + * @cp: channel_program on which to perform the operation 621 + * @mdev: the mediated device to perform pin/unpin operations 622 + * @orb: control block for the channel program from the guest 623 + * 624 + * This creates one or more ccwchain(s), and copies the raw data of 625 + * the target channel program from @orb->cmd.iova to the new ccwchain(s). 626 + * 627 + * Limitations: 628 + * 1. Supports only prefetch enabled mode. 629 + * 2. Supports idal(c64) ccw chaining. 630 + * 3. Supports 4k idaw. 631 + * 632 + * Returns: 633 + * %0 on success and a negative error value on failure. 634 + */ 635 + int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb) 636 + { 637 + u64 iova = orb->cmd.cpa; 638 + struct ccwchain *chain; 639 + int len, ret; 640 + 641 + /* 642 + * XXX: 643 + * Only support prefetch enable mode now. 644 + * Only support 64bit addressing idal. 645 + * Only support 4k IDAW. 646 + */ 647 + if (!orb->cmd.pfch || !orb->cmd.c64 || orb->cmd.i2k) 648 + return -EOPNOTSUPP; 649 + 650 + INIT_LIST_HEAD(&cp->ccwchain_list); 651 + memcpy(&cp->orb, orb, sizeof(*orb)); 652 + cp->mdev = mdev; 653 + 654 + /* Get chain length. */ 655 + len = ccwchain_calc_length(iova, cp); 656 + if (len < 0) 657 + return len; 658 + 659 + /* Alloc mem for the head chain. */ 660 + chain = ccwchain_alloc(cp, len); 661 + if (!chain) 662 + return -ENOMEM; 663 + chain->ch_iova = iova; 664 + 665 + /* Copy the head chain from guest. */ 666 + ret = copy_ccw_from_iova(cp, chain->ch_ccw, iova, len); 667 + if (ret) { 668 + ccwchain_free(chain); 669 + return ret; 670 + } 671 + 672 + /* Now loop for its TICs. */ 673 + ret = ccwchain_loop_tic(chain, cp); 674 + if (ret) 675 + cp_unpin_free(cp); 676 + 677 + return ret; 678 + } 679 + 680 + 681 + /** 682 + * cp_free() - free resources for channel program. 683 + * @cp: channel_program on which to perform the operation 684 + * 685 + * This unpins the memory pages and frees the memory space occupied by 686 + * @cp, which must have been returned by a previous call to cp_init(). 687 + * Otherwise, undefined behavior occurs. 688 + */ 689 + void cp_free(struct channel_program *cp) 690 + { 691 + cp_unpin_free(cp); 692 + } 693 + 694 + /** 695 + * cp_prefetch() - translate a guest physical address channel program to 696 + * a real-device runnable channel program. 697 + * @cp: channel_program on which to perform the operation 698 + * 699 + * This function translates the guest-physical-address channel program 700 + * and stores the result to ccwchain list. @cp must have been 701 + * initialized by a previous call with cp_init(). Otherwise, undefined 702 + * behavior occurs. 703 + * 704 + * The S/390 CCW Translation APIS (prefixed by 'cp_') are introduced 705 + * as helpers to do ccw chain translation inside the kernel. Basically 706 + * they accept a channel program issued by a virtual machine, and 707 + * translate the channel program to a real-device runnable channel 708 + * program. 709 + * 710 + * These APIs will copy the ccws into kernel-space buffers, and update 711 + * the guest phsical addresses with their corresponding host physical 712 + * addresses. Then channel I/O device drivers could issue the 713 + * translated channel program to real devices to perform an I/O 714 + * operation. 715 + * 716 + * These interfaces are designed to support translation only for 717 + * channel programs, which are generated and formatted by a 718 + * guest. Thus this will make it possible for things like VFIO to 719 + * leverage the interfaces to passthrough a channel I/O mediated 720 + * device in QEMU. 721 + * 722 + * We support direct ccw chaining by translating them to idal ccws. 723 + * 724 + * Returns: 725 + * %0 on success and a negative error value on failure. 726 + */ 727 + int cp_prefetch(struct channel_program *cp) 728 + { 729 + struct ccwchain *chain; 730 + int len, idx, ret; 731 + 732 + list_for_each_entry(chain, &cp->ccwchain_list, next) { 733 + len = chain->ch_len; 734 + for (idx = 0; idx < len; idx++) { 735 + ret = ccwchain_fetch_one(chain, idx, cp); 736 + if (ret) 737 + return ret; 738 + } 739 + } 740 + 741 + return 0; 742 + } 743 + 744 + /** 745 + * cp_get_orb() - get the orb of the channel program 746 + * @cp: channel_program on which to perform the operation 747 + * @intparm: new intparm for the returned orb 748 + * @lpm: candidate value of the logical-path mask for the returned orb 749 + * 750 + * This function returns the address of the updated orb of the channel 751 + * program. Channel I/O device drivers could use this orb to issue a 752 + * ssch. 753 + */ 754 + union orb *cp_get_orb(struct channel_program *cp, u32 intparm, u8 lpm) 755 + { 756 + union orb *orb; 757 + struct ccwchain *chain; 758 + struct ccw1 *cpa; 759 + 760 + orb = &cp->orb; 761 + 762 + orb->cmd.intparm = intparm; 763 + orb->cmd.fmt = 1; 764 + orb->cmd.key = PAGE_DEFAULT_KEY >> 4; 765 + 766 + if (orb->cmd.lpm == 0) 767 + orb->cmd.lpm = lpm; 768 + 769 + chain = list_first_entry(&cp->ccwchain_list, struct ccwchain, next); 770 + cpa = chain->ch_ccw; 771 + orb->cmd.cpa = (__u32) __pa(cpa); 772 + 773 + return orb; 774 + } 775 + 776 + /** 777 + * cp_update_scsw() - update scsw for a channel program. 778 + * @cp: channel_program on which to perform the operation 779 + * @scsw: I/O results of the channel program and also the target to be 780 + * updated 781 + * 782 + * @scsw contains the I/O results of the channel program that pointed 783 + * to by @cp. However what @scsw->cpa stores is a host physical 784 + * address, which is meaningless for the guest, which is waiting for 785 + * the I/O results. 786 + * 787 + * This function updates @scsw->cpa to its coressponding guest physical 788 + * address. 789 + */ 790 + void cp_update_scsw(struct channel_program *cp, union scsw *scsw) 791 + { 792 + struct ccwchain *chain; 793 + u32 cpa = scsw->cmd.cpa; 794 + u32 ccw_head, ccw_tail; 795 + 796 + /* 797 + * LATER: 798 + * For now, only update the cmd.cpa part. We may need to deal with 799 + * other portions of the schib as well, even if we don't return them 800 + * in the ioctl directly. Path status changes etc. 801 + */ 802 + list_for_each_entry(chain, &cp->ccwchain_list, next) { 803 + ccw_head = (u32)(u64)chain->ch_ccw; 804 + ccw_tail = (u32)(u64)(chain->ch_ccw + chain->ch_len - 1); 805 + 806 + if ((ccw_head <= cpa) && (cpa <= ccw_tail)) { 807 + /* 808 + * (cpa - ccw_head) is the offset value of the host 809 + * physical ccw to its chain head. 810 + * Adding this value to the guest physical ccw chain 811 + * head gets us the guest cpa. 812 + */ 813 + cpa = chain->ch_iova + (cpa - ccw_head); 814 + break; 815 + } 816 + } 817 + 818 + scsw->cmd.cpa = cpa; 819 + } 820 + 821 + /** 822 + * cp_iova_pinned() - check if an iova is pinned for a ccw chain. 823 + * @cmd: ccwchain command on which to perform the operation 824 + * @iova: the iova to check 825 + * 826 + * If the @iova is currently pinned for the ccw chain, return true; 827 + * else return false. 828 + */ 829 + bool cp_iova_pinned(struct channel_program *cp, u64 iova) 830 + { 831 + struct ccwchain *chain; 832 + int i; 833 + 834 + list_for_each_entry(chain, &cp->ccwchain_list, next) { 835 + for (i = 0; i < chain->ch_len; i++) 836 + if (pfn_array_table_iova_pinned(chain->ch_pat + i, 837 + iova)) 838 + return true; 839 + } 840 + 841 + return false; 842 + }
+42
drivers/s390/cio/vfio_ccw_cp.h
··· 1 + /* 2 + * channel program interfaces 3 + * 4 + * Copyright IBM Corp. 2017 5 + * 6 + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 7 + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> 8 + */ 9 + 10 + #ifndef _VFIO_CCW_CP_H_ 11 + #define _VFIO_CCW_CP_H_ 12 + 13 + #include <asm/cio.h> 14 + #include <asm/scsw.h> 15 + 16 + #include "orb.h" 17 + 18 + /** 19 + * struct channel_program - manage information for channel program 20 + * @ccwchain_list: list head of ccwchains 21 + * @orb: orb for the currently processed ssch request 22 + * @mdev: the mediated device to perform page pinning/unpinning 23 + * 24 + * @ccwchain_list is the head of a ccwchain list, that contents the 25 + * translated result of the guest channel program that pointed out by 26 + * the iova parameter when calling cp_init. 27 + */ 28 + struct channel_program { 29 + struct list_head ccwchain_list; 30 + union orb orb; 31 + struct device *mdev; 32 + }; 33 + 34 + extern int cp_init(struct channel_program *cp, struct device *mdev, 35 + union orb *orb); 36 + extern void cp_free(struct channel_program *cp); 37 + extern int cp_prefetch(struct channel_program *cp); 38 + extern union orb *cp_get_orb(struct channel_program *cp, u32 intparm, u8 lpm); 39 + extern void cp_update_scsw(struct channel_program *cp, union scsw *scsw); 40 + extern bool cp_iova_pinned(struct channel_program *cp, u64 iova); 41 + 42 + #endif
+308
drivers/s390/cio/vfio_ccw_drv.c
··· 1 + /* 2 + * VFIO based Physical Subchannel device driver 3 + * 4 + * Copyright IBM Corp. 2017 5 + * 6 + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 7 + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> 8 + */ 9 + 10 + #include <linux/module.h> 11 + #include <linux/init.h> 12 + #include <linux/device.h> 13 + #include <linux/slab.h> 14 + #include <linux/uuid.h> 15 + #include <linux/mdev.h> 16 + 17 + #include <asm/isc.h> 18 + 19 + #include "ioasm.h" 20 + #include "css.h" 21 + #include "vfio_ccw_private.h" 22 + 23 + struct workqueue_struct *vfio_ccw_work_q; 24 + 25 + /* 26 + * Helpers 27 + */ 28 + int vfio_ccw_sch_quiesce(struct subchannel *sch) 29 + { 30 + struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); 31 + DECLARE_COMPLETION_ONSTACK(completion); 32 + int iretry, ret = 0; 33 + 34 + spin_lock_irq(sch->lock); 35 + if (!sch->schib.pmcw.ena) 36 + goto out_unlock; 37 + ret = cio_disable_subchannel(sch); 38 + if (ret != -EBUSY) 39 + goto out_unlock; 40 + 41 + do { 42 + iretry = 255; 43 + 44 + ret = cio_cancel_halt_clear(sch, &iretry); 45 + while (ret == -EBUSY) { 46 + /* 47 + * Flush all I/O and wait for 48 + * cancel/halt/clear completion. 49 + */ 50 + private->completion = &completion; 51 + spin_unlock_irq(sch->lock); 52 + 53 + wait_for_completion_timeout(&completion, 3*HZ); 54 + 55 + spin_lock_irq(sch->lock); 56 + private->completion = NULL; 57 + flush_workqueue(vfio_ccw_work_q); 58 + ret = cio_cancel_halt_clear(sch, &iretry); 59 + }; 60 + 61 + ret = cio_disable_subchannel(sch); 62 + } while (ret == -EBUSY); 63 + out_unlock: 64 + private->state = VFIO_CCW_STATE_NOT_OPER; 65 + spin_unlock_irq(sch->lock); 66 + return ret; 67 + } 68 + 69 + static void vfio_ccw_sch_io_todo(struct work_struct *work) 70 + { 71 + struct vfio_ccw_private *private; 72 + struct subchannel *sch; 73 + struct irb *irb; 74 + 75 + private = container_of(work, struct vfio_ccw_private, io_work); 76 + irb = &private->irb; 77 + sch = private->sch; 78 + 79 + if (scsw_is_solicited(&irb->scsw)) { 80 + cp_update_scsw(&private->cp, &irb->scsw); 81 + cp_free(&private->cp); 82 + } 83 + memcpy(private->io_region.irb_area, irb, sizeof(*irb)); 84 + 85 + if (private->io_trigger) 86 + eventfd_signal(private->io_trigger, 1); 87 + 88 + if (private->mdev) 89 + private->state = VFIO_CCW_STATE_IDLE; 90 + } 91 + 92 + /* 93 + * Sysfs interfaces 94 + */ 95 + static ssize_t chpids_show(struct device *dev, 96 + struct device_attribute *attr, 97 + char *buf) 98 + { 99 + struct subchannel *sch = to_subchannel(dev); 100 + struct chsc_ssd_info *ssd = &sch->ssd_info; 101 + ssize_t ret = 0; 102 + int chp; 103 + int mask; 104 + 105 + for (chp = 0; chp < 8; chp++) { 106 + mask = 0x80 >> chp; 107 + if (ssd->path_mask & mask) 108 + ret += sprintf(buf + ret, "%02x ", ssd->chpid[chp].id); 109 + else 110 + ret += sprintf(buf + ret, "00 "); 111 + } 112 + ret += sprintf(buf+ret, "\n"); 113 + return ret; 114 + } 115 + 116 + static ssize_t pimpampom_show(struct device *dev, 117 + struct device_attribute *attr, 118 + char *buf) 119 + { 120 + struct subchannel *sch = to_subchannel(dev); 121 + struct pmcw *pmcw = &sch->schib.pmcw; 122 + 123 + return sprintf(buf, "%02x %02x %02x\n", 124 + pmcw->pim, pmcw->pam, pmcw->pom); 125 + } 126 + 127 + static DEVICE_ATTR(chpids, 0444, chpids_show, NULL); 128 + static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL); 129 + 130 + static struct attribute *vfio_subchannel_attrs[] = { 131 + &dev_attr_chpids.attr, 132 + &dev_attr_pimpampom.attr, 133 + NULL, 134 + }; 135 + 136 + static struct attribute_group vfio_subchannel_attr_group = { 137 + .attrs = vfio_subchannel_attrs, 138 + }; 139 + 140 + /* 141 + * Css driver callbacks 142 + */ 143 + static void vfio_ccw_sch_irq(struct subchannel *sch) 144 + { 145 + struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); 146 + 147 + inc_irq_stat(IRQIO_CIO); 148 + vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT); 149 + } 150 + 151 + static int vfio_ccw_sch_probe(struct subchannel *sch) 152 + { 153 + struct pmcw *pmcw = &sch->schib.pmcw; 154 + struct vfio_ccw_private *private; 155 + int ret; 156 + 157 + if (pmcw->qf) { 158 + dev_warn(&sch->dev, "vfio: ccw: does not support QDIO: %s\n", 159 + dev_name(&sch->dev)); 160 + return -ENODEV; 161 + } 162 + 163 + private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); 164 + if (!private) 165 + return -ENOMEM; 166 + private->sch = sch; 167 + dev_set_drvdata(&sch->dev, private); 168 + 169 + spin_lock_irq(sch->lock); 170 + private->state = VFIO_CCW_STATE_NOT_OPER; 171 + sch->isc = VFIO_CCW_ISC; 172 + ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); 173 + spin_unlock_irq(sch->lock); 174 + if (ret) 175 + goto out_free; 176 + 177 + ret = sysfs_create_group(&sch->dev.kobj, &vfio_subchannel_attr_group); 178 + if (ret) 179 + goto out_disable; 180 + 181 + ret = vfio_ccw_mdev_reg(sch); 182 + if (ret) 183 + goto out_rm_group; 184 + 185 + INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo); 186 + atomic_set(&private->avail, 1); 187 + private->state = VFIO_CCW_STATE_STANDBY; 188 + 189 + return 0; 190 + 191 + out_rm_group: 192 + sysfs_remove_group(&sch->dev.kobj, &vfio_subchannel_attr_group); 193 + out_disable: 194 + cio_disable_subchannel(sch); 195 + out_free: 196 + dev_set_drvdata(&sch->dev, NULL); 197 + kfree(private); 198 + return ret; 199 + } 200 + 201 + static int vfio_ccw_sch_remove(struct subchannel *sch) 202 + { 203 + struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); 204 + 205 + vfio_ccw_sch_quiesce(sch); 206 + 207 + vfio_ccw_mdev_unreg(sch); 208 + 209 + sysfs_remove_group(&sch->dev.kobj, &vfio_subchannel_attr_group); 210 + 211 + dev_set_drvdata(&sch->dev, NULL); 212 + 213 + kfree(private); 214 + 215 + return 0; 216 + } 217 + 218 + static void vfio_ccw_sch_shutdown(struct subchannel *sch) 219 + { 220 + vfio_ccw_sch_quiesce(sch); 221 + } 222 + 223 + /** 224 + * vfio_ccw_sch_event - process subchannel event 225 + * @sch: subchannel 226 + * @process: non-zero if function is called in process context 227 + * 228 + * An unspecified event occurred for this subchannel. Adjust data according 229 + * to the current operational state of the subchannel. Return zero when the 230 + * event has been handled sufficiently or -EAGAIN when this function should 231 + * be called again in process context. 232 + */ 233 + static int vfio_ccw_sch_event(struct subchannel *sch, int process) 234 + { 235 + struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); 236 + unsigned long flags; 237 + 238 + spin_lock_irqsave(sch->lock, flags); 239 + if (!device_is_registered(&sch->dev)) 240 + goto out_unlock; 241 + 242 + if (work_pending(&sch->todo_work)) 243 + goto out_unlock; 244 + 245 + if (cio_update_schib(sch)) { 246 + vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); 247 + goto out_unlock; 248 + } 249 + 250 + private = dev_get_drvdata(&sch->dev); 251 + if (private->state == VFIO_CCW_STATE_NOT_OPER) { 252 + private->state = private->mdev ? VFIO_CCW_STATE_IDLE : 253 + VFIO_CCW_STATE_STANDBY; 254 + } 255 + 256 + out_unlock: 257 + spin_unlock_irqrestore(sch->lock, flags); 258 + 259 + return 0; 260 + } 261 + 262 + static struct css_device_id vfio_ccw_sch_ids[] = { 263 + { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, }, 264 + { /* end of list */ }, 265 + }; 266 + MODULE_DEVICE_TABLE(css, vfio_ccw_sch_ids); 267 + 268 + static struct css_driver vfio_ccw_sch_driver = { 269 + .drv = { 270 + .name = "vfio_ccw", 271 + .owner = THIS_MODULE, 272 + }, 273 + .subchannel_type = vfio_ccw_sch_ids, 274 + .irq = vfio_ccw_sch_irq, 275 + .probe = vfio_ccw_sch_probe, 276 + .remove = vfio_ccw_sch_remove, 277 + .shutdown = vfio_ccw_sch_shutdown, 278 + .sch_event = vfio_ccw_sch_event, 279 + }; 280 + 281 + static int __init vfio_ccw_sch_init(void) 282 + { 283 + int ret; 284 + 285 + vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw"); 286 + if (!vfio_ccw_work_q) 287 + return -ENOMEM; 288 + 289 + isc_register(VFIO_CCW_ISC); 290 + ret = css_driver_register(&vfio_ccw_sch_driver); 291 + if (ret) { 292 + isc_unregister(VFIO_CCW_ISC); 293 + destroy_workqueue(vfio_ccw_work_q); 294 + } 295 + 296 + return ret; 297 + } 298 + 299 + static void __exit vfio_ccw_sch_exit(void) 300 + { 301 + css_driver_unregister(&vfio_ccw_sch_driver); 302 + isc_unregister(VFIO_CCW_ISC); 303 + destroy_workqueue(vfio_ccw_work_q); 304 + } 305 + module_init(vfio_ccw_sch_init); 306 + module_exit(vfio_ccw_sch_exit); 307 + 308 + MODULE_LICENSE("GPL v2");
+207
drivers/s390/cio/vfio_ccw_fsm.c
··· 1 + /* 2 + * Finite state machine for vfio-ccw device handling 3 + * 4 + * Copyright IBM Corp. 2017 5 + * 6 + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 7 + */ 8 + 9 + #include <linux/vfio.h> 10 + #include <linux/mdev.h> 11 + 12 + #include "ioasm.h" 13 + #include "vfio_ccw_private.h" 14 + 15 + static int fsm_io_helper(struct vfio_ccw_private *private) 16 + { 17 + struct subchannel *sch; 18 + union orb *orb; 19 + int ccode; 20 + __u8 lpm; 21 + unsigned long flags; 22 + 23 + sch = private->sch; 24 + 25 + spin_lock_irqsave(sch->lock, flags); 26 + private->state = VFIO_CCW_STATE_BUSY; 27 + spin_unlock_irqrestore(sch->lock, flags); 28 + 29 + orb = cp_get_orb(&private->cp, (u32)(addr_t)sch, sch->lpm); 30 + 31 + /* Issue "Start Subchannel" */ 32 + ccode = ssch(sch->schid, orb); 33 + 34 + switch (ccode) { 35 + case 0: 36 + /* 37 + * Initialize device status information 38 + */ 39 + sch->schib.scsw.cmd.actl |= SCSW_ACTL_START_PEND; 40 + return 0; 41 + case 1: /* Status pending */ 42 + case 2: /* Busy */ 43 + return -EBUSY; 44 + case 3: /* Device/path not operational */ 45 + { 46 + lpm = orb->cmd.lpm; 47 + if (lpm != 0) 48 + sch->lpm &= ~lpm; 49 + else 50 + sch->lpm = 0; 51 + 52 + if (cio_update_schib(sch)) 53 + return -ENODEV; 54 + 55 + return sch->lpm ? -EACCES : -ENODEV; 56 + } 57 + default: 58 + return ccode; 59 + } 60 + } 61 + 62 + static void fsm_notoper(struct vfio_ccw_private *private, 63 + enum vfio_ccw_event event) 64 + { 65 + struct subchannel *sch = private->sch; 66 + 67 + /* 68 + * TODO: 69 + * Probably we should send the machine check to the guest. 70 + */ 71 + css_sched_sch_todo(sch, SCH_TODO_UNREG); 72 + private->state = VFIO_CCW_STATE_NOT_OPER; 73 + } 74 + 75 + /* 76 + * No operation action. 77 + */ 78 + static void fsm_nop(struct vfio_ccw_private *private, 79 + enum vfio_ccw_event event) 80 + { 81 + } 82 + 83 + static void fsm_io_error(struct vfio_ccw_private *private, 84 + enum vfio_ccw_event event) 85 + { 86 + pr_err("vfio-ccw: FSM: I/O request from state:%d\n", private->state); 87 + private->io_region.ret_code = -EIO; 88 + } 89 + 90 + static void fsm_io_busy(struct vfio_ccw_private *private, 91 + enum vfio_ccw_event event) 92 + { 93 + private->io_region.ret_code = -EBUSY; 94 + } 95 + 96 + static void fsm_disabled_irq(struct vfio_ccw_private *private, 97 + enum vfio_ccw_event event) 98 + { 99 + struct subchannel *sch = private->sch; 100 + 101 + /* 102 + * An interrupt in a disabled state means a previous disable was not 103 + * successful - should not happen, but we try to disable again. 104 + */ 105 + cio_disable_subchannel(sch); 106 + } 107 + 108 + /* 109 + * Deal with the ccw command request from the userspace. 110 + */ 111 + static void fsm_io_request(struct vfio_ccw_private *private, 112 + enum vfio_ccw_event event) 113 + { 114 + union orb *orb; 115 + union scsw *scsw = &private->scsw; 116 + struct ccw_io_region *io_region = &private->io_region; 117 + struct mdev_device *mdev = private->mdev; 118 + 119 + private->state = VFIO_CCW_STATE_BOXED; 120 + 121 + memcpy(scsw, io_region->scsw_area, sizeof(*scsw)); 122 + 123 + if (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) { 124 + orb = (union orb *)io_region->orb_area; 125 + 126 + io_region->ret_code = cp_init(&private->cp, mdev_dev(mdev), 127 + orb); 128 + if (io_region->ret_code) 129 + goto err_out; 130 + 131 + io_region->ret_code = cp_prefetch(&private->cp); 132 + if (io_region->ret_code) { 133 + cp_free(&private->cp); 134 + goto err_out; 135 + } 136 + 137 + /* Start channel program and wait for I/O interrupt. */ 138 + io_region->ret_code = fsm_io_helper(private); 139 + if (io_region->ret_code) { 140 + cp_free(&private->cp); 141 + goto err_out; 142 + } 143 + return; 144 + } else if (scsw->cmd.fctl & SCSW_FCTL_HALT_FUNC) { 145 + /* XXX: Handle halt. */ 146 + io_region->ret_code = -EOPNOTSUPP; 147 + goto err_out; 148 + } else if (scsw->cmd.fctl & SCSW_FCTL_CLEAR_FUNC) { 149 + /* XXX: Handle clear. */ 150 + io_region->ret_code = -EOPNOTSUPP; 151 + goto err_out; 152 + } 153 + 154 + err_out: 155 + private->state = VFIO_CCW_STATE_IDLE; 156 + } 157 + 158 + /* 159 + * Got an interrupt for a normal io (state busy). 160 + */ 161 + static void fsm_irq(struct vfio_ccw_private *private, 162 + enum vfio_ccw_event event) 163 + { 164 + struct irb *irb; 165 + 166 + if (!private) 167 + return; 168 + 169 + irb = this_cpu_ptr(&cio_irb); 170 + memcpy(&private->irb, irb, sizeof(*irb)); 171 + 172 + queue_work(vfio_ccw_work_q, &private->io_work); 173 + 174 + if (private->completion) 175 + complete(private->completion); 176 + } 177 + 178 + /* 179 + * Device statemachine 180 + */ 181 + fsm_func_t *vfio_ccw_jumptable[NR_VFIO_CCW_STATES][NR_VFIO_CCW_EVENTS] = { 182 + [VFIO_CCW_STATE_NOT_OPER] = { 183 + [VFIO_CCW_EVENT_NOT_OPER] = fsm_nop, 184 + [VFIO_CCW_EVENT_IO_REQ] = fsm_io_error, 185 + [VFIO_CCW_EVENT_INTERRUPT] = fsm_disabled_irq, 186 + }, 187 + [VFIO_CCW_STATE_STANDBY] = { 188 + [VFIO_CCW_EVENT_NOT_OPER] = fsm_notoper, 189 + [VFIO_CCW_EVENT_IO_REQ] = fsm_io_error, 190 + [VFIO_CCW_EVENT_INTERRUPT] = fsm_irq, 191 + }, 192 + [VFIO_CCW_STATE_IDLE] = { 193 + [VFIO_CCW_EVENT_NOT_OPER] = fsm_notoper, 194 + [VFIO_CCW_EVENT_IO_REQ] = fsm_io_request, 195 + [VFIO_CCW_EVENT_INTERRUPT] = fsm_irq, 196 + }, 197 + [VFIO_CCW_STATE_BOXED] = { 198 + [VFIO_CCW_EVENT_NOT_OPER] = fsm_notoper, 199 + [VFIO_CCW_EVENT_IO_REQ] = fsm_io_busy, 200 + [VFIO_CCW_EVENT_INTERRUPT] = fsm_irq, 201 + }, 202 + [VFIO_CCW_STATE_BUSY] = { 203 + [VFIO_CCW_EVENT_NOT_OPER] = fsm_notoper, 204 + [VFIO_CCW_EVENT_IO_REQ] = fsm_io_busy, 205 + [VFIO_CCW_EVENT_INTERRUPT] = fsm_irq, 206 + }, 207 + };
+447
drivers/s390/cio/vfio_ccw_ops.c
··· 1 + /* 2 + * Physical device callbacks for vfio_ccw 3 + * 4 + * Copyright IBM Corp. 2017 5 + * 6 + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 7 + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> 8 + */ 9 + 10 + #include <linux/vfio.h> 11 + #include <linux/mdev.h> 12 + 13 + #include "vfio_ccw_private.h" 14 + 15 + static int vfio_ccw_mdev_reset(struct mdev_device *mdev) 16 + { 17 + struct vfio_ccw_private *private; 18 + struct subchannel *sch; 19 + int ret; 20 + 21 + private = dev_get_drvdata(mdev_parent_dev(mdev)); 22 + if (!private) 23 + return -ENODEV; 24 + 25 + sch = private->sch; 26 + /* 27 + * TODO: 28 + * In the cureent stage, some things like "no I/O running" and "no 29 + * interrupt pending" are clear, but we are not sure what other state 30 + * we need to care about. 31 + * There are still a lot more instructions need to be handled. We 32 + * should come back here later. 33 + */ 34 + ret = vfio_ccw_sch_quiesce(sch); 35 + if (ret) 36 + return ret; 37 + 38 + ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); 39 + if (!ret) 40 + private->state = VFIO_CCW_STATE_IDLE; 41 + 42 + return ret; 43 + } 44 + 45 + static int vfio_ccw_mdev_notifier(struct notifier_block *nb, 46 + unsigned long action, 47 + void *data) 48 + { 49 + struct vfio_ccw_private *private = 50 + container_of(nb, struct vfio_ccw_private, nb); 51 + 52 + if (!private) 53 + return NOTIFY_STOP; 54 + 55 + /* 56 + * Vendor drivers MUST unpin pages in response to an 57 + * invalidation. 58 + */ 59 + if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) { 60 + struct vfio_iommu_type1_dma_unmap *unmap = data; 61 + 62 + if (!cp_iova_pinned(&private->cp, unmap->iova)) 63 + return NOTIFY_OK; 64 + 65 + if (vfio_ccw_mdev_reset(private->mdev)) 66 + return NOTIFY_BAD; 67 + 68 + cp_free(&private->cp); 69 + return NOTIFY_OK; 70 + } 71 + 72 + return NOTIFY_DONE; 73 + } 74 + 75 + static ssize_t name_show(struct kobject *kobj, struct device *dev, char *buf) 76 + { 77 + return sprintf(buf, "I/O subchannel (Non-QDIO)\n"); 78 + } 79 + MDEV_TYPE_ATTR_RO(name); 80 + 81 + static ssize_t device_api_show(struct kobject *kobj, struct device *dev, 82 + char *buf) 83 + { 84 + return sprintf(buf, "%s\n", VFIO_DEVICE_API_CCW_STRING); 85 + } 86 + MDEV_TYPE_ATTR_RO(device_api); 87 + 88 + static ssize_t available_instances_show(struct kobject *kobj, 89 + struct device *dev, char *buf) 90 + { 91 + struct vfio_ccw_private *private = dev_get_drvdata(dev); 92 + 93 + return sprintf(buf, "%d\n", atomic_read(&private->avail)); 94 + } 95 + MDEV_TYPE_ATTR_RO(available_instances); 96 + 97 + static struct attribute *mdev_types_attrs[] = { 98 + &mdev_type_attr_name.attr, 99 + &mdev_type_attr_device_api.attr, 100 + &mdev_type_attr_available_instances.attr, 101 + NULL, 102 + }; 103 + 104 + static struct attribute_group mdev_type_group = { 105 + .name = "io", 106 + .attrs = mdev_types_attrs, 107 + }; 108 + 109 + struct attribute_group *mdev_type_groups[] = { 110 + &mdev_type_group, 111 + NULL, 112 + }; 113 + 114 + static int vfio_ccw_mdev_create(struct kobject *kobj, struct mdev_device *mdev) 115 + { 116 + struct vfio_ccw_private *private = 117 + dev_get_drvdata(mdev_parent_dev(mdev)); 118 + 119 + if (private->state == VFIO_CCW_STATE_NOT_OPER) 120 + return -ENODEV; 121 + 122 + if (atomic_dec_if_positive(&private->avail) < 0) 123 + return -EPERM; 124 + 125 + private->mdev = mdev; 126 + private->state = VFIO_CCW_STATE_IDLE; 127 + 128 + return 0; 129 + } 130 + 131 + static int vfio_ccw_mdev_remove(struct mdev_device *mdev) 132 + { 133 + struct vfio_ccw_private *private = 134 + dev_get_drvdata(mdev_parent_dev(mdev)); 135 + int ret; 136 + 137 + if (!private) 138 + goto out; 139 + 140 + if ((private->state == VFIO_CCW_STATE_NOT_OPER) || 141 + (private->state == VFIO_CCW_STATE_STANDBY)) 142 + goto out; 143 + 144 + ret = vfio_ccw_mdev_reset(mdev); 145 + if (ret) 146 + return ret; 147 + 148 + private->state = VFIO_CCW_STATE_STANDBY; 149 + 150 + out: 151 + private->mdev = NULL; 152 + atomic_inc(&private->avail); 153 + 154 + return 0; 155 + } 156 + 157 + static int vfio_ccw_mdev_open(struct mdev_device *mdev) 158 + { 159 + struct vfio_ccw_private *private = 160 + dev_get_drvdata(mdev_parent_dev(mdev)); 161 + unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP; 162 + 163 + private->nb.notifier_call = vfio_ccw_mdev_notifier; 164 + 165 + return vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, 166 + &events, &private->nb); 167 + } 168 + 169 + void vfio_ccw_mdev_release(struct mdev_device *mdev) 170 + { 171 + struct vfio_ccw_private *private = 172 + dev_get_drvdata(mdev_parent_dev(mdev)); 173 + 174 + vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, 175 + &private->nb); 176 + } 177 + 178 + static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev, 179 + char __user *buf, 180 + size_t count, 181 + loff_t *ppos) 182 + { 183 + struct vfio_ccw_private *private; 184 + struct ccw_io_region *region; 185 + 186 + if (*ppos + count > sizeof(*region)) 187 + return -EINVAL; 188 + 189 + private = dev_get_drvdata(mdev_parent_dev(mdev)); 190 + if (!private) 191 + return -ENODEV; 192 + 193 + region = &private->io_region; 194 + if (copy_to_user(buf, (void *)region + *ppos, count)) 195 + return -EFAULT; 196 + 197 + return count; 198 + } 199 + 200 + static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev, 201 + const char __user *buf, 202 + size_t count, 203 + loff_t *ppos) 204 + { 205 + struct vfio_ccw_private *private; 206 + struct ccw_io_region *region; 207 + 208 + if (*ppos + count > sizeof(*region)) 209 + return -EINVAL; 210 + 211 + private = dev_get_drvdata(mdev_parent_dev(mdev)); 212 + if (!private) 213 + return -ENODEV; 214 + if (private->state != VFIO_CCW_STATE_IDLE) 215 + return -EACCES; 216 + 217 + region = &private->io_region; 218 + if (copy_from_user((void *)region + *ppos, buf, count)) 219 + return -EFAULT; 220 + 221 + vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_IO_REQ); 222 + if (region->ret_code != 0) { 223 + private->state = VFIO_CCW_STATE_IDLE; 224 + return region->ret_code; 225 + } 226 + 227 + return count; 228 + } 229 + 230 + static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info) 231 + { 232 + info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET; 233 + info->num_regions = VFIO_CCW_NUM_REGIONS; 234 + info->num_irqs = VFIO_CCW_NUM_IRQS; 235 + 236 + return 0; 237 + } 238 + 239 + static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info, 240 + u16 *cap_type_id, 241 + void **cap_type) 242 + { 243 + switch (info->index) { 244 + case VFIO_CCW_CONFIG_REGION_INDEX: 245 + info->offset = 0; 246 + info->size = sizeof(struct ccw_io_region); 247 + info->flags = VFIO_REGION_INFO_FLAG_READ 248 + | VFIO_REGION_INFO_FLAG_WRITE; 249 + return 0; 250 + default: 251 + return -EINVAL; 252 + } 253 + } 254 + 255 + int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info) 256 + { 257 + if (info->index != VFIO_CCW_IO_IRQ_INDEX) 258 + return -EINVAL; 259 + 260 + info->count = 1; 261 + info->flags = VFIO_IRQ_INFO_EVENTFD; 262 + 263 + return 0; 264 + } 265 + 266 + static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev, 267 + uint32_t flags, 268 + void __user *data) 269 + { 270 + struct vfio_ccw_private *private; 271 + struct eventfd_ctx **ctx; 272 + 273 + if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER)) 274 + return -EINVAL; 275 + 276 + private = dev_get_drvdata(mdev_parent_dev(mdev)); 277 + if (!private) 278 + return -ENODEV; 279 + 280 + ctx = &private->io_trigger; 281 + 282 + switch (flags & VFIO_IRQ_SET_DATA_TYPE_MASK) { 283 + case VFIO_IRQ_SET_DATA_NONE: 284 + { 285 + if (*ctx) 286 + eventfd_signal(*ctx, 1); 287 + return 0; 288 + } 289 + case VFIO_IRQ_SET_DATA_BOOL: 290 + { 291 + uint8_t trigger; 292 + 293 + if (get_user(trigger, (uint8_t __user *)data)) 294 + return -EFAULT; 295 + 296 + if (trigger && *ctx) 297 + eventfd_signal(*ctx, 1); 298 + return 0; 299 + } 300 + case VFIO_IRQ_SET_DATA_EVENTFD: 301 + { 302 + int32_t fd; 303 + 304 + if (get_user(fd, (int32_t __user *)data)) 305 + return -EFAULT; 306 + 307 + if (fd == -1) { 308 + if (*ctx) 309 + eventfd_ctx_put(*ctx); 310 + *ctx = NULL; 311 + } else if (fd >= 0) { 312 + struct eventfd_ctx *efdctx; 313 + 314 + efdctx = eventfd_ctx_fdget(fd); 315 + if (IS_ERR(efdctx)) 316 + return PTR_ERR(efdctx); 317 + 318 + if (*ctx) 319 + eventfd_ctx_put(*ctx); 320 + 321 + *ctx = efdctx; 322 + } else 323 + return -EINVAL; 324 + 325 + return 0; 326 + } 327 + default: 328 + return -EINVAL; 329 + } 330 + } 331 + 332 + static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, 333 + unsigned int cmd, 334 + unsigned long arg) 335 + { 336 + int ret = 0; 337 + unsigned long minsz; 338 + 339 + switch (cmd) { 340 + case VFIO_DEVICE_GET_INFO: 341 + { 342 + struct vfio_device_info info; 343 + 344 + minsz = offsetofend(struct vfio_device_info, num_irqs); 345 + 346 + if (copy_from_user(&info, (void __user *)arg, minsz)) 347 + return -EFAULT; 348 + 349 + if (info.argsz < minsz) 350 + return -EINVAL; 351 + 352 + ret = vfio_ccw_mdev_get_device_info(&info); 353 + if (ret) 354 + return ret; 355 + 356 + return copy_to_user((void __user *)arg, &info, minsz); 357 + } 358 + case VFIO_DEVICE_GET_REGION_INFO: 359 + { 360 + struct vfio_region_info info; 361 + u16 cap_type_id = 0; 362 + void *cap_type = NULL; 363 + 364 + minsz = offsetofend(struct vfio_region_info, offset); 365 + 366 + if (copy_from_user(&info, (void __user *)arg, minsz)) 367 + return -EFAULT; 368 + 369 + if (info.argsz < minsz) 370 + return -EINVAL; 371 + 372 + ret = vfio_ccw_mdev_get_region_info(&info, &cap_type_id, 373 + &cap_type); 374 + if (ret) 375 + return ret; 376 + 377 + return copy_to_user((void __user *)arg, &info, minsz); 378 + } 379 + case VFIO_DEVICE_GET_IRQ_INFO: 380 + { 381 + struct vfio_irq_info info; 382 + 383 + minsz = offsetofend(struct vfio_irq_info, count); 384 + 385 + if (copy_from_user(&info, (void __user *)arg, minsz)) 386 + return -EFAULT; 387 + 388 + if (info.argsz < minsz || info.index >= VFIO_CCW_NUM_IRQS) 389 + return -EINVAL; 390 + 391 + ret = vfio_ccw_mdev_get_irq_info(&info); 392 + if (ret) 393 + return ret; 394 + 395 + if (info.count == -1) 396 + return -EINVAL; 397 + 398 + return copy_to_user((void __user *)arg, &info, minsz); 399 + } 400 + case VFIO_DEVICE_SET_IRQS: 401 + { 402 + struct vfio_irq_set hdr; 403 + size_t data_size; 404 + void __user *data; 405 + 406 + minsz = offsetofend(struct vfio_irq_set, count); 407 + 408 + if (copy_from_user(&hdr, (void __user *)arg, minsz)) 409 + return -EFAULT; 410 + 411 + ret = vfio_set_irqs_validate_and_prepare(&hdr, 1, 412 + VFIO_CCW_NUM_IRQS, 413 + &data_size); 414 + if (ret) 415 + return ret; 416 + 417 + data = (void __user *)(arg + minsz); 418 + return vfio_ccw_mdev_set_irqs(mdev, hdr.flags, data); 419 + } 420 + case VFIO_DEVICE_RESET: 421 + return vfio_ccw_mdev_reset(mdev); 422 + default: 423 + return -ENOTTY; 424 + } 425 + } 426 + 427 + static const struct mdev_parent_ops vfio_ccw_mdev_ops = { 428 + .owner = THIS_MODULE, 429 + .supported_type_groups = mdev_type_groups, 430 + .create = vfio_ccw_mdev_create, 431 + .remove = vfio_ccw_mdev_remove, 432 + .open = vfio_ccw_mdev_open, 433 + .release = vfio_ccw_mdev_release, 434 + .read = vfio_ccw_mdev_read, 435 + .write = vfio_ccw_mdev_write, 436 + .ioctl = vfio_ccw_mdev_ioctl, 437 + }; 438 + 439 + int vfio_ccw_mdev_reg(struct subchannel *sch) 440 + { 441 + return mdev_register_device(&sch->dev, &vfio_ccw_mdev_ops); 442 + } 443 + 444 + void vfio_ccw_mdev_unreg(struct subchannel *sch) 445 + { 446 + mdev_unregister_device(&sch->dev); 447 + }
+96
drivers/s390/cio/vfio_ccw_private.h
··· 1 + /* 2 + * Private stuff for vfio_ccw driver 3 + * 4 + * Copyright IBM Corp. 2017 5 + * 6 + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 7 + * Xiao Feng Ren <renxiaof@linux.vnet.ibm.com> 8 + */ 9 + 10 + #ifndef _VFIO_CCW_PRIVATE_H_ 11 + #define _VFIO_CCW_PRIVATE_H_ 12 + 13 + #include <linux/completion.h> 14 + #include <linux/eventfd.h> 15 + #include <linux/workqueue.h> 16 + #include <linux/vfio_ccw.h> 17 + 18 + #include "css.h" 19 + #include "vfio_ccw_cp.h" 20 + 21 + /** 22 + * struct vfio_ccw_private 23 + * @sch: pointer to the subchannel 24 + * @state: internal state of the device 25 + * @completion: synchronization helper of the I/O completion 26 + * @avail: available for creating a mediated device 27 + * @mdev: pointer to the mediated device 28 + * @nb: notifier for vfio events 29 + * @io_region: MMIO region to input/output I/O arguments/results 30 + * @cp: channel program for the current I/O operation 31 + * @irb: irb info received from interrupt 32 + * @scsw: scsw info 33 + * @io_trigger: eventfd ctx for signaling userspace I/O results 34 + * @io_work: work for deferral process of I/O handling 35 + */ 36 + struct vfio_ccw_private { 37 + struct subchannel *sch; 38 + int state; 39 + struct completion *completion; 40 + atomic_t avail; 41 + struct mdev_device *mdev; 42 + struct notifier_block nb; 43 + struct ccw_io_region io_region; 44 + 45 + struct channel_program cp; 46 + struct irb irb; 47 + union scsw scsw; 48 + 49 + struct eventfd_ctx *io_trigger; 50 + struct work_struct io_work; 51 + } __aligned(8); 52 + 53 + extern int vfio_ccw_mdev_reg(struct subchannel *sch); 54 + extern void vfio_ccw_mdev_unreg(struct subchannel *sch); 55 + 56 + extern int vfio_ccw_sch_quiesce(struct subchannel *sch); 57 + 58 + /* 59 + * States of the device statemachine. 60 + */ 61 + enum vfio_ccw_state { 62 + VFIO_CCW_STATE_NOT_OPER, 63 + VFIO_CCW_STATE_STANDBY, 64 + VFIO_CCW_STATE_IDLE, 65 + VFIO_CCW_STATE_BOXED, 66 + VFIO_CCW_STATE_BUSY, 67 + /* last element! */ 68 + NR_VFIO_CCW_STATES 69 + }; 70 + 71 + /* 72 + * Asynchronous events of the device statemachine. 73 + */ 74 + enum vfio_ccw_event { 75 + VFIO_CCW_EVENT_NOT_OPER, 76 + VFIO_CCW_EVENT_IO_REQ, 77 + VFIO_CCW_EVENT_INTERRUPT, 78 + /* last element! */ 79 + NR_VFIO_CCW_EVENTS 80 + }; 81 + 82 + /* 83 + * Action called through jumptable. 84 + */ 85 + typedef void (fsm_func_t)(struct vfio_ccw_private *, enum vfio_ccw_event); 86 + extern fsm_func_t *vfio_ccw_jumptable[NR_VFIO_CCW_STATES][NR_VFIO_CCW_EVENTS]; 87 + 88 + static inline void vfio_ccw_fsm_event(struct vfio_ccw_private *private, 89 + int event) 90 + { 91 + vfio_ccw_jumptable[private->state][event](private, event); 92 + } 93 + 94 + extern struct workqueue_struct *vfio_ccw_work_q; 95 + 96 + #endif
+18
include/uapi/linux/vfio.h
··· 198 198 #define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */ 199 199 #define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2) /* vfio-platform device */ 200 200 #define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */ 201 + #define VFIO_DEVICE_FLAGS_CCW (1 << 4) /* vfio-ccw device */ 201 202 __u32 num_regions; /* Max region index + 1 */ 202 203 __u32 num_irqs; /* Max IRQ index + 1 */ 203 204 }; ··· 213 212 #define VFIO_DEVICE_API_PCI_STRING "vfio-pci" 214 213 #define VFIO_DEVICE_API_PLATFORM_STRING "vfio-platform" 215 214 #define VFIO_DEVICE_API_AMBA_STRING "vfio-amba" 215 + #define VFIO_DEVICE_API_CCW_STRING "vfio-ccw" 216 216 217 217 /** 218 218 * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8, ··· 446 444 VFIO_PCI_ERR_IRQ_INDEX, 447 445 VFIO_PCI_REQ_IRQ_INDEX, 448 446 VFIO_PCI_NUM_IRQS 447 + }; 448 + 449 + /* 450 + * The vfio-ccw bus driver makes use of the following fixed region and 451 + * IRQ index mapping. Unimplemented regions return a size of zero. 452 + * Unimplemented IRQ types return a count of zero. 453 + */ 454 + 455 + enum { 456 + VFIO_CCW_CONFIG_REGION_INDEX, 457 + VFIO_CCW_NUM_REGIONS 458 + }; 459 + 460 + enum { 461 + VFIO_CCW_IO_IRQ_INDEX, 462 + VFIO_CCW_NUM_IRQS 449 463 }; 450 464 451 465 /**
+24
include/uapi/linux/vfio_ccw.h
··· 1 + /* 2 + * Interfaces for vfio-ccw 3 + * 4 + * Copyright IBM Corp. 2017 5 + * 6 + * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> 7 + */ 8 + 9 + #ifndef _VFIO_CCW_H_ 10 + #define _VFIO_CCW_H_ 11 + 12 + #include <linux/types.h> 13 + 14 + struct ccw_io_region { 15 + #define ORB_AREA_SIZE 12 16 + __u8 orb_area[ORB_AREA_SIZE]; 17 + #define SCSW_AREA_SIZE 12 18 + __u8 scsw_area[SCSW_AREA_SIZE]; 19 + #define IRB_AREA_SIZE 96 20 + __u8 irb_area[IRB_AREA_SIZE]; 21 + __u32 ret_code; 22 + } __packed; 23 + 24 + #endif