From patchwork Fri Apr 29 12:11:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dong Jia Shi X-Patchwork-Id: 616777 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qxFJS2dcNz9t3Z for ; Fri, 29 Apr 2016 23:43:04 +1000 (AEST) Received: from localhost ([::1]:54540 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aw8h9-0005BL-6T for incoming@patchwork.ozlabs.org; Fri, 29 Apr 2016 09:42:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39909) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aw7I9-0001oI-Q7 for qemu-devel@nongnu.org; Fri, 29 Apr 2016 08:13:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aw7Hx-000346-KS for qemu-devel@nongnu.org; Fri, 29 Apr 2016 08:13:00 -0400 Received: from e19.ny.us.ibm.com ([129.33.205.209]:36819) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aw7Hx-0002tv-F3 for qemu-devel@nongnu.org; Fri, 29 Apr 2016 08:12:53 -0400 Received: from localhost by e19.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 29 Apr 2016 08:12:16 -0400 Received: from d01dlp02.pok.ibm.com (9.56.250.167) by e19.ny.us.ibm.com (146.89.104.206) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 29 Apr 2016 08:12:14 -0400 X-IBM-Helo: d01dlp02.pok.ibm.com X-IBM-MailFrom: bjsdjshi@linux.vnet.ibm.com X-IBM-RcptTo: qemu-devel@nongnu.org; alex.williamson@redhat.com; agraf@suse.com; kvm@vger.kernel.org; linux-s390@vger.kernel.org Received: from b01cxnp23032.gho.pok.ibm.com (b01cxnp23032.gho.pok.ibm.com [9.57.198.27]) by d01dlp02.pok.ibm.com (Postfix) with ESMTP id 5BF7B6E8045; Fri, 29 Apr 2016 08:11:58 -0400 (EDT) Received: from b01ledav001.gho.pok.ibm.com (b01ledav001.gho.pok.ibm.com [9.57.199.106]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u3TCC6Ln37224470; Fri, 29 Apr 2016 12:12:12 GMT Received: from b01ledav001.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CEE5D2803A; Fri, 29 Apr 2016 08:12:10 -0400 (EDT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by b01ledav001.gho.pok.ibm.com (Postfix) with ESMTP id B59A82803E; Fri, 29 Apr 2016 08:12:09 -0400 (EDT) From: Dong Jia Shi To: kvm@vger.kernel.org, linux-s390@vger.kernel.org, qemu-devel@nongnu.org Date: Fri, 29 Apr 2016 14:11:50 +0200 Message-Id: <1461931915-22397-4-git-send-email-bjsdjshi@linux.vnet.ibm.com> X-Mailer: git-send-email 2.6.6 In-Reply-To: <1461931915-22397-1-git-send-email-bjsdjshi@linux.vnet.ibm.com> References: <1461931915-22397-1-git-send-email-bjsdjshi@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16042912-0057-0000-0000-0000042FDC96 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 129.33.205.209 Subject: [Qemu-devel] [PATCH RFC 3/8] vfio: ccw: basic implementation for vfio_ccw driver X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: borntraeger@de.ibm.com, alex.williamson@redhat.com, renxiaof@linux.vnet.ibm.com, cornelia.huck@de.ibm.com, bjsdjshi@linux.vnet.ibm.com, agraf@suse.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add a basic vfio_ccw driver, which depends on the VFIO No-IOMMU support. Add a new config option: Device Drivers --> VFIO Non-Privileged userspace driver framework --> VFIO No-IOMMU support --> VFIO support for ccw devices Signed-off-by: Dong Jia Shi Reviewed-by: Pierre Morel --- arch/s390/include/asm/irq.h | 1 + arch/s390/kernel/irq.c | 1 + drivers/vfio/Kconfig | 1 + drivers/vfio/Makefile | 1 + drivers/vfio/ccw/Kconfig | 7 ++ drivers/vfio/ccw/Makefile | 2 + drivers/vfio/ccw/vfio_ccw.c | 160 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 173 insertions(+) create mode 100644 drivers/vfio/ccw/Kconfig create mode 100644 drivers/vfio/ccw/Makefile create mode 100644 drivers/vfio/ccw/vfio_ccw.c diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h index f97b055..5ec272a 100644 --- a/arch/s390/include/asm/irq.h +++ b/arch/s390/include/asm/irq.h @@ -66,6 +66,7 @@ enum interruption_class { IRQIO_VAI, NMI_NMI, CPU_RST, + IRQIO_VFC, NR_ARCH_IRQS }; diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index c373a1d..706002a 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -88,6 +88,7 @@ static const struct irq_class irqclass_sub_desc[] = { {.irq = IRQIO_VAI, .name = "VAI", .desc = "[I/O] Virtual I/O Devices AI"}, {.irq = NMI_NMI, .name = "NMI", .desc = "[NMI] Machine Check"}, {.irq = CPU_RST, .name = "RST", .desc = "[CPU] CPU Restart"}, + {.irq = IRQIO_VFC, .name = "VFC", .desc = "[I/O] VFIO CCW Devices"}, }; void __init init_IRQ(void) diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index da6e2ce..f1d414c 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -46,6 +46,7 @@ menuconfig VFIO_NOIOMMU If you don't know what to do here, say N. +source "drivers/vfio/ccw/Kconfig" source "drivers/vfio/pci/Kconfig" source "drivers/vfio/platform/Kconfig" source "virt/lib/Kconfig" diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile index 7b8a31f..2b39593 100644 --- a/drivers/vfio/Makefile +++ b/drivers/vfio/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o obj-$(CONFIG_VFIO_SPAPR_EEH) += vfio_spapr_eeh.o obj-$(CONFIG_VFIO_PCI) += pci/ obj-$(CONFIG_VFIO_PLATFORM) += platform/ +obj-$(CONFIG_VFIO_CCW) += ccw/ diff --git a/drivers/vfio/ccw/Kconfig b/drivers/vfio/ccw/Kconfig new file mode 100644 index 0000000..6281152 --- /dev/null +++ b/drivers/vfio/ccw/Kconfig @@ -0,0 +1,7 @@ +config VFIO_CCW + tristate "VFIO support for CCW devices" + depends on VFIO_NOIOMMU && CCW + help + VFIO support for CCW bus driver. Note that this is just + the base driver; you'll also need a userspace program + to provide a device configuration and channel programs. diff --git a/drivers/vfio/ccw/Makefile b/drivers/vfio/ccw/Makefile new file mode 100644 index 0000000..ea14ca9 --- /dev/null +++ b/drivers/vfio/ccw/Makefile @@ -0,0 +1,2 @@ +vfio-ccw-y := vfio_ccw.o +obj-$(CONFIG_VFIO_CCW) += vfio-ccw.o diff --git a/drivers/vfio/ccw/vfio_ccw.c b/drivers/vfio/ccw/vfio_ccw.c new file mode 100644 index 0000000..8b0acae --- /dev/null +++ b/drivers/vfio/ccw/vfio_ccw.c @@ -0,0 +1,160 @@ +/* + * vfio based ccw device driver + * + * Copyright IBM Corp. 2016 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Dong Jia Shi + * Xiao Feng Ren + */ + +#include +#include +#include +#include +#include +#include + +/** + * struct vfio_ccw_device + * @cdev: ccw device + * @going_away: if an offline procedure was already ongoing + */ +struct vfio_ccw_device { + struct ccw_device *cdev; + bool going_away; +}; + +enum vfio_ccw_device_type { + vfio_dasd_eckd, +}; + +struct ccw_device_id vfio_ccw_ids[] = { + { CCW_DEVICE_DEVTYPE(0x3990, 0, 0x3390, 0), + .driver_info = vfio_dasd_eckd}, + { /* End of list. */ }, +}; +MODULE_DEVICE_TABLE(ccw, vfio_ccw_ids); + +/* + * vfio callbacks + */ +static int vfio_ccw_open(void *device_data) +{ + if (!try_module_get(THIS_MODULE)) + return -ENODEV; + + return 0; +} + +static void vfio_ccw_release(void *device_data) +{ + module_put(THIS_MODULE); +} + +static long vfio_ccw_ioctl(void *device_data, unsigned int cmd, + unsigned long arg) +{ + return -ENOTTY; +} + +static const struct vfio_device_ops vfio_ccw_ops = { + .name = "vfio_ccw", + .open = vfio_ccw_open, + .release = vfio_ccw_release, + .ioctl = vfio_ccw_ioctl, +}; + +static int vfio_ccw_probe(struct ccw_device *cdev) +{ + struct iommu_group *group = vfio_iommu_group_get(&cdev->dev); + + if (!group) + return -EINVAL; + + return 0; +} + +static int vfio_ccw_set_offline(struct ccw_device *cdev) +{ + struct vfio_device *device = vfio_device_get_from_dev(&cdev->dev); + struct vfio_ccw_device *vdev; + + if (!device) + return 0; + + vdev = vfio_device_data(device); + vfio_device_put(device); + if (!vdev || vdev->going_away) + return 0; + + vdev->going_away = true; + vfio_del_group_dev(&cdev->dev); + kfree(vdev); + + return 0; +} + +void vfio_ccw_remove(struct ccw_device *cdev) +{ + if (cdev && cdev->online) + vfio_ccw_set_offline(cdev); + + vfio_iommu_group_put(cdev->dev.iommu_group, &cdev->dev); +} + +static int vfio_ccw_set_online(struct ccw_device *cdev) +{ + struct vfio_ccw_device *vdev; + int ret; + + vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + if (!vdev) + return -ENOMEM; + + vdev->cdev = cdev; + + ret = vfio_add_group_dev(&cdev->dev, &vfio_ccw_ops, vdev); + if (ret) + kfree(vdev); + + return ret; +} + +static int vfio_ccw_notify(struct ccw_device *cdev, int event) +{ + /* LATER: We probably need to handle device/path state changes. */ + return 0; +} + +static struct ccw_driver vfio_ccw_driver = { + .driver = { + .name = "vfio_ccw", + .owner = THIS_MODULE, + }, + .ids = vfio_ccw_ids, + .probe = vfio_ccw_probe, + .remove = vfio_ccw_remove, + .set_offline = vfio_ccw_set_offline, + .set_online = vfio_ccw_set_online, + .notify = vfio_ccw_notify, + .int_class = IRQIO_VFC, +}; + +static int __init vfio_ccw_init(void) +{ + return ccw_driver_register(&vfio_ccw_driver); +} + +static void __exit vfio_ccw_cleanup(void) +{ + ccw_driver_unregister(&vfio_ccw_driver); +} + +module_init(vfio_ccw_init); +module_exit(vfio_ccw_cleanup); + +MODULE_LICENSE("GPL v2");