Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vfio/fsl-mc: Add irq infrastructure for fsl-mc devices

This patch adds the skeleton for interrupt support
for fsl-mc devices. The interrupts are not yet functional,
the functionality will be added by subsequent patches.

Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>

authored by

Diana Craciun and committed by
Alex Williamson
2e0d2956 f2ba7e8c

+91 -3
+1 -1
drivers/vfio/fsl-mc/Makefile
··· 1 1 # SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 2 3 - vfio-fsl-mc-y := vfio_fsl_mc.o 3 + vfio-fsl-mc-y := vfio_fsl_mc.o vfio_fsl_mc_intr.o 4 4 obj-$(CONFIG_VFIO_FSL_MC) += vfio-fsl-mc.o
+50 -2
drivers/vfio/fsl-mc/vfio_fsl_mc.c
··· 217 217 } 218 218 case VFIO_DEVICE_GET_IRQ_INFO: 219 219 { 220 - return -ENOTTY; 220 + struct vfio_irq_info info; 221 + 222 + minsz = offsetofend(struct vfio_irq_info, count); 223 + if (copy_from_user(&info, (void __user *)arg, minsz)) 224 + return -EFAULT; 225 + 226 + if (info.argsz < minsz) 227 + return -EINVAL; 228 + 229 + if (info.index >= mc_dev->obj_desc.irq_count) 230 + return -EINVAL; 231 + 232 + info.flags = VFIO_IRQ_INFO_EVENTFD; 233 + info.count = 1; 234 + 235 + return copy_to_user((void __user *)arg, &info, minsz); 221 236 } 222 237 case VFIO_DEVICE_SET_IRQS: 223 238 { 224 - return -ENOTTY; 239 + struct vfio_irq_set hdr; 240 + u8 *data = NULL; 241 + int ret = 0; 242 + size_t data_size = 0; 243 + 244 + minsz = offsetofend(struct vfio_irq_set, count); 245 + 246 + if (copy_from_user(&hdr, (void __user *)arg, minsz)) 247 + return -EFAULT; 248 + 249 + ret = vfio_set_irqs_validate_and_prepare(&hdr, mc_dev->obj_desc.irq_count, 250 + mc_dev->obj_desc.irq_count, &data_size); 251 + if (ret) 252 + return ret; 253 + 254 + if (data_size) { 255 + data = memdup_user((void __user *)(arg + minsz), 256 + data_size); 257 + if (IS_ERR(data)) 258 + return PTR_ERR(data); 259 + } 260 + 261 + mutex_lock(&vdev->igate); 262 + ret = vfio_fsl_mc_set_irqs_ioctl(vdev, hdr.flags, 263 + hdr.index, hdr.start, 264 + hdr.count, data); 265 + mutex_unlock(&vdev->igate); 266 + kfree(data); 267 + 268 + return ret; 225 269 } 226 270 case VFIO_DEVICE_RESET: 227 271 { ··· 467 423 if (ret) 468 424 goto out_reflck; 469 425 426 + mutex_init(&vdev->igate); 427 + 470 428 return 0; 471 429 472 430 out_reflck: ··· 488 442 vdev = vfio_del_group_dev(dev); 489 443 if (!vdev) 490 444 return -EINVAL; 445 + 446 + mutex_destroy(&vdev->igate); 491 447 492 448 vfio_fsl_mc_reflck_put(vdev->reflck); 493 449
+34
drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 + /* 3 + * Copyright 2013-2016 Freescale Semiconductor Inc. 4 + * Copyright 2019 NXP 5 + */ 6 + 7 + #include <linux/vfio.h> 8 + #include <linux/slab.h> 9 + #include <linux/types.h> 10 + #include <linux/eventfd.h> 11 + #include <linux/msi.h> 12 + 13 + #include "linux/fsl/mc.h" 14 + #include "vfio_fsl_mc_private.h" 15 + 16 + static int vfio_fsl_mc_set_irq_trigger(struct vfio_fsl_mc_device *vdev, 17 + unsigned int index, unsigned int start, 18 + unsigned int count, u32 flags, 19 + void *data) 20 + { 21 + return -EINVAL; 22 + } 23 + 24 + int vfio_fsl_mc_set_irqs_ioctl(struct vfio_fsl_mc_device *vdev, 25 + u32 flags, unsigned int index, 26 + unsigned int start, unsigned int count, 27 + void *data) 28 + { 29 + if (flags & VFIO_IRQ_SET_ACTION_TRIGGER) 30 + return vfio_fsl_mc_set_irq_trigger(vdev, index, start, 31 + count, flags, data); 32 + else 33 + return -EINVAL; 34 + }
+6
drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
··· 33 33 int refcnt; 34 34 struct vfio_fsl_mc_region *regions; 35 35 struct vfio_fsl_mc_reflck *reflck; 36 + struct mutex igate; 36 37 }; 38 + 39 + extern int vfio_fsl_mc_set_irqs_ioctl(struct vfio_fsl_mc_device *vdev, 40 + u32 flags, unsigned int index, 41 + unsigned int start, unsigned int count, 42 + void *data); 37 43 38 44 #endif /* VFIO_FSL_MC_PRIVATE_H */