Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756792AbaD1Pyz (ORCPT ); Mon, 28 Apr 2014 11:54:55 -0400 Received: from mail-wi0-f180.google.com ([209.85.212.180]:64131 "EHLO mail-wi0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756528AbaD1Pyr (ORCPT ); Mon, 28 Apr 2014 11:54:47 -0400 From: Antonios Motakis To: alex.williamson@redhat.com, kvmarm@lists.cs.columbia.edu, iommu@lists.linux-foundation.org Cc: tech@virtualopensystems.com, a.rigo@virtualopensystems.com, kvm@vger.kernel.org, christoffer.dall@linaro.org, will.deacon@arm.com, kim.phillips@freescale.com, stuart.yoder@freescale.com, Antonios Motakis , Catalin Marinas , Mark Rutland , linux-kernel@vger.kernel.org (open list) Subject: [RFC PATCH v5 09/11] VFIO_PLATFORM: Return IRQ info Date: Mon, 28 Apr 2014 17:52:49 +0200 Message-Id: <1398700371-20096-10-git-send-email-a.motakis@virtualopensystems.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1398700371-20096-1-git-send-email-a.motakis@virtualopensystems.com> References: <1398700371-20096-1-git-send-email-a.motakis@virtualopensystems.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return information for the interrupts exposed by the device. This patch extends VFIO_DEVICE_GET_INFO with the number of IRQs and enables VFIO_DEVICE_GET_IRQ_INFO Signed-off-by: Antonios Motakis --- drivers/vfio/platform/Makefile | 2 +- drivers/vfio/platform/vfio_platform.c | 35 +++++++++++++-- drivers/vfio/platform/vfio_platform_irq.c | 63 +++++++++++++++++++++++++++ drivers/vfio/platform/vfio_platform_private.h | 11 +++++ 4 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 drivers/vfio/platform/vfio_platform_irq.c diff --git a/drivers/vfio/platform/Makefile b/drivers/vfio/platform/Makefile index df3a014..2c53327 100644 --- a/drivers/vfio/platform/Makefile +++ b/drivers/vfio/platform/Makefile @@ -1,4 +1,4 @@ -vfio-platform-y := vfio_platform.o +vfio-platform-y := vfio_platform.o vfio_platform_irq.o obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform.o diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c index 37beff3..2e16595 100644 --- a/drivers/vfio/platform/vfio_platform.c +++ b/drivers/vfio/platform/vfio_platform.c @@ -79,6 +79,7 @@ static void vfio_platform_release(void *device_data) struct vfio_platform_device *vdev = device_data; vfio_platform_regions_cleanup(vdev); + vfio_platform_irq_cleanup(vdev); module_put(THIS_MODULE); } @@ -92,12 +93,22 @@ static int vfio_platform_open(void *device_data) if (ret) return ret; + ret = vfio_platform_irq_init(vdev); + if (ret) + goto err_irq; + if (!try_module_get(THIS_MODULE)) { - vfio_platform_regions_cleanup(vdev); - return -ENODEV; + ret = -ENODEV; + goto err_mod; } return 0; + +err_mod: + vfio_platform_irq_cleanup(vdev); +err_irq: + vfio_platform_regions_cleanup(vdev); + return ret; } static long vfio_platform_ioctl(void *device_data, @@ -119,7 +130,7 @@ static long vfio_platform_ioctl(void *device_data, info.flags = VFIO_DEVICE_FLAGS_PLATFORM; info.num_regions = vdev->num_regions; - info.num_irqs = 0; + info.num_irqs = vdev->num_irqs; return copy_to_user((void __user *)arg, &info, minsz); @@ -145,7 +156,23 @@ static long vfio_platform_ioctl(void *device_data, return copy_to_user((void __user *)arg, &info, minsz); } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) { - return -EINVAL; + struct vfio_irq_info info; + + minsz = offsetofend(struct vfio_irq_info, count); + + if (copy_from_user(&info, (void __user *)arg, minsz)) + return -EFAULT; + + if (info.argsz < minsz) + return -EINVAL; + + if (info.index >= vdev->num_irqs) + return -EINVAL; + + info.flags = vdev->irq[info.index].flags; + info.count = vdev->irq[info.index].count; + + return copy_to_user((void __user *)arg, &info, minsz); } else if (cmd == VFIO_DEVICE_SET_IRQS) return -EINVAL; diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c new file mode 100644 index 0000000..075c401 --- /dev/null +++ b/drivers/vfio/platform/vfio_platform_irq.c @@ -0,0 +1,63 @@ +/* + * VFIO platform devices interrupt handling + * + * Copyright (C) 2013 - Virtual Open Systems + * Author: Antonios Motakis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vfio_platform_private.h" + +int vfio_platform_irq_init(struct vfio_platform_device *vdev) +{ + int cnt = 0, i; + + while (platform_get_irq(vdev->pdev, cnt) > 0) + cnt++; + + vdev->num_irqs = cnt; + + vdev->irq = kzalloc(sizeof(struct vfio_platform_irq) * vdev->num_irqs, + GFP_KERNEL); + if (!vdev->irq) + return -ENOMEM; + + for (i = 0; i < cnt; i++) { + struct vfio_platform_irq irq; + + irq.flags = 0; + irq.count = 1; + + vdev->irq[i] = irq; + } + + return 0; +} + +void vfio_platform_irq_cleanup(struct vfio_platform_device *vdev) +{ + kfree(vdev->irq); +} diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h index 3448f918..9776cff 100644 --- a/drivers/vfio/platform/vfio_platform_private.h +++ b/drivers/vfio/platform/vfio_platform_private.h @@ -24,6 +24,11 @@ #define VFIO_PLATFORM_INDEX_TO_OFFSET(index) \ ((u64)(index) << VFIO_PLATFORM_OFFSET_SHIFT) +struct vfio_platform_irq { + u32 flags; + u32 count; +}; + struct vfio_platform_region { u64 addr; resource_size_t size; @@ -34,6 +39,12 @@ struct vfio_platform_device { struct platform_device *pdev; struct vfio_platform_region *region; u32 num_regions; + struct vfio_platform_irq *irq; + u32 num_irqs; }; +extern int vfio_platform_irq_init(struct vfio_platform_device *vdev); + +extern void vfio_platform_irq_cleanup(struct vfio_platform_device *vdev); + #endif /* VFIO_PLATFORM_PRIVATE_H */ -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/