brintos

brintos / linux-shallow public Read only

0
0
Text · 2.1 KiB · 420d89b Raw
88 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Async I/O region for vfio_ccw4 *5 * Copyright Red Hat, Inc. 20196 *7 * Author(s): Cornelia Huck <cohuck@redhat.com>8 */9 10#include <linux/vfio.h>11 12#include "vfio_ccw_private.h"13 14static ssize_t vfio_ccw_async_region_read(struct vfio_ccw_private *private,15					  char __user *buf, size_t count,16					  loff_t *ppos)17{18	unsigned int i = VFIO_CCW_OFFSET_TO_INDEX(*ppos) - VFIO_CCW_NUM_REGIONS;19	loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;20	struct ccw_cmd_region *region;21	int ret;22 23	if (pos + count > sizeof(*region))24		return -EINVAL;25 26	mutex_lock(&private->io_mutex);27	region = private->region[i].data;28	if (copy_to_user(buf, (void *)region + pos, count))29		ret = -EFAULT;30	else31		ret = count;32	mutex_unlock(&private->io_mutex);33	return ret;34}35 36static ssize_t vfio_ccw_async_region_write(struct vfio_ccw_private *private,37					   const char __user *buf, size_t count,38					   loff_t *ppos)39{40	unsigned int i = VFIO_CCW_OFFSET_TO_INDEX(*ppos) - VFIO_CCW_NUM_REGIONS;41	loff_t pos = *ppos & VFIO_CCW_OFFSET_MASK;42	struct ccw_cmd_region *region;43	int ret;44 45	if (pos + count > sizeof(*region))46		return -EINVAL;47 48	if (!mutex_trylock(&private->io_mutex))49		return -EAGAIN;50 51	region = private->region[i].data;52	if (copy_from_user((void *)region + pos, buf, count)) {53		ret = -EFAULT;54		goto out_unlock;55	}56 57	vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_ASYNC_REQ);58 59	ret = region->ret_code ? region->ret_code : count;60 61out_unlock:62	mutex_unlock(&private->io_mutex);63	return ret;64}65 66static void vfio_ccw_async_region_release(struct vfio_ccw_private *private,67					  struct vfio_ccw_region *region)68{69 70}71 72static const struct vfio_ccw_regops vfio_ccw_async_region_ops = {73	.read = vfio_ccw_async_region_read,74	.write = vfio_ccw_async_region_write,75	.release = vfio_ccw_async_region_release,76};77 78int vfio_ccw_register_async_dev_regions(struct vfio_ccw_private *private)79{80	return vfio_ccw_register_dev_region(private,81					    VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD,82					    &vfio_ccw_async_region_ops,83					    sizeof(struct ccw_cmd_region),84					    VFIO_REGION_INFO_FLAG_READ |85					    VFIO_REGION_INFO_FLAG_WRITE,86					    private->cmd_region);87}88