From patchwork Wed Jun 30 06:14:12 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 108743 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o5U6EvR5005961 for ; Wed, 30 Jun 2010 06:14:58 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752251Ab0F3GOz (ORCPT ); Wed, 30 Jun 2010 02:14:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:7048 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752232Ab0F3GOy (ORCPT ); Wed, 30 Jun 2010 02:14:54 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o5U6EFPG005261 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 30 Jun 2010 02:14:15 -0400 Received: from [172.17.76.4] (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o5U6ED9h003771; Wed, 30 Jun 2010 02:14:13 -0400 Subject: Re: [PATCH V2] VFIO driver: Non-privileged user level PCI drivers From: Alex Williamson To: Tom Lyon Cc: randy.dunlap@oracle.com, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, chrisw@sous-sol.org, joro@8bytes.org, hjk@linutronix.de, mst@redhat.com, avi@redhat.com, gregkh@suse.de, aafabbri@cisco.com, scofeldm@cisco.com In-Reply-To: <4c0eb470.1HMjondO00NIvFM6%pugs@cisco.com> References: <4c0eb470.1HMjondO00NIvFM6%pugs@cisco.com> Date: Wed, 30 Jun 2010 00:14:12 -0600 Message-ID: <1277878452.3164.26.camel@x201> Mime-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 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 (demeter.kernel.org [140.211.167.41]); Wed, 30 Jun 2010 06:14:58 +0000 (UTC) diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 96639e5..a0e8227 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -129,6 +129,10 @@ static int vfio_release(struct inode *inode, struct file *filep) eventfd_ctx_put(vdev->ev_msi); vdev->ev_irq = NULL; } + if (vdev->pci_config_map) { + kfree(vdev->pci_config_map); + vdev->pci_config_map = NULL; + } vfio_domain_unset(vdev); /* reset to known state if we can */ (void) pci_reset_function(vdev->pdev); diff --git a/drivers/vfio/vfio_pci_config.c b/drivers/vfio/vfio_pci_config.c index c821b5d..f6e26b1 100644 --- a/drivers/vfio/vfio_pci_config.c +++ b/drivers/vfio/vfio_pci_config.c @@ -79,18 +79,18 @@ struct perm_bits { static struct perm_bits pci_cap_basic_perm[] = { { 0xFFFFFFFF, 0, }, /* 0x00 vendor & device id - RO */ { 0, 0xFFFFFFFC, }, /* 0x04 cmd & status except mem/io */ - { 0, 0xFF00FFFF, }, /* 0x08 bist, htype, lat, cache */ - { 0xFFFFFFFF, 0xFFFFFFFF, }, /* 0x0c bar */ + { 0, 0, }, /* 0x08 class code & revision id */ + { 0, 0xFF00FFFF, }, /* 0x0c bist, htype, lat, cache */ { 0xFFFFFFFF, 0xFFFFFFFF, }, /* 0x10 bar */ { 0xFFFFFFFF, 0xFFFFFFFF, }, /* 0x14 bar */ { 0xFFFFFFFF, 0xFFFFFFFF, }, /* 0x18 bar */ { 0xFFFFFFFF, 0xFFFFFFFF, }, /* 0x1c bar */ { 0xFFFFFFFF, 0xFFFFFFFF, }, /* 0x20 bar */ - { 0, 0, }, /* 0x24 cardbus - not yet */ - { 0, 0, }, /* 0x28 subsys vendor & dev */ - { 0xFFFFFFFF, 0xFFFFFFFF, }, /* 0x2c rom bar */ - { 0, 0, }, /* 0x30 capability ptr & resv */ - { 0, 0, }, /* 0x34 resv */ + { 0xFFFFFFFF, 0xFFFFFFFF, }, /* 0x24 bar */ + { 0, 0, }, /* 0x28 cardbus - not yet */ + { 0, 0, }, /* 0x2c subsys vendor & dev */ + { 0xFFFFFFFF, 0xFFFFFFFF, }, /* 0x30 rom bar */ + { 0, 0, }, /* 0x34 capability ptr & resv */ { 0, 0, }, /* 0x38 resv */ { 0x000000FF, 0x000000FF, }, /* 0x3c max_lat ... irq */ }; @@ -318,30 +318,55 @@ static void vfio_virt_init(struct vfio_dev *vdev) static void vfio_bar_fixup(struct vfio_dev *vdev) { struct pci_dev *pdev = vdev->pdev; - int bar; - u32 *lp; - u32 len; + int bar, mem64 = 0; + u32 *lp = NULL; + u64 len = 0; for (bar = 0; bar <= 5; bar++) { - len = pci_resource_len(pdev, bar); - lp = (u32 *)&vdev->vinfo.bar[bar * 4]; - if (len == 0) { - *lp = 0; - } else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { - *lp &= ~0x1; - *lp = (*lp & ~(len-1)) | - (*lp & ~PCI_BASE_ADDRESS_MEM_MASK); - if (*lp & PCI_BASE_ADDRESS_MEM_TYPE_64) - bar++; - } else if (pci_resource_flags(pdev, bar) & IORESOURCE_IO) { + if (!mem64) { + len = pci_resource_len(pdev, bar); + lp = (u32 *)&vdev->vinfo.bar[bar * 4]; + if (len == 0) { + *lp = 0; + continue; + } + + len = ~(len - 1); + } else + len >>= 32; + + if (*lp == ~0U) + *lp = (u32)len; + else + *lp &= (u32)len; + + if (mem64) { + mem64 = 0; + continue; + } + + if (pci_resource_flags(pdev, bar) & IORESOURCE_IO) *lp |= PCI_BASE_ADDRESS_SPACE_IO; - *lp = (*lp & ~(len-1)) | - (*lp & ~PCI_BASE_ADDRESS_IO_MASK); + else { + *lp |= PCI_BASE_ADDRESS_SPACE_MEMORY; + if (pci_resource_flags(pdev, bar) & IORESOURCE_PREFETCH) + *lp |= PCI_BASE_ADDRESS_MEM_PREFETCH; + if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM_64) { + *lp |= PCI_BASE_ADDRESS_MEM_TYPE_64; + mem64 = 1; + } } } + lp = (u32 *)vdev->vinfo.rombar; len = pci_resource_len(pdev, PCI_ROM_RESOURCE); - *lp = *lp & PCI_ROM_ADDRESS_MASK & ~(len-1); + len = ~(len - 1); + + if (*lp == ~PCI_ROM_ADDRESS_ENABLE) + *lp = (u32)len; + else + *lp = *lp & ((u32)len | PCI_ROM_ADDRESS_ENABLE); + vdev->vinfo.bardirty = 0; }