Introduce device information about vfio-ccw: VFIO_DEVICE_FLAGS_CCW. Realize VFIO_DEVICE_GET_REGION_INFO ioctl for vfio-ccw.
Unified · Split
| @@ -188,6 +188,83 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev, · 187 unmodified lines | ||
| 188 | 188 | return count; |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | +static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info) | |
| 192 | +{ | |
| 193 | + info->flags = VFIO_DEVICE_FLAGS_CCW; | |
| 194 | + info->num_regions = VFIO_CCW_NUM_REGIONS; | |
| 195 | + info->num_irqs = 0; | |
| 196 | + | |
| 197 | + return 0; | |
| 198 | +} | |
| 199 | + | |
| 200 | +static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info, | |
| 201 | + u16 *cap_type_id, | |
| 202 | + void **cap_type) | |
| 203 | +{ | |
| 204 | + switch (info->index) { | |
| 205 | + case VFIO_CCW_CONFIG_REGION_INDEX: | |
| 206 | + info->offset = 0; | |
| 207 | + info->size = sizeof(struct ccw_io_region); | |
| 208 | + info->flags = VFIO_REGION_INFO_FLAG_READ | |
| 209 | + | VFIO_REGION_INFO_FLAG_WRITE; | |
| 210 | + return 0; | |
| 211 | + default: | |
| 212 | + return -EINVAL; | |
| 213 | + } | |
| 214 | +} | |
| 215 | + | |
| 216 | +static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, | |
| 217 | + unsigned int cmd, | |
| 218 | + unsigned long arg) | |
| 219 | +{ | |
| 220 | + int ret = 0; | |
| 221 | + unsigned long minsz; | |
| 222 | + | |
| 223 | + switch (cmd) { | |
| 224 | + case VFIO_DEVICE_GET_INFO: | |
| 225 | + { | |
| 226 | + struct vfio_device_info info; | |
| 227 | + | |
| 228 | + minsz = offsetofend(struct vfio_device_info, num_irqs); | |
| 229 | + | |
| 230 | + if (copy_from_user(&info, (void __user *)arg, minsz)) | |
| 231 | + return -EFAULT; | |
| 232 | + | |
| 233 | + if (info.argsz < minsz) | |
| 234 | + return -EINVAL; | |
| 235 | + | |
| 236 | + ret = vfio_ccw_mdev_get_device_info(&info); | |
| 237 | + if (ret) | |
| 238 | + return ret; | |
| 239 | + | |
| 240 | + return copy_to_user((void __user *)arg, &info, minsz); | |
| 241 | + } | |
| 242 | + case VFIO_DEVICE_GET_REGION_INFO: | |
| 243 | + { | |
| 244 | + struct vfio_region_info info; | |
| 245 | + u16 cap_type_id = 0; | |
| 246 | + void *cap_type = NULL; | |
| 247 | + | |
| 248 | + minsz = offsetofend(struct vfio_region_info, offset); | |
| 249 | + | |
| 250 | + if (copy_from_user(&info, (void __user *)arg, minsz)) | |
| 251 | + return -EFAULT; | |
| 252 | + | |
| 253 | + if (info.argsz < minsz) | |
| 254 | + return -EINVAL; | |
| 255 | + | |
| 256 | + ret = vfio_ccw_mdev_get_region_info(&info, &cap_type_id, | |
| 257 | + &cap_type); | |
| 258 | + if (ret) | |
| 259 | + return ret; | |
| 260 | + | |
| 261 | + return copy_to_user((void __user *)arg, &info, minsz); | |
| 262 | + } | |
| 263 | + default: | |
| 264 | + return -ENOTTY; | |
| 265 | + } | |
| 266 | +} | |
| 267 | + | |
| 191 | 268 | static const struct mdev_parent_ops vfio_ccw_mdev_ops = { |
| 192 | 269 | .owner = THIS_MODULE, |
| 193 | 270 | .supported_type_groups = mdev_type_groups, |
| @@ -197,6 +274,7 @@ static const struct mdev_parent_ops vfio_ccw_mdev_ops = { · 3 unmodified lines | ||
| 197 | 274 | .release = vfio_ccw_mdev_release, |
| 198 | 275 | .read = vfio_ccw_mdev_read, |
| 199 | 276 | .write = vfio_ccw_mdev_write, |
| 277 | + .ioctl = vfio_ccw_mdev_ioctl, | |
| 200 | 278 | }; |
| 201 | 279 | |
| 202 | 280 | int vfio_ccw_mdev_reg(struct subchannel *sch) |
| @@ -198,6 +198,7 @@ struct vfio_device_info { · 197 unmodified lines | ||
| 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 | }; |
| @@ -447,6 +448,16 @@ enum { · 243 unmodified lines | ||
| 447 | 448 | VFIO_PCI_NUM_IRQS |
| 448 | 449 | }; |
| 449 | 450 | |
| 451 | +/* | |
| 452 | + * The vfio-ccw bus driver makes use of the following fixed region. | |
| 453 | + * Unimplemented regions return a size of zero. | |
| 454 | + */ | |
| 455 | + | |
| 456 | +enum { | |
| 457 | + VFIO_CCW_CONFIG_REGION_INDEX, | |
| 458 | + VFIO_CCW_NUM_REGIONS | |
| 459 | +}; | |
| 460 | + | |
| 450 | 461 | /** |
| 451 | 462 | * VFIO_DEVICE_GET_PCI_HOT_RESET_INFO - _IORW(VFIO_TYPE, VFIO_BASE + 12, |
| 452 | 463 | * struct vfio_pci_hot_reset_info) |