summaryrefslogtreecommitdiff
path: root/drivers/s390/cio/vfio_ccw_ops.c
diff options
context:
space:
mode:
authorDong Jia Shi <bjsdjshi@linux.vnet.ibm.com>2017-03-17 06:17:35 +0300
committerCornelia Huck <cornelia.huck@de.ibm.com>2017-03-31 13:55:07 +0300
commit4e149e431a2858b86b4f9c801b2a4dde50c929f9 (patch)
treea7547d4f98ea5e31a7516806e32feeaaa41b14be /drivers/s390/cio/vfio_ccw_ops.c
parent060d2b5afcc4f9e2d61e2b059e648f569b8dba9a (diff)
downloadlinux-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.c24
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;
}