From patchwork Wed Jan 21 12:49:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baptiste Reynal X-Patchwork-Id: 5676921 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4B700C058D for ; Wed, 21 Jan 2015 12:52:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 47861204D6 for ; Wed, 21 Jan 2015 12:52:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 35428202C8 for ; Wed, 21 Jan 2015 12:52:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753056AbbAUMwo (ORCPT ); Wed, 21 Jan 2015 07:52:44 -0500 Received: from mail-wg0-f48.google.com ([74.125.82.48]:62357 "EHLO mail-wg0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753444AbbAUMwX (ORCPT ); Wed, 21 Jan 2015 07:52:23 -0500 Received: by mail-wg0-f48.google.com with SMTP id x12so11147283wgg.7 for ; Wed, 21 Jan 2015 04:52:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=awgHSiUO1fPBfyevwgg44iu88OMPooni44O3aifTgVg=; b=dLsjqByBKB4B9EhmmTbuKaoE6VNN6yq7Q3mhIv9R5LbW/KNOOzofX83yVxHcne3Y4C vUMfLIVLy0yM9utXJTJyGyEa1BJjuLYXU+vV6Sa7t60Yvy3W4DS/wEMSIkbOhRw0XKNe 4FyXMLK64pDzsml72maqPLXhLS9O+JZmTmD/H9QdMFVraz+ycDRAN5vNbY1jWfQ6Eavy hjL3P/bS0uenqvaFfIwgcyjFI1DUQgIXpaLihOdSoxKtt9F4FGsurp1bc4l/1vZF+wd1 pv9Y9BLXfKXCQApHLvSgbK/dum7aXgPYgNKuvzNQ2d4QaONepT9dmiYYjf0ESIIQwS1/ ZDjA== X-Gm-Message-State: ALoCoQk8JniCxM+e18RWWiDJWvOG5HBJeW2t0O3iYSrZV7NEqHwXCrpw2IH52wMKrmY5H/erXGou X-Received: by 10.180.8.202 with SMTP id t10mr57563235wia.15.1421844741760; Wed, 21 Jan 2015 04:52:21 -0800 (PST) Received: from localhost (LPuteaux-656-1-278-113.w80-15.abo.wanadoo.fr. [80.15.154.113]) by mx.google.com with ESMTPSA id x6sm25422355wjf.24.2015.01.21.04.52.20 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Jan 2015 04:52:21 -0800 (PST) From: Baptiste Reynal To: kvmarm@lists.cs.columbia.edu, iommu@lists.linux-fundation.org, alex.williamson@redhat.com Cc: will.deacon@arm.com, tech@virtualopensystems.com, christoffer.dall@linaro.org, eric.auger@linaro.org, kim.phillips@freescale.com, marc.zyngier@arm.com, Antonios Motakis , Baptiste Reynal , linux-kernel@vger.kernel.org (open list), kvm@vger.kernel.org (open list:VFIO DRIVER) Subject: [PATCH v12 08/18] vfio/platform: return IRQ info Date: Wed, 21 Jan 2015 13:49:56 +0100 Message-Id: <1421844606-24751-9-git-send-email-b.reynal@virtualopensystems.com> X-Mailer: git-send-email 2.2.2 In-Reply-To: <1421844606-24751-1-git-send-email-b.reynal@virtualopensystems.com> References: <1421844606-24751-1-git-send-email-b.reynal@virtualopensystems.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Antonios Motakis 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_common.c | 31 +++++++++++++--- drivers/vfio/platform/vfio_platform_irq.c | 51 +++++++++++++++++++++++++++ drivers/vfio/platform/vfio_platform_private.h | 10 ++++++ 4 files changed, 89 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 279862b..c6316cc 100644 --- a/drivers/vfio/platform/Makefile +++ b/drivers/vfio/platform/Makefile @@ -1,4 +1,4 @@ -vfio-platform-y := vfio_platform.o vfio_platform_common.o +vfio-platform-y := vfio_platform.o vfio_platform_common.o vfio_platform_irq.o obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform.o diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index 6bf78ee..cf7bb08 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -100,6 +100,7 @@ static void vfio_platform_release(void *device_data) if (!(--vdev->refcnt)) { vfio_platform_regions_cleanup(vdev); + vfio_platform_irq_cleanup(vdev); } mutex_unlock(&driver_lock); @@ -121,6 +122,10 @@ static int vfio_platform_open(void *device_data) ret = vfio_platform_regions_init(vdev); if (ret) goto err_reg; + + ret = vfio_platform_irq_init(vdev); + if (ret) + goto err_irq; } vdev->refcnt++; @@ -128,6 +133,8 @@ static int vfio_platform_open(void *device_data) mutex_unlock(&driver_lock); return 0; +err_irq: + vfio_platform_regions_cleanup(vdev); err_reg: mutex_unlock(&driver_lock); module_put(THIS_MODULE); @@ -153,7 +160,7 @@ static long vfio_platform_ioctl(void *device_data, info.flags = vdev->flags; 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); @@ -178,10 +185,26 @@ 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; + } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) { + 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->irqs[info.index].flags; + info.count = vdev->irqs[info.index].count; + + return copy_to_user((void __user *)arg, &info, minsz); - else if (cmd == VFIO_DEVICE_SET_IRQS) + } else if (cmd == VFIO_DEVICE_SET_IRQS) return -EINVAL; else if (cmd == VFIO_DEVICE_RESET) diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c new file mode 100644 index 0000000..c6c3ec1 --- /dev/null +++ b/drivers/vfio/platform/vfio_platform_irq.c @@ -0,0 +1,51 @@ +/* + * 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 "vfio_platform_private.h" + +int vfio_platform_irq_init(struct vfio_platform_device *vdev) +{ + int cnt = 0, i; + + while (vdev->get_irq(vdev, cnt) >= 0) + cnt++; + + vdev->irqs = kcalloc(cnt, sizeof(struct vfio_platform_irq), GFP_KERNEL); + if (!vdev->irqs) + return -ENOMEM; + + for (i = 0; i < cnt; i++) { + vdev->irqs[i].flags = 0; + vdev->irqs[i].count = 1; + } + + vdev->num_irqs = cnt; + + return 0; +} + +void vfio_platform_irq_cleanup(struct vfio_platform_device *vdev) +{ + vdev->num_irqs = 0; + kfree(vdev->irqs); +} diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h index 97c78f9..a2e286e 100644 --- a/drivers/vfio/platform/vfio_platform_private.h +++ b/drivers/vfio/platform/vfio_platform_private.h @@ -27,6 +27,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; @@ -40,6 +45,8 @@ struct vfio_platform_region { struct vfio_platform_device { struct vfio_platform_region *regions; u32 num_regions; + struct vfio_platform_irq *irqs; + u32 num_irqs; int refcnt; /* @@ -59,4 +66,7 @@ extern int vfio_platform_probe_common(struct vfio_platform_device *vdev, extern struct vfio_platform_device *vfio_platform_remove_common (struct device *dev); +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 */