From patchwork Thu Sep 1 19:50:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 1120442 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p81Jpw1b012934 for ; Thu, 1 Sep 2011 19:51:58 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757912Ab1IATv5 (ORCPT ); Thu, 1 Sep 2011 15:51:57 -0400 Received: from mx1.redhat.com ([209.132.183.28]:62351 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757676Ab1IATv4 (ORCPT ); Thu, 1 Sep 2011 15:51:56 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p81JoqXu014293 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 1 Sep 2011 15:50:52 -0400 Received: from s20.home (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p81Joobi026798; Thu, 1 Sep 2011 15:50:50 -0400 From: Alex Williamson Subject: [RFC PATCH 4/5] VFIO: Add PCI device support To: chrisw@sous-sol.org, aik@au1.ibm.com, pmac@au1.ibm.com, dwg@au1.ibm.com, joerg.roedel@amd.com, agraf@suse.de, benve@cisco.com, aafabbri@cisco.com, B08248@freescale.com, B07421@freescale.com, avi@redhat.com, kvm@vger.kernel.org, qemu-devel@nongnu.org, iommu@lists.linux-foundation.org, linux-pci@vger.kernel.org Cc: alex.williamson@redhat.com Date: Thu, 01 Sep 2011 13:50:50 -0600 Message-ID: <20110901195050.2391.12028.stgit@s20.home> In-Reply-To: <20110901194915.2391.97400.stgit@s20.home> References: <20110901194915.2391.97400.stgit@s20.home> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 01 Sep 2011 19:51:58 +0000 (UTC) Signed-off-by: Alex Williamson --- drivers/vfio/Kconfig | 7 ++ drivers/vfio/Makefile | 1 drivers/vfio/vfio_main.c | 10 +++ drivers/vfio/vfio_pci.c | 124 +++++++++++++++++++++++++++++++++++++++++++ drivers/vfio/vfio_private.h | 5 ++ 5 files changed, 147 insertions(+), 0 deletions(-) create mode 100644 drivers/vfio/vfio_pci.c -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index a150521..b17bdbd 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -3,3 +3,10 @@ menuconfig VFIO depends on IOMMU_API help If you don't know what to do here, say N. + +menuconfig VFIO_PCI + bool "VFIO support for PCI devices" + depends on VFIO && PCI + default y if X86 + help + If you don't know what to do here, say N. diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile index 5eaa074..90ee753 100644 --- a/drivers/vfio/Makefile +++ b/drivers/vfio/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_VFIO) := vfio.o vfio-y := vfio_main.o vfio_iommu.o vfio_device.o +vfio-$(CONFIG_VFIO_PCI) += vfio_pci.o diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 7f05692..c6e80f7 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -834,6 +834,12 @@ static int __init vfio_init(void) if (ret) goto err_cdev; +#ifdef CONFIG_VFIO_PCI + ret = vfio_pci_init(&vfio); + if (ret) + pr_debug(DRIVER_DESC "PCI init failed %d\n", ret); +#endif + pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); return 0; @@ -864,6 +870,10 @@ static void __exit vfio_cleanup(void) } } +#ifdef CONFIG_VFIO_PCI + vfio_pci_cleanup(&vfio); +#endif + idr_destroy(&vfio.idr); cdev_del(&vfio.cdev); unregister_chrdev_region(vfio.devt, MINORMASK); diff --git a/drivers/vfio/vfio_pci.c b/drivers/vfio/vfio_pci.c new file mode 100644 index 0000000..88325d0 --- /dev/null +++ b/drivers/vfio/vfio_pci.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2011 Red Hat, Inc. All rights reserved. + * Author: Alex Williamson + * + * 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. + * + * Derived from original vfio: + * Copyright 2010 Cisco Systems, Inc. All rights reserved. + * Author: Tom Lyon, pugs@cisco.com + */ + +#include +#include +#include +#include +#include + +#include "vfio_private.h" + +struct vfio_pci_device { + struct vfio_device vdev; + struct pci_dev *pdev; +}; + +static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + return 0; +} + +static void vfio_pci_remove(struct pci_dev *pdev) +{ +} + +static struct pci_driver vfio_pci_driver = { + .name = "vfio", + .id_table = NULL, /* only dynamic id's */ + .probe = vfio_pci_probe, + .remove = vfio_pci_remove, +}; + +static struct vfio_device *vfio_pci_new(struct device *dev) +{ + struct vfio_pci_device *pvdev; + + pvdev = kzalloc(sizeof(*pvdev), GFP_KERNEL); + if (!pvdev) + return ERR_PTR(-ENOMEM); + + printk("%s: alloc pvdev @%p\n", __FUNCTION__, pvdev); + pvdev->pdev = container_of(dev, struct pci_dev, dev); + + // PCI stuff... + + return &pvdev->vdev; +} + +static void vfio_pci_free(struct vfio_device *vdev) +{ + struct vfio_pci_device *pvdev; + + pvdev = container_of(vdev, struct vfio_pci_device, vdev); + + // PCI stuff... + + printk("%s: freeing pvdev @%p\n", __FUNCTION__, pvdev); + kfree(pvdev); +} + +static const struct vfio_device_ops vfio_pci_ops = { + .new = vfio_pci_new, + .free = vfio_pci_free, +}; + +static int vfio_pci_device_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); + + if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) + return 0; + + if (action == BUS_NOTIFY_ADD_DEVICE) + return vfio_group_add_dev(dev, (void *)&vfio_pci_ops); + else if (action == BUS_NOTIFY_DEL_DEVICE) + vfio_group_del_dev(dev); + return 0; +} + +static int vfio_pci_add_dev(struct device *dev, void *unused) +{ + struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); + + if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) + return 0; + + return vfio_group_add_dev(dev, (void *)&vfio_pci_ops); +} + +static struct notifier_block vfio_pci_device_nb = { + .notifier_call = vfio_pci_device_notifier, +}; + +void __exit vfio_pci_cleanup(struct vfio *vfio) +{ + bus_unregister_notifier(&pci_bus_type, &vfio_pci_device_nb); + pci_unregister_driver(&vfio_pci_driver); +} + +int __init vfio_pci_init(struct vfio *vfio) +{ + int ret; + + ret = pci_register_driver(&vfio_pci_driver); + if (ret) + return ret; + + bus_register_notifier(&pci_bus_type, &vfio_pci_device_nb); + bus_for_each_dev(&pci_bus_type, NULL, NULL, vfio_pci_add_dev); + + return 0; +} diff --git a/drivers/vfio/vfio_private.h b/drivers/vfio/vfio_private.h index 2cc300c..85c88ea 100644 --- a/drivers/vfio/vfio_private.h +++ b/drivers/vfio/vfio_private.h @@ -79,4 +79,9 @@ struct vfio_group { extern int vfio_group_add_dev(struct device *dev, void *data); extern void vfio_group_del_dev(struct device *dev); +#ifdef CONFIG_VFIO_PCI +extern int vfio_pci_init(struct vfio *vfio); +extern void vfio_pci_cleanup(struct vfio *vfio); +#endif + #endif /* VFIO_PRIVATE_H */