root/drivers/s390/cio/vfio_ccw_ops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vfio_ccw_mdev_reset
  2. vfio_ccw_mdev_notifier
  3. name_show
  4. device_api_show
  5. available_instances_show
  6. vfio_ccw_mdev_create
  7. vfio_ccw_mdev_remove
  8. vfio_ccw_mdev_open
  9. vfio_ccw_mdev_release
  10. vfio_ccw_mdev_read_io_region
  11. vfio_ccw_mdev_read
  12. vfio_ccw_mdev_write_io_region
  13. vfio_ccw_mdev_write
  14. vfio_ccw_mdev_get_device_info
  15. vfio_ccw_mdev_get_region_info
  16. vfio_ccw_mdev_get_irq_info
  17. vfio_ccw_mdev_set_irqs
  18. vfio_ccw_register_dev_region
  19. vfio_ccw_mdev_ioctl
  20. vfio_ccw_mdev_reg
  21. vfio_ccw_mdev_unreg

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Physical device callbacks for vfio_ccw
   4  *
   5  * Copyright IBM Corp. 2017
   6  * Copyright Red Hat, Inc. 2019
   7  *
   8  * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
   9  *            Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
  10  *            Cornelia Huck <cohuck@redhat.com>
  11  */
  12 
  13 #include <linux/vfio.h>
  14 #include <linux/mdev.h>
  15 #include <linux/nospec.h>
  16 #include <linux/slab.h>
  17 
  18 #include "vfio_ccw_private.h"
  19 
  20 static int vfio_ccw_mdev_reset(struct mdev_device *mdev)
  21 {
  22         struct vfio_ccw_private *private;
  23         struct subchannel *sch;
  24         int ret;
  25 
  26         private = dev_get_drvdata(mdev_parent_dev(mdev));
  27         sch = private->sch;
  28         /*
  29          * TODO:
  30          * In the cureent stage, some things like "no I/O running" and "no
  31          * interrupt pending" are clear, but we are not sure what other state
  32          * we need to care about.
  33          * There are still a lot more instructions need to be handled. We
  34          * should come back here later.
  35          */
  36         ret = vfio_ccw_sch_quiesce(sch);
  37         if (ret)
  38                 return ret;
  39 
  40         ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
  41         if (!ret)
  42                 private->state = VFIO_CCW_STATE_IDLE;
  43 
  44         return ret;
  45 }
  46 
  47 static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
  48                                   unsigned long action,
  49                                   void *data)
  50 {
  51         struct vfio_ccw_private *private =
  52                 container_of(nb, struct vfio_ccw_private, nb);
  53 
  54         /*
  55          * Vendor drivers MUST unpin pages in response to an
  56          * invalidation.
  57          */
  58         if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
  59                 struct vfio_iommu_type1_dma_unmap *unmap = data;
  60 
  61                 if (!cp_iova_pinned(&private->cp, unmap->iova))
  62                         return NOTIFY_OK;
  63 
  64                 if (vfio_ccw_mdev_reset(private->mdev))
  65                         return NOTIFY_BAD;
  66 
  67                 cp_free(&private->cp);
  68                 return NOTIFY_OK;
  69         }
  70 
  71         return NOTIFY_DONE;
  72 }
  73 
  74 static ssize_t name_show(struct kobject *kobj, struct device *dev, char *buf)
  75 {
  76         return sprintf(buf, "I/O subchannel (Non-QDIO)\n");
  77 }
  78 static MDEV_TYPE_ATTR_RO(name);
  79 
  80 static ssize_t device_api_show(struct kobject *kobj, struct device *dev,
  81                                char *buf)
  82 {
  83         return sprintf(buf, "%s\n", VFIO_DEVICE_API_CCW_STRING);
  84 }
  85 static MDEV_TYPE_ATTR_RO(device_api);
  86 
  87 static ssize_t available_instances_show(struct kobject *kobj,
  88                                         struct device *dev, char *buf)
  89 {
  90         struct vfio_ccw_private *private = dev_get_drvdata(dev);
  91 
  92         return sprintf(buf, "%d\n", atomic_read(&private->avail));
  93 }
  94 static MDEV_TYPE_ATTR_RO(available_instances);
  95 
  96 static struct attribute *mdev_types_attrs[] = {
  97         &mdev_type_attr_name.attr,
  98         &mdev_type_attr_device_api.attr,
  99         &mdev_type_attr_available_instances.attr,
 100         NULL,
 101 };
 102 
 103 static struct attribute_group mdev_type_group = {
 104         .name  = "io",
 105         .attrs = mdev_types_attrs,
 106 };
 107 
 108 static struct attribute_group *mdev_type_groups[] = {
 109         &mdev_type_group,
 110         NULL,
 111 };
 112 
 113 static int vfio_ccw_mdev_create(struct kobject *kobj, struct mdev_device *mdev)
 114 {
 115         struct vfio_ccw_private *private =
 116                 dev_get_drvdata(mdev_parent_dev(mdev));
 117 
 118         if (private->state == VFIO_CCW_STATE_NOT_OPER)
 119                 return -ENODEV;
 120 
 121         if (atomic_dec_if_positive(&private->avail) < 0)
 122                 return -EPERM;
 123 
 124         private->mdev = mdev;
 125         private->state = VFIO_CCW_STATE_IDLE;
 126 
 127         VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: create\n",
 128                            mdev_uuid(mdev), private->sch->schid.cssid,
 129                            private->sch->schid.ssid,
 130                            private->sch->schid.sch_no);
 131 
 132         return 0;
 133 }
 134 
 135 static int vfio_ccw_mdev_remove(struct mdev_device *mdev)
 136 {
 137         struct vfio_ccw_private *private =
 138                 dev_get_drvdata(mdev_parent_dev(mdev));
 139 
 140         VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: remove\n",
 141                            mdev_uuid(mdev), private->sch->schid.cssid,
 142                            private->sch->schid.ssid,
 143                            private->sch->schid.sch_no);
 144 
 145         if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
 146             (private->state != VFIO_CCW_STATE_STANDBY)) {
 147                 if (!vfio_ccw_sch_quiesce(private->sch))
 148                         private->state = VFIO_CCW_STATE_STANDBY;
 149                 /* The state will be NOT_OPER on error. */
 150         }
 151 
 152         cp_free(&private->cp);
 153         private->mdev = NULL;
 154         atomic_inc(&private->avail);
 155 
 156         return 0;
 157 }
 158 
 159 static int vfio_ccw_mdev_open(struct mdev_device *mdev)
 160 {
 161         struct vfio_ccw_private *private =
 162                 dev_get_drvdata(mdev_parent_dev(mdev));
 163         unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
 164         int ret;
 165 
 166         private->nb.notifier_call = vfio_ccw_mdev_notifier;
 167 
 168         ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
 169                                      &events, &private->nb);
 170         if (ret)
 171                 return ret;
 172 
 173         ret = vfio_ccw_register_async_dev_regions(private);
 174         if (ret)
 175                 vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
 176                                          &private->nb);
 177         return ret;
 178 }
 179 
 180 static void vfio_ccw_mdev_release(struct mdev_device *mdev)
 181 {
 182         struct vfio_ccw_private *private =
 183                 dev_get_drvdata(mdev_parent_dev(mdev));
 184         int i;
 185 
 186         if ((private->state != VFIO_CCW_STATE_NOT_OPER) &&
 187             (private->state != VFIO_CCW_STATE_STANDBY)) {
 188                 if (!vfio_ccw_mdev_reset(mdev))
 189                         private->state = VFIO_CCW_STATE_STANDBY;
 190                 /* The state will be NOT_OPER on error. */
 191         }
 192 
 193         cp_free(&private->cp);
 194         vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
 195                                  &private->nb);
 196 
 197         for (i = 0; i < private->num_regions; i++)
 198                 private->region[i].ops->release(private, &private->region[i]);
 199 
 200         private->num_regions = 0;
 201         kfree(private->region);
 202         private->region = NULL;
 203 }
 204 
 205 static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
 206                                             char __user *buf, size_t count,
 207                                             loff_t *ppos)
 208 {
 209         loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;
 210         struct ccw_io_region *region;
 211         int ret;
 212 
 213         if (pos + count > sizeof(*region))
 214                 return -EINVAL;
 215 
 216         mutex_lock(&private->io_mutex);
 217         region = private->io_region;
 218         if (copy_to_user(buf, (void *)region + pos, count))
 219                 ret = -EFAULT;
 220         else
 221                 ret = count;
 222         mutex_unlock(&private->io_mutex);
 223         return ret;
 224 }
 225 
 226 static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev,
 227                                   char __user *buf,
 228                                   size_t count,
 229                                   loff_t *ppos)
 230 {
 231         unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
 232         struct vfio_ccw_private *private;
 233 
 234         private = dev_get_drvdata(mdev_parent_dev(mdev));
 235 
 236         if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
 237                 return -EINVAL;
 238 
 239         switch (index) {
 240         case VFIO_CCW_CONFIG_REGION_INDEX:
 241                 return vfio_ccw_mdev_read_io_region(private, buf, count, ppos);
 242         default:
 243                 index -= VFIO_CCW_NUM_REGIONS;
 244                 return private->region[index].ops->read(private, buf, count,
 245                                                         ppos);
 246         }
 247 
 248         return -EINVAL;
 249 }
 250 
 251 static ssize_t vfio_ccw_mdev_write_io_region(struct vfio_ccw_private *private,
 252                                              const char __user *buf,
 253                                              size_t count, loff_t *ppos)
 254 {
 255         loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;
 256         struct ccw_io_region *region;
 257         int ret;
 258 
 259         if (pos + count > sizeof(*region))
 260                 return -EINVAL;
 261 
 262         if (!mutex_trylock(&private->io_mutex))
 263                 return -EAGAIN;
 264 
 265         region = private->io_region;
 266         if (copy_from_user((void *)region + pos, buf, count)) {
 267                 ret = -EFAULT;
 268                 goto out_unlock;
 269         }
 270 
 271         vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_IO_REQ);
 272         if (region->ret_code != 0)
 273                 private->state = VFIO_CCW_STATE_IDLE;
 274         ret = (region->ret_code != 0) ? region->ret_code : count;
 275 
 276 out_unlock:
 277         mutex_unlock(&private->io_mutex);
 278         return ret;
 279 }
 280 
 281 static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev,
 282                                    const char __user *buf,
 283                                    size_t count,
 284                                    loff_t *ppos)
 285 {
 286         unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos);
 287         struct vfio_ccw_private *private;
 288 
 289         private = dev_get_drvdata(mdev_parent_dev(mdev));
 290 
 291         if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions)
 292                 return -EINVAL;
 293 
 294         switch (index) {
 295         case VFIO_CCW_CONFIG_REGION_INDEX:
 296                 return vfio_ccw_mdev_write_io_region(private, buf, count, ppos);
 297         default:
 298                 index -= VFIO_CCW_NUM_REGIONS;
 299                 return private->region[index].ops->write(private, buf, count,
 300                                                          ppos);
 301         }
 302 
 303         return -EINVAL;
 304 }
 305 
 306 static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info,
 307                                          struct mdev_device *mdev)
 308 {
 309         struct vfio_ccw_private *private;
 310 
 311         private = dev_get_drvdata(mdev_parent_dev(mdev));
 312         info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET;
 313         info->num_regions = VFIO_CCW_NUM_REGIONS + private->num_regions;
 314         info->num_irqs = VFIO_CCW_NUM_IRQS;
 315 
 316         return 0;
 317 }
 318 
 319 static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info,
 320                                          struct mdev_device *mdev,
 321                                          unsigned long arg)
 322 {
 323         struct vfio_ccw_private *private;
 324         int i;
 325 
 326         private = dev_get_drvdata(mdev_parent_dev(mdev));
 327         switch (info->index) {
 328         case VFIO_CCW_CONFIG_REGION_INDEX:
 329                 info->offset = 0;
 330                 info->size = sizeof(struct ccw_io_region);
 331                 info->flags = VFIO_REGION_INFO_FLAG_READ
 332                               | VFIO_REGION_INFO_FLAG_WRITE;
 333                 return 0;
 334         default: /* all other regions are handled via capability chain */
 335         {
 336                 struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
 337                 struct vfio_region_info_cap_type cap_type = {
 338                         .header.id = VFIO_REGION_INFO_CAP_TYPE,
 339                         .header.version = 1 };
 340                 int ret;
 341 
 342                 if (info->index >=
 343                     VFIO_CCW_NUM_REGIONS + private->num_regions)
 344                         return -EINVAL;
 345 
 346                 info->index = array_index_nospec(info->index,
 347                                                  VFIO_CCW_NUM_REGIONS +
 348                                                  private->num_regions);
 349 
 350                 i = info->index - VFIO_CCW_NUM_REGIONS;
 351 
 352                 info->offset = VFIO_CCW_INDEX_TO_OFFSET(info->index);
 353                 info->size = private->region[i].size;
 354                 info->flags = private->region[i].flags;
 355 
 356                 cap_type.type = private->region[i].type;
 357                 cap_type.subtype = private->region[i].subtype;
 358 
 359                 ret = vfio_info_add_capability(&caps, &cap_type.header,
 360                                                sizeof(cap_type));
 361                 if (ret)
 362                         return ret;
 363 
 364                 info->flags |= VFIO_REGION_INFO_FLAG_CAPS;
 365                 if (info->argsz < sizeof(*info) + caps.size) {
 366                         info->argsz = sizeof(*info) + caps.size;
 367                         info->cap_offset = 0;
 368                 } else {
 369                         vfio_info_cap_shift(&caps, sizeof(*info));
 370                         if (copy_to_user((void __user *)arg + sizeof(*info),
 371                                          caps.buf, caps.size)) {
 372                                 kfree(caps.buf);
 373                                 return -EFAULT;
 374                         }
 375                         info->cap_offset = sizeof(*info);
 376                 }
 377 
 378                 kfree(caps.buf);
 379 
 380         }
 381         }
 382         return 0;
 383 }
 384 
 385 static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info)
 386 {
 387         if (info->index != VFIO_CCW_IO_IRQ_INDEX)
 388                 return -EINVAL;
 389 
 390         info->count = 1;
 391         info->flags = VFIO_IRQ_INFO_EVENTFD;
 392 
 393         return 0;
 394 }
 395 
 396 static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev,
 397                                   uint32_t flags,
 398                                   void __user *data)
 399 {
 400         struct vfio_ccw_private *private;
 401         struct eventfd_ctx **ctx;
 402 
 403         if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER))
 404                 return -EINVAL;
 405 
 406         private = dev_get_drvdata(mdev_parent_dev(mdev));
 407         ctx = &private->io_trigger;
 408 
 409         switch (flags & VFIO_IRQ_SET_DATA_TYPE_MASK) {
 410         case VFIO_IRQ_SET_DATA_NONE:
 411         {
 412                 if (*ctx)
 413                         eventfd_signal(*ctx, 1);
 414                 return 0;
 415         }
 416         case VFIO_IRQ_SET_DATA_BOOL:
 417         {
 418                 uint8_t trigger;
 419 
 420                 if (get_user(trigger, (uint8_t __user *)data))
 421                         return -EFAULT;
 422 
 423                 if (trigger && *ctx)
 424                         eventfd_signal(*ctx, 1);
 425                 return 0;
 426         }
 427         case VFIO_IRQ_SET_DATA_EVENTFD:
 428         {
 429                 int32_t fd;
 430 
 431                 if (get_user(fd, (int32_t __user *)data))
 432                         return -EFAULT;
 433 
 434                 if (fd == -1) {
 435                         if (*ctx)
 436                                 eventfd_ctx_put(*ctx);
 437                         *ctx = NULL;
 438                 } else if (fd >= 0) {
 439                         struct eventfd_ctx *efdctx;
 440 
 441                         efdctx = eventfd_ctx_fdget(fd);
 442                         if (IS_ERR(efdctx))
 443                                 return PTR_ERR(efdctx);
 444 
 445                         if (*ctx)
 446                                 eventfd_ctx_put(*ctx);
 447 
 448                         *ctx = efdctx;
 449                 } else
 450                         return -EINVAL;
 451 
 452                 return 0;
 453         }
 454         default:
 455                 return -EINVAL;
 456         }
 457 }
 458 
 459 int vfio_ccw_register_dev_region(struct vfio_ccw_private *private,
 460                                  unsigned int subtype,
 461                                  const struct vfio_ccw_regops *ops,
 462                                  size_t size, u32 flags, void *data)
 463 {
 464         struct vfio_ccw_region *region;
 465 
 466         region = krealloc(private->region,
 467                           (private->num_regions + 1) * sizeof(*region),
 468                           GFP_KERNEL);
 469         if (!region)
 470                 return -ENOMEM;
 471 
 472         private->region = region;
 473         private->region[private->num_regions].type = VFIO_REGION_TYPE_CCW;
 474         private->region[private->num_regions].subtype = subtype;
 475         private->region[private->num_regions].ops = ops;
 476         private->region[private->num_regions].size = size;
 477         private->region[private->num_regions].flags = flags;
 478         private->region[private->num_regions].data = data;
 479 
 480         private->num_regions++;
 481 
 482         return 0;
 483 }
 484 
 485 static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
 486                                    unsigned int cmd,
 487                                    unsigned long arg)
 488 {
 489         int ret = 0;
 490         unsigned long minsz;
 491 
 492         switch (cmd) {
 493         case VFIO_DEVICE_GET_INFO:
 494         {
 495                 struct vfio_device_info info;
 496 
 497                 minsz = offsetofend(struct vfio_device_info, num_irqs);
 498 
 499                 if (copy_from_user(&info, (void __user *)arg, minsz))
 500                         return -EFAULT;
 501 
 502                 if (info.argsz < minsz)
 503                         return -EINVAL;
 504 
 505                 ret = vfio_ccw_mdev_get_device_info(&info, mdev);
 506                 if (ret)
 507                         return ret;
 508 
 509                 return copy_to_user((void __user *)arg, &info, minsz);
 510         }
 511         case VFIO_DEVICE_GET_REGION_INFO:
 512         {
 513                 struct vfio_region_info info;
 514 
 515                 minsz = offsetofend(struct vfio_region_info, offset);
 516 
 517                 if (copy_from_user(&info, (void __user *)arg, minsz))
 518                         return -EFAULT;
 519 
 520                 if (info.argsz < minsz)
 521                         return -EINVAL;
 522 
 523                 ret = vfio_ccw_mdev_get_region_info(&info, mdev, arg);
 524                 if (ret)
 525                         return ret;
 526 
 527                 return copy_to_user((void __user *)arg, &info, minsz);
 528         }
 529         case VFIO_DEVICE_GET_IRQ_INFO:
 530         {
 531                 struct vfio_irq_info info;
 532 
 533                 minsz = offsetofend(struct vfio_irq_info, count);
 534 
 535                 if (copy_from_user(&info, (void __user *)arg, minsz))
 536                         return -EFAULT;
 537 
 538                 if (info.argsz < minsz || info.index >= VFIO_CCW_NUM_IRQS)
 539                         return -EINVAL;
 540 
 541                 ret = vfio_ccw_mdev_get_irq_info(&info);
 542                 if (ret)
 543                         return ret;
 544 
 545                 if (info.count == -1)
 546                         return -EINVAL;
 547 
 548                 return copy_to_user((void __user *)arg, &info, minsz);
 549         }
 550         case VFIO_DEVICE_SET_IRQS:
 551         {
 552                 struct vfio_irq_set hdr;
 553                 size_t data_size;
 554                 void __user *data;
 555 
 556                 minsz = offsetofend(struct vfio_irq_set, count);
 557 
 558                 if (copy_from_user(&hdr, (void __user *)arg, minsz))
 559                         return -EFAULT;
 560 
 561                 ret = vfio_set_irqs_validate_and_prepare(&hdr, 1,
 562                                                          VFIO_CCW_NUM_IRQS,
 563                                                          &data_size);
 564                 if (ret)
 565                         return ret;
 566 
 567                 data = (void __user *)(arg + minsz);
 568                 return vfio_ccw_mdev_set_irqs(mdev, hdr.flags, data);
 569         }
 570         case VFIO_DEVICE_RESET:
 571                 return vfio_ccw_mdev_reset(mdev);
 572         default:
 573                 return -ENOTTY;
 574         }
 575 }
 576 
 577 static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
 578         .owner                  = THIS_MODULE,
 579         .supported_type_groups  = mdev_type_groups,
 580         .create                 = vfio_ccw_mdev_create,
 581         .remove                 = vfio_ccw_mdev_remove,
 582         .open                   = vfio_ccw_mdev_open,
 583         .release                = vfio_ccw_mdev_release,
 584         .read                   = vfio_ccw_mdev_read,
 585         .write                  = vfio_ccw_mdev_write,
 586         .ioctl                  = vfio_ccw_mdev_ioctl,
 587 };
 588 
 589 int vfio_ccw_mdev_reg(struct subchannel *sch)
 590 {
 591         return mdev_register_device(&sch->dev, &vfio_ccw_mdev_ops);
 592 }
 593 
 594 void vfio_ccw_mdev_unreg(struct subchannel *sch)
 595 {
 596         mdev_unregister_device(&sch->dev);
 597 }

/* [<][>][^][v][top][bottom][index][help] */