aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDong Jia Shi <bjsdjshi@linux.vnet.ibm.com>2017-03-16 23:17:37 -0400
committerCornelia Huck <cornelia.huck@de.ibm.com>2017-03-31 06:55:08 -0400
commit83d1193a96dc78576c15f93cd70e0558763a85b3 (patch)
tree3d7e58feeab5cfbeb2f7f42101055b4b3c4e515e
parente01bcdd61320c91c826376e0a7dd96ef8e85dd18 (diff)
vfio: ccw: realize VFIO_DEVICE_RESET ioctl
Introduce VFIO_DEVICE_RESET ioctl for vfio-ccw to make it possible to hot-reset the device. We try to achieve a reset by first disabling the subchannel and then enabling it again: this should clear all state at the subchannel. Signed-off-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> Message-Id: <20170317031743.40128-11-bjsdjshi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
-rw-r--r--drivers/s390/cio/vfio_ccw_ops.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index f3300ddded3f..125818cdf305 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -12,6 +12,32 @@
12 12
13#include "vfio_ccw_private.h" 13#include "vfio_ccw_private.h"
14 14
15static int vfio_ccw_mdev_reset(struct mdev_device *mdev)
16{
17 struct vfio_ccw_private *private;
18 struct subchannel *sch;
19 int ret;
20
21 private = dev_get_drvdata(mdev_parent_dev(mdev));
22 if (!private)
23 return -ENODEV;
24
25 sch = private->sch;
26 /*
27 * TODO:
28 * In the cureent stage, some things like "no I/O running" and "no
29 * interrupt pending" are clear, but we are not sure what other state
30 * we need to care about.
31 * There are still a lot more instructions need to be handled. We
32 * should come back here later.
33 */
34 ret = vfio_ccw_sch_quiesce(sch);
35 if (ret)
36 return ret;
37
38 return cio_enable_subchannel(sch, (u32)(unsigned long)sch);
39}
40
15static int vfio_ccw_mdev_notifier(struct notifier_block *nb, 41static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
16 unsigned long action, 42 unsigned long action,
17 void *data) 43 void *data)
@@ -28,15 +54,11 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb,
28 */ 54 */
29 if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) { 55 if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
30 struct vfio_iommu_type1_dma_unmap *unmap = data; 56 struct vfio_iommu_type1_dma_unmap *unmap = data;
31 struct subchannel *sch = private->sch;
32 57
33 if (!cp_iova_pinned(&private->cp, unmap->iova)) 58 if (!cp_iova_pinned(&private->cp, unmap->iova))
34 return NOTIFY_OK; 59 return NOTIFY_OK;
35 60
36 if (vfio_ccw_sch_quiesce(sch)) 61 if (vfio_ccw_mdev_reset(private->mdev))
37 return NOTIFY_BAD;
38
39 if (cio_enable_subchannel(sch, (u32)(unsigned long)sch))
40 return NOTIFY_BAD; 62 return NOTIFY_BAD;
41 63
42 cp_free(&private->cp); 64 cp_free(&private->cp);
@@ -100,16 +122,11 @@ static int vfio_ccw_mdev_create(struct kobject *kobj, struct mdev_device *mdev)
100 122
101static int vfio_ccw_mdev_remove(struct mdev_device *mdev) 123static int vfio_ccw_mdev_remove(struct mdev_device *mdev)
102{ 124{
103 struct vfio_ccw_private *private; 125 struct vfio_ccw_private *private =
104 struct subchannel *sch; 126 dev_get_drvdata(mdev_parent_dev(mdev));
105 int ret; 127 int ret;
106 128
107 private = dev_get_drvdata(mdev_parent_dev(mdev)); 129 ret = vfio_ccw_mdev_reset(mdev);
108 sch = private->sch;
109 ret = vfio_ccw_sch_quiesce(sch);
110 if (ret)
111 return ret;
112 ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
113 if (ret) 130 if (ret)
114 return ret; 131 return ret;
115 132
@@ -190,7 +207,7 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev,
190 207
191static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info) 208static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info)
192{ 209{
193 info->flags = VFIO_DEVICE_FLAGS_CCW; 210 info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET;
194 info->num_regions = VFIO_CCW_NUM_REGIONS; 211 info->num_regions = VFIO_CCW_NUM_REGIONS;
195 info->num_irqs = 0; 212 info->num_irqs = 0;
196 213
@@ -260,6 +277,8 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
260 277
261 return copy_to_user((void __user *)arg, &info, minsz); 278 return copy_to_user((void __user *)arg, &info, minsz);
262 } 279 }
280 case VFIO_DEVICE_RESET:
281 return vfio_ccw_mdev_reset(mdev);
263 default: 282 default:
264 return -ENOTTY; 283 return -ENOTTY;
265 } 284 }