Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 060d2b5a authored by Dong Jia Shi's avatar Dong Jia Shi Committed by Cornelia Huck
Browse files

vfio: ccw: introduce ccw_io_region



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.

Reviewed-by: default avatarPierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: default avatarDong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
Message-Id: <20170317031743.40128-8-bjsdjshi@linux.vnet.ibm.com>
Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
parent 84cd8fc4
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -127,6 +127,51 @@ void vfio_ccw_mdev_release(struct mdev_device *mdev)
				 &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_parent_dev(mdev));
	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_parent_dev(mdev));
	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 mdev_parent_ops vfio_ccw_mdev_ops = {
	.owner			= THIS_MODULE,
	.supported_type_groups  = mdev_type_groups,
@@ -134,6 +179,8 @@ static const struct mdev_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)
+4 −0
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@
#ifndef _VFIO_CCW_PRIVATE_H_
#define _VFIO_CCW_PRIVATE_H_

#include <linux/vfio_ccw.h>

#include "css.h"

/**
@@ -19,6 +21,7 @@
 * @avail: available for creating a mediated device
 * @mdev: pointer 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;
@@ -26,6 +29,7 @@ struct vfio_ccw_private {
	atomic_t		avail;
	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);
+24 −0
Original line number Diff line number Diff line
/*
 * Interfaces for vfio-ccw
 *
 * Copyright IBM Corp. 2017
 *
 * Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
 */

#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