@@ -71,6 +71,7 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch)
ret = cio_disable_subchannel(sch);
} while (ret == -EBUSY);
+ vfio_device_put(&private->vdev);
return ret;
}
@@ -131,6 +132,7 @@ static void vfio_ccw_sch_irq(struct subchannel *sch)
inc_irq_stat(IRQIO_CIO);
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
+ vfio_device_put(&private->vdev);
}
struct vfio_ccw_private *vfio_ccw_alloc_private(struct mdev_device *mdev,
@@ -252,6 +254,7 @@ static void vfio_ccw_sch_shutdown(struct subchannel *sch)
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_CLOSE);
vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER);
+ vfio_device_put(&private->vdev);
}
/**
@@ -287,6 +290,7 @@ static int vfio_ccw_sch_event(struct subchannel *sch, int process)
out_unlock:
spin_unlock_irqrestore(sch->lock, flags);
+ vfio_device_put(&private->vdev);
return rc;
}
@@ -334,8 +338,10 @@ static int vfio_ccw_chp_event(struct subchannel *sch,
sch->schid.ssid, sch->schid.sch_no,
mask, event);
- if (cio_update_schib(sch))
+ if (cio_update_schib(sch)) {
+ vfio_device_put(&private->vdev);
return -ENODEV;
+ }
switch (event) {
case CHP_VARY_OFF:
@@ -365,6 +371,7 @@ static int vfio_ccw_chp_event(struct subchannel *sch,
break;
}
+ vfio_device_put(&private->vdev);
return 0;
}
@@ -135,6 +135,8 @@ static inline struct vfio_ccw_private *vfio_ccw_get_private(struct subchannel *s
return NULL;
private = dev_get_drvdata(&sch->dev);
+ if (private && !vfio_device_try_get(&private->vdev))
+ private = NULL;
return private;
}
Take a reference to the vfio device when looking at the corresponding vfio_ccw_private struct, and put it back once we are finished. Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Eric Farman <farman@linux.ibm.com> --- drivers/s390/cio/vfio_ccw_drv.c | 9 ++++++++- drivers/s390/cio/vfio_ccw_private.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-)