From patchwork Mon Sep 27 20:46:32 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 213412 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o8RKlW86017047 for ; Mon, 27 Sep 2010 20:47:32 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760216Ab0I0Uqu (ORCPT ); Mon, 27 Sep 2010 16:46:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:17808 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760199Ab0I0Uqt (ORCPT ); Mon, 27 Sep 2010 16:46:49 -0400 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8RKkYXo003402 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 27 Sep 2010 16:46:34 -0400 Received: from [10.3.113.98] (ovpn-113-98.phx2.redhat.com [10.3.113.98]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o8RKkWnD012498; Mon, 27 Sep 2010 16:46:32 -0400 Subject: Re: [PATCH 3/3] VFIO V4: VFIO driver: Non-privileged user level PCI drivers From: Alex Williamson To: Tom Lyon Cc: linux-pci@vger.kernel.org, jbarnes@virtuousgeek.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, randy.dunlap@oracle.com, arnd@arndb.de, joro@8bytes.org, hjk@linutronix.de, avi@redhat.com, gregkh@suse.de, chrisw@sous-sol.org, mst@redhat.com In-Reply-To: <4c9a72a0.u2cnjUB7QZ91tLeo%pugs@cisco.com> References: <4c9a72a0.u2cnjUB7QZ91tLeo%pugs@cisco.com> Date: Mon, 27 Sep 2010 14:46:32 -0600 Message-ID: <1285620392.4951.50.camel@x201> Mime-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21 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.3 (demeter1.kernel.org [140.211.167.41]); Mon, 27 Sep 2010 20:47:32 +0000 (UTC) diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index a18e39a..d3886d9 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -85,6 +85,53 @@ static inline int overlap(int a1, int b1, int a2, int b2) return !(b2 <= a1 || b1 <= a2); } +static int vfio_setup_pci(struct vfio_dev *vdev) +{ + int ret, bar; + + ret = pci_enable_device(vdev->pdev); + if (ret) + return ret; + + ret = pci_request_regions(vdev->pdev, "VFIO"); + if (ret) { + pci_disable_device(vdev->pdev); + return ret; + } + + for (bar = PCI_STD_RESOURCES; bar <= PCI_ROM_RESOURCE; bar++) { + if (!pci_resource_len(vdev->pdev, bar)) + continue; + if (bar != PCI_ROM_RESOURCE) { + if (!pci_resource_start(vdev->pdev, bar)) + continue; + vdev->barmap[bar] = pci_iomap(vdev->pdev, bar, 0); + } else { + size_t size; + vdev->barmap[bar] = pci_map_rom(vdev->pdev, &size); + } + } + return ret; +} + +static void vfio_disable_pci(struct vfio_dev *vdev) +{ + int bar; + + for (bar = PCI_STD_RESOURCES; bar <= PCI_ROM_RESOURCE; bar++) { + if (!vdev->barmap[bar]) + continue; + if (bar != PCI_ROM_RESOURCE) + pci_iounmap(vdev->pdev, vdev->barmap[bar]); + else + pci_unmap_rom(vdev->pdev, vdev->barmap[bar]); + vdev->barmap[bar] = NULL; + } + + pci_release_regions(vdev->pdev); + pci_disable_device(vdev->pdev); +} + static int vfio_open(struct inode *inode, struct file *filep) { struct vfio_dev *vdev; @@ -110,7 +157,7 @@ static int vfio_open(struct inode *inode, struct file *filep) INIT_LIST_HEAD(&listener->dm_list); filep->private_data = listener; if (vdev->listeners == 0) - ret = pci_enable_device(vdev->pdev); + ret = vfio_setup_pci(vdev); if (ret == 0) vdev->listeners++; mutex_unlock(&vdev->lgate); @@ -151,7 +198,7 @@ static int vfio_release(struct inode *inode, struct file *filep) vdev->vconfig = NULL; kfree(vdev->pci_config_map); vdev->pci_config_map = NULL; - pci_disable_device(vdev->pdev); + vfio_disable_pci(vdev); vfio_domain_unset(vdev); wake_up(&vdev->dev_idle_q); } diff --git a/drivers/vfio/vfio_rdwr.c b/drivers/vfio/vfio_rdwr.c index 1fd50a6..7705b45 100644 --- a/drivers/vfio/vfio_rdwr.c +++ b/drivers/vfio/vfio_rdwr.c @@ -64,7 +64,7 @@ ssize_t vfio_io_readwrite( if (pos + count > end) return -EINVAL; if (vdev->barmap[pci_space] == NULL) - vdev->barmap[pci_space] = pci_iomap(pdev, pci_space, 0); + return -EINVAL; io = vdev->barmap[pci_space]; while (count > 0) { @@ -137,7 +137,12 @@ ssize_t vfio_mem_readwrite( return -EINVAL; end = pci_resource_len(pdev, pci_space); if (vdev->barmap[pci_space] == NULL) - vdev->barmap[pci_space] = pci_iomap(pdev, pci_space, 0); + return -EINVAL; + if (pci_space == PCI_ROM_RESOURCE) { + u32 rom = *(u32 *)(vdev->vconfig + PCI_ROM_ADDRESS); + if (!(rom & PCI_ROM_ADDRESS_ENABLE)) + return -EINVAL; + } io = vdev->barmap[pci_space]; if (pos > end)