To provide user-space a set of interfaces to: 1. pass in a ccw program to perform an I/O operation. 2. read back I/O results of the completed I/O operations. We introduce an MMIO region for the vfio-ccw device here. This region is defined to content: 1. areas to store arguments that an ssch required. 2. areas to store the I/O results. Using pwrite/pread to the device on this region, a user-space program could write/read data to/from the vfio-ccw device. Signed-off-by: Dong Jia Shi <bjsdjshi@xxxxxxxxxxxxxxxxxx> Reviewed-by: Pierre Morel <pmorel@xxxxxxxxxxxxxxxxxx> --- arch/s390/include/uapi/asm/Kbuild | 1 + arch/s390/include/uapi/asm/vfio_ccw.h | 28 +++++++++++++++++++++ drivers/s390/cio/vfio_ccw_ops.c | 47 +++++++++++++++++++++++++++++++++++ drivers/s390/cio/vfio_ccw_private.h | 4 +++ 4 files changed, 80 insertions(+) create mode 100644 arch/s390/include/uapi/asm/vfio_ccw.h diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild index bf736e7..fdb9529 100644 --- a/arch/s390/include/uapi/asm/Kbuild +++ b/arch/s390/include/uapi/asm/Kbuild @@ -52,3 +52,4 @@ header-y += unistd.h header-y += virtio-ccw.h header-y += vtoc.h header-y += zcrypt.h +header-y += vfio_ccw.h diff --git a/arch/s390/include/uapi/asm/vfio_ccw.h b/arch/s390/include/uapi/asm/vfio_ccw.h new file mode 100644 index 0000000..4ee74ae --- /dev/null +++ b/arch/s390/include/uapi/asm/vfio_ccw.h @@ -0,0 +1,28 @@ +/* + * Interfaces for vfio-ccw + * + * Copyright IBM Corp. 2017 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Dong Jia Shi <bjsdjshi@xxxxxxxxxxxxxxxxxx> + */ + +#ifndef _VFIO_CCW_H_ +#define _VFIO_CCW_H_ + +#include <linux/types.h> + +struct ccw_io_region { +#define ORB_AREA_SIZE 12 + __u8 orb_area[ORB_AREA_SIZE]; +#define SCSW_AREA_SIZE 12 + __u8 scsw_area[SCSW_AREA_SIZE]; +#define IRB_AREA_SIZE 96 + __u8 irb_area[IRB_AREA_SIZE]; + __u32 ret_code; +} __packed; + +#endif diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 6031a10..d68a296 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -129,6 +129,51 @@ void vfio_ccw_mdev_release(struct mdev_device *mdev) vfio_unregister_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY, &private->nb); } +static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev, + char __user *buf, + size_t count, + loff_t *ppos) +{ + struct vfio_ccw_private *private; + struct ccw_io_region *region; + + if (*ppos + count > sizeof(*region)) + return -EINVAL; + + private = dev_get_drvdata(mdev->dev.parent); + if (!private) + return -ENODEV; + + region = &private->io_region; + if (copy_to_user(buf, (void *)region + *ppos, count)) + return -EFAULT; + + return count; +} + +static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev, + const char __user *buf, + size_t count, + loff_t *ppos) +{ + struct vfio_ccw_private *private; + struct ccw_io_region *region; + + if (*ppos + count > sizeof(*region)) + return -EINVAL; + + private = dev_get_drvdata(mdev->dev.parent); + if (!private) + return -ENODEV; + + region = &private->io_region; + if (copy_from_user((void *)region + *ppos, buf, count)) + return -EFAULT; + region->ret_code = 0; + + return count; +} + static const struct parent_ops vfio_ccw_mdev_ops = { .owner = THIS_MODULE, .supported_type_groups = mdev_type_groups, @@ -136,6 +181,8 @@ static const struct parent_ops vfio_ccw_mdev_ops = { .remove = vfio_ccw_mdev_remove, .open = vfio_ccw_mdev_open, .release = vfio_ccw_mdev_release, + .read = vfio_ccw_mdev_read, + .write = vfio_ccw_mdev_write, }; int vfio_ccw_mdev_reg(struct subchannel *sch) diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index 4cd6657..99265a9 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -14,6 +14,8 @@ #ifndef _VFIO_CCW_PRIVATE_H_ #define _VFIO_CCW_PRIVATE_H_ +#include <asm/vfio_ccw.h> + #include "css.h" /** @@ -22,12 +24,14 @@ * @completion: synchronization helper of the I/O completion * @mdev: pointor to the mediated device * @nb: notifier for vfio events + * @io_region: MMIO region to input/output I/O arguments/results */ struct vfio_ccw_private { struct subchannel *sch; struct completion *completion; struct mdev_device *mdev; struct notifier_block nb; + struct ccw_io_region io_region; } __aligned(8); extern int vfio_ccw_mdev_reg(struct subchannel *sch); -- 2.8.4 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html