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 | return count; | 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 | static const struct mdev_parent_ops vfio_ccw_mdev_ops = { | 268 | static const struct mdev_parent_ops vfio_ccw_mdev_ops = { |
| 192 | .owner = THIS_MODULE, | 269 | .owner = THIS_MODULE, |
| 193 | .supported_type_groups = mdev_type_groups, | 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 | .release = vfio_ccw_mdev_release, | 274 | .release = vfio_ccw_mdev_release, |
| 198 | .read = vfio_ccw_mdev_read, | 275 | .read = vfio_ccw_mdev_read, |
| 199 | .write = vfio_ccw_mdev_write, | 276 | .write = vfio_ccw_mdev_write, |
| 277 | .ioctl = vfio_ccw_mdev_ioctl, | ||
| 200 | }; | 278 | }; |
| 201 | 279 | ||
| 202 | int vfio_ccw_mdev_reg(struct subchannel *sch) | 280 | int vfio_ccw_mdev_reg(struct subchannel *sch) |
| @@ -198,6 +198,7 @@ struct vfio_device_info { · 197 unmodified lines | |||
| 198 | #define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */ | 198 | #define VFIO_DEVICE_FLAGS_PCI (1 << 1) /* vfio-pci device */ |
| 199 | #define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2) /* vfio-platform device */ | 199 | #define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2) /* vfio-platform device */ |
| 200 | #define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */ | 200 | #define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */ |
| 201 | #define VFIO_DEVICE_FLAGS_CCW (1 << 4) /* vfio-ccw device */ | ||
| 201 | __u32 num_regions; /* Max region index + 1 */ | 202 | __u32 num_regions; /* Max region index + 1 */ |
| 202 | __u32 num_irqs; /* Max IRQ index + 1 */ | 203 | __u32 num_irqs; /* Max IRQ index + 1 */ |
| 203 | }; | 204 | }; |
| @@ -447,6 +448,16 @@ enum { · 243 unmodified lines | |||
| 447 | VFIO_PCI_NUM_IRQS | 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 | * VFIO_DEVICE_GET_PCI_HOT_RESET_INFO - _IORW(VFIO_TYPE, VFIO_BASE + 12, | 462 | * VFIO_DEVICE_GET_PCI_HOT_RESET_INFO - _IORW(VFIO_TYPE, VFIO_BASE + 12, |
| 452 | * struct vfio_pci_hot_reset_info) | 463 | * struct vfio_pci_hot_reset_info) |