diff options
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/vfio_ccw_cp.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/vfio_ccw_drv.c | 24 | ||||
-rw-r--r-- | drivers/s390/cio/vfio_ccw_fsm.c | 6 | ||||
-rw-r--r-- | drivers/s390/cio/vfio_ccw_ops.c | 4 | ||||
-rw-r--r-- | drivers/s390/cio/vfio_ccw_private.h | 2 |
5 files changed, 30 insertions, 8 deletions
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index dbe7c7ac9ac8..fd77e46eb3b2 100644 --- a/drivers/s390/cio/vfio_ccw_cp.c +++ b/drivers/s390/cio/vfio_ccw_cp.c @@ -163,7 +163,7 @@ static bool pfn_array_table_iova_pinned(struct pfn_array_table *pat, for (i = 0; i < pat->pat_nr; i++, pa++) for (j = 0; j < pa->pa_nr; j++) - if (pa->pa_iova_pfn[i] == iova_pfn) + if (pa->pa_iova_pfn[j] == iova_pfn) return true; return false; diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 770fa9cfc310..f47d16b5810b 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -22,6 +22,7 @@ #include "vfio_ccw_private.h" struct workqueue_struct *vfio_ccw_work_q; +struct kmem_cache *vfio_ccw_io_region; /* * Helpers @@ -79,7 +80,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work) cp_update_scsw(&private->cp, &irb->scsw); cp_free(&private->cp); } - memcpy(private->io_region.irb_area, irb, sizeof(*irb)); + memcpy(private->io_region->irb_area, irb, sizeof(*irb)); if (private->io_trigger) eventfd_signal(private->io_trigger, 1); @@ -114,6 +115,14 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); if (!private) return -ENOMEM; + + private->io_region = kmem_cache_zalloc(vfio_ccw_io_region, + GFP_KERNEL | GFP_DMA); + if (!private->io_region) { + kfree(private); + return -ENOMEM; + } + private->sch = sch; dev_set_drvdata(&sch->dev, private); @@ -139,6 +148,7 @@ out_disable: cio_disable_subchannel(sch); out_free: dev_set_drvdata(&sch->dev, NULL); + kmem_cache_free(vfio_ccw_io_region, private->io_region); kfree(private); return ret; } @@ -153,6 +163,7 @@ static int vfio_ccw_sch_remove(struct subchannel *sch) dev_set_drvdata(&sch->dev, NULL); + kmem_cache_free(vfio_ccw_io_region, private->io_region); kfree(private); return 0; @@ -232,10 +243,20 @@ static int __init vfio_ccw_sch_init(void) if (!vfio_ccw_work_q) return -ENOMEM; + vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region", + sizeof(struct ccw_io_region), 0, + SLAB_ACCOUNT, 0, + sizeof(struct ccw_io_region), NULL); + if (!vfio_ccw_io_region) { + destroy_workqueue(vfio_ccw_work_q); + return -ENOMEM; + } + isc_register(VFIO_CCW_ISC); ret = css_driver_register(&vfio_ccw_sch_driver); if (ret) { isc_unregister(VFIO_CCW_ISC); + kmem_cache_destroy(vfio_ccw_io_region); destroy_workqueue(vfio_ccw_work_q); } @@ -246,6 +267,7 @@ static void __exit vfio_ccw_sch_exit(void) { css_driver_unregister(&vfio_ccw_sch_driver); isc_unregister(VFIO_CCW_ISC); + kmem_cache_destroy(vfio_ccw_io_region); destroy_workqueue(vfio_ccw_work_q); } module_init(vfio_ccw_sch_init); diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c index 797a82731159..f94aa01f9c36 100644 --- a/drivers/s390/cio/vfio_ccw_fsm.c +++ b/drivers/s390/cio/vfio_ccw_fsm.c @@ -93,13 +93,13 @@ static void fsm_io_error(struct vfio_ccw_private *private, enum vfio_ccw_event event) { pr_err("vfio-ccw: FSM: I/O request from state:%d\n", private->state); - private->io_region.ret_code = -EIO; + private->io_region->ret_code = -EIO; } static void fsm_io_busy(struct vfio_ccw_private *private, enum vfio_ccw_event event) { - private->io_region.ret_code = -EBUSY; + private->io_region->ret_code = -EBUSY; } static void fsm_disabled_irq(struct vfio_ccw_private *private, @@ -126,7 +126,7 @@ static void fsm_io_request(struct vfio_ccw_private *private, { union orb *orb; union scsw *scsw = &private->scsw; - struct ccw_io_region *io_region = &private->io_region; + struct ccw_io_region *io_region = private->io_region; struct mdev_device *mdev = private->mdev; char *errstr = "request"; diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 41eeb57d68a3..f673e106c041 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -174,7 +174,7 @@ static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev, return -EINVAL; private = dev_get_drvdata(mdev_parent_dev(mdev)); - region = &private->io_region; + region = private->io_region; if (copy_to_user(buf, (void *)region + *ppos, count)) return -EFAULT; @@ -196,7 +196,7 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev, if (private->state != VFIO_CCW_STATE_IDLE) return -EACCES; - region = &private->io_region; + region = private->io_region; if (copy_from_user((void *)region + *ppos, buf, count)) return -EFAULT; diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index 78a66d96756b..078e46f9623d 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -41,7 +41,7 @@ struct vfio_ccw_private { atomic_t avail; struct mdev_device *mdev; struct notifier_block nb; - struct ccw_io_region io_region; + struct ccw_io_region *io_region; struct channel_program cp; struct irb irb; |