diff options
author | Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> | 2017-03-17 06:17:35 +0300 |
---|---|---|
committer | Cornelia Huck <cornelia.huck@de.ibm.com> | 2017-03-31 13:55:07 +0300 |
commit | 4e149e431a2858b86b4f9c801b2a4dde50c929f9 (patch) | |
tree | a7547d4f98ea5e31a7516806e32feeaaa41b14be /drivers/s390/cio/vfio_ccw_ops.c | |
parent | 060d2b5afcc4f9e2d61e2b059e648f569b8dba9a (diff) | |
download | linux-4e149e431a2858b86b4f9c801b2a4dde50c929f9.tar.xz |
vfio: ccw: handle ccw command request
We implement the basic ccw command handling infrastructure
here:
1. Translate the ccw commands.
2. Issue the translated ccw commands to the device.
3. Once we get the execution result, update the guest SCSW
with it.
Acked-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
Message-Id: <20170317031743.40128-9-bjsdjshi@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/vfio_ccw_ops.c')
-rw-r--r-- | drivers/s390/cio/vfio_ccw_ops.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 6c06805839d8..878c88239fc8 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -23,12 +23,25 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb, return NOTIFY_STOP; /* - * TODO: * Vendor drivers MUST unpin pages in response to an * invalidation. */ - if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) - return NOTIFY_BAD; + if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) { + struct vfio_iommu_type1_dma_unmap *unmap = data; + struct subchannel *sch = private->sch; + + if (!cp_iova_pinned(&private->cp, unmap->iova)) + return NOTIFY_OK; + + if (vfio_ccw_sch_quiesce(sch)) + return NOTIFY_BAD; + + if (cio_enable_subchannel(sch, (u32)(unsigned long)sch)) + return NOTIFY_BAD; + + cp_free(&private->cp); + return NOTIFY_OK; + } return NOTIFY_DONE; } @@ -167,7 +180,10 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev, region = &private->io_region; if (copy_from_user((void *)region + *ppos, buf, count)) return -EFAULT; - region->ret_code = 0; + + region->ret_code = vfio_ccw_sch_cmd_request(private); + if (region->ret_code != 0) + return region->ret_code; return count; } |