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

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

vfio: ccw: realize VFIO_DEVICE_GET_REGION_INFO ioctl



Introduce device information about vfio-ccw: VFIO_DEVICE_FLAGS_CCW.
Realize VFIO_DEVICE_GET_REGION_INFO ioctl for vfio-ccw.

Reviewed-by: default avatarPierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: default avatarDong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
Acked-by: default avatarAlex Williamson <alex.williamson@redhat.com>
Message-Id: <20170317031743.40128-10-bjsdjshi@linux.vnet.ibm.com>
Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
parent 4e149e43
Loading
Loading
Loading
Loading
+78 −0
Original line number Diff line number Diff line
@@ -188,6 +188,83 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev,
	return count;
}

static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info)
{
	info->flags = VFIO_DEVICE_FLAGS_CCW;
	info->num_regions = VFIO_CCW_NUM_REGIONS;
	info->num_irqs = 0;

	return 0;
}

static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info,
					 u16 *cap_type_id,
					 void **cap_type)
{
	switch (info->index) {
	case VFIO_CCW_CONFIG_REGION_INDEX:
		info->offset = 0;
		info->size = sizeof(struct ccw_io_region);
		info->flags = VFIO_REGION_INFO_FLAG_READ
			      | VFIO_REGION_INFO_FLAG_WRITE;
		return 0;
	default:
		return -EINVAL;
	}
}

static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
				   unsigned int cmd,
				   unsigned long arg)
{
	int ret = 0;
	unsigned long minsz;

	switch (cmd) {
	case VFIO_DEVICE_GET_INFO:
	{
		struct vfio_device_info info;

		minsz = offsetofend(struct vfio_device_info, num_irqs);

		if (copy_from_user(&info, (void __user *)arg, minsz))
			return -EFAULT;

		if (info.argsz < minsz)
			return -EINVAL;

		ret = vfio_ccw_mdev_get_device_info(&info);
		if (ret)
			return ret;

		return copy_to_user((void __user *)arg, &info, minsz);
	}
	case VFIO_DEVICE_GET_REGION_INFO:
	{
		struct vfio_region_info info;
		u16 cap_type_id = 0;
		void *cap_type = NULL;

		minsz = offsetofend(struct vfio_region_info, offset);

		if (copy_from_user(&info, (void __user *)arg, minsz))
			return -EFAULT;

		if (info.argsz < minsz)
			return -EINVAL;

		ret = vfio_ccw_mdev_get_region_info(&info, &cap_type_id,
						    &cap_type);
		if (ret)
			return ret;

		return copy_to_user((void __user *)arg, &info, minsz);
	}
	default:
		return -ENOTTY;
	}
}

static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
	.owner			= THIS_MODULE,
	.supported_type_groups  = mdev_type_groups,
@@ -197,6 +274,7 @@ static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
	.release		= vfio_ccw_mdev_release,
	.read			= vfio_ccw_mdev_read,
	.write			= vfio_ccw_mdev_write,
	.ioctl			= vfio_ccw_mdev_ioctl,
};

int vfio_ccw_mdev_reg(struct subchannel *sch)
+11 −0
Original line number Diff line number Diff line
@@ -198,6 +198,7 @@ struct vfio_device_info {
#define VFIO_DEVICE_FLAGS_PCI	(1 << 1)	/* vfio-pci device */
#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2)	/* vfio-platform device */
#define VFIO_DEVICE_FLAGS_AMBA  (1 << 3)	/* vfio-amba device */
#define VFIO_DEVICE_FLAGS_CCW	(1 << 4)	/* vfio-ccw device */
	__u32	num_regions;	/* Max region index + 1 */
	__u32	num_irqs;	/* Max IRQ index + 1 */
};
@@ -447,6 +448,16 @@ enum {
	VFIO_PCI_NUM_IRQS
};

/*
 * The vfio-ccw bus driver makes use of the following fixed region.
 * Unimplemented regions return a size of zero.
 */

enum {
	VFIO_CCW_CONFIG_REGION_INDEX,
	VFIO_CCW_NUM_REGIONS
};

/**
 * VFIO_DEVICE_GET_PCI_HOT_RESET_INFO - _IORW(VFIO_TYPE, VFIO_BASE + 12,
 *					      struct vfio_pci_hot_reset_info)