From patchwork Fri Jan 30 13:46:14 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baptiste Reynal X-Patchwork-Id: 5750421 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 3E980BF440 for ; Fri, 30 Jan 2015 13:52:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 522FE2025B for ; Fri, 30 Jan 2015 13:52:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3CBE82027D for ; Fri, 30 Jan 2015 13:52:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1762341AbbA3Nse (ORCPT ); Fri, 30 Jan 2015 08:48:34 -0500 Received: from mail-wi0-f169.google.com ([209.85.212.169]:51980 "EHLO mail-wi0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755391AbbA3Nsa (ORCPT ); Fri, 30 Jan 2015 08:48:30 -0500 Received: by mail-wi0-f169.google.com with SMTP id h11so3044609wiw.0 for ; Fri, 30 Jan 2015 05:48:29 -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=/PMKqBCGIHYePQ62xpk1ZaPOrHW4br4kXJUnx0mH2Ps=; b=NhCet0jqTVOY31u+Q+Vcxr0MBrj4st74jGQ1tdL9ys3RDT85E1Wjh4GGa3yJgq34MC 9EzdVwSsMeEOh6vJMyp3h/cWWyd84SjQQFdFe5XsKqWfS+t/ybJ/17T3I5ftNAK2U0KF EW1g/xWRmaaqfAzDC3kfIlXhhq+DbhCfy0nnmY7nNCSCfeBhN320ajQtp8UeEyzgKTtk bdJvgGQ22c/GKJWyzNl9ElXM5WjzNM1ilF+f14ixj3iOvV1+OtTXbtwFqRdCt6RkcsMu U5Vcwr8SUcx9kTxBjpPYZhW53QOb5JJKxz/FaaumlbCeeeIRh1bI6DNoZ65AlS92X5ue +Rsw== X-Gm-Message-State: ALoCoQlGa5wxqYCMhY3ekgtCtjiPkrSOKR3/lI/rxabH98ORJp0fluU3fLBIlCwH/Eritz3k5O75 X-Received: by 10.180.74.6 with SMTP id p6mr5001374wiv.79.1422625709190; Fri, 30 Jan 2015 05:48:29 -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 n3sm6338585wjq.30.2015.01.30.05.48.28 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Jan 2015 05:48:28 -0800 (PST) From: Baptiste Reynal To: kvmarm@lists.cs.columbia.edu, iommu@lists.linux-foundation.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 v13 08/18] vfio/platform: return IRQ info Date: Fri, 30 Jan 2015 14:46:14 +0100 Message-Id: <1422625584-3741-9-git-send-email-b.reynal@virtualopensystems.com> X-Mailer: git-send-email 2.2.2 In-Reply-To: <1422625584-3741-1-git-send-email-b.reynal@virtualopensystems.com> References: <1422625584-3741-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=unavailable 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 d7fe2c7..908d510 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -101,6 +101,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); @@ -122,6 +123,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++; @@ -129,6 +134,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); @@ -154,7 +161,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); @@ -179,10 +186,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 */