From patchwork Thu Apr 27 14:35:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 9702971 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B083C601D3 for ; Thu, 27 Apr 2017 14:41:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9A7BE28636 for ; Thu, 27 Apr 2017 14:41:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8E5F028655; Thu, 27 Apr 2017 14:41:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 609A628636 for ; Thu, 27 Apr 2017 14:41:56 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d3kaD-0001y5-0h; Thu, 27 Apr 2017 14:39:49 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d3kaA-0001xi-Tx for xen-devel@lists.xenproject.org; Thu, 27 Apr 2017 14:39:47 +0000 Received: from [85.158.143.35] by server-4.bemta-6.messagelabs.com id CB/46-02956-2B202095; Thu, 27 Apr 2017 14:39:46 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprLIsWRWlGSWpSXmKPExsXitHSDve5GJqZ Ig8lbdC2+b5nM5MDocfjDFZYAxijWzLyk/IoE1oxZO56wF8zUr1g25wNbA+N6uS5GTg4JAX+J TxO+MoLYbAI6Ehfn7mTrYuTgEBFQkbi916CLkYuDWWAuo8TLd4tZQGqEBXwkeo/sYwOxWQRUJ Y6/nAYW5xWwlGi6+5wVYqaexNuJL8BmcgpYSbx7fRnMFgKqmTz3IRNEvaDEyZlPwHqZBTQlWr f/Zoew5SWat85mhqhXlOif94BtAiPfLCQts5C0zELSsoCReRWjRnFqUVlqka6hpV5SUWZ6Rkl uYmaOrqGBmV5uanFxYnpqTmJSsV5yfu4mRmCwMQDBDsYfywIOMUpyMCmJ8soeZIwU4kvKT6nM SCzOiC8qzUktPsQow8GhJMFbxMgUKSRYlJqeWpGWmQMMe5i0BAePkgivNEiat7ggMbc4Mx0id YpRUUqc1w4kIQCSyCjNg2uDxdolRlkpYV5GoEOEeApSi3IzS1DlXzGKczAqCfNqgEzhycwrgZ v+CmgxE9BiFhcGkMUliQgpqQbG5uRaAWWxxvLVS7IqAqfbfZilsGuT/FmbxSy1x9ZVe+/YGXd eJOaOsI3GhWhZlXfTDA/efprdffyGUNvTk+sPdjurCe0+HWU6O6r90iHb806Gv2s69/1UEFdN eJdUanDU6s+Msu+vwi9UGpxcksTpLiwm/fb+SuF5S5/cDtzHO29TMv8a9sYPSizFGYmGWsxFx YkAu0XgKbACAAA= X-Env-Sender: prvs=283fe5697=roger.pau@citrix.com X-Msg-Ref: server-10.tower-21.messagelabs.com!1493303984!59020718!1 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 55768 invoked from network); 27 Apr 2017 14:39:45 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-10.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 27 Apr 2017 14:39:45 -0000 X-IronPort-AV: E=Sophos;i="5.37,384,1488844800"; d="scan'208";a="430028074" From: Roger Pau Monne To: Date: Thu, 27 Apr 2017 15:35:41 +0100 Message-ID: <20170427143546.14662-5-roger.pau@citrix.com> X-Mailer: git-send-email 2.11.0 (Apple Git-81) In-Reply-To: <20170427143546.14662-1-roger.pau@citrix.com> References: <20170427143546.14662-1-roger.pau@citrix.com> MIME-Version: 1.0 Cc: boris.ostrovsky@oracle.com, Roger Pau Monne , julien.grall@arm.com, Jan Beulich Subject: [Xen-devel] [PATCH v3 4/9] xen/pci: split code to size BARs from pci_add_device X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP So that it can be called from outside in order to get the size of regular PCI BARs. This will be required in order to map the BARs from PCI devices into PVH Dom0 p2m. Signed-off-by: Roger Pau Monné --- Cc: Jan Beulich --- xen/drivers/passthrough/pci.c | 86 ++++++++++++++++++++++++++----------------- xen/include/xen/pci.h | 3 ++ 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 2288cf8814..7710c41533 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -588,6 +588,51 @@ static void pci_enable_acs(struct pci_dev *pdev) pci_conf_write16(seg, bus, dev, func, pos + PCI_ACS_CTRL, ctrl); } +int pci_size_bar(unsigned int seg, unsigned int bus, unsigned int slot, + unsigned int func, unsigned int base, unsigned int max_bars, + unsigned int *index, uint64_t *addr, uint64_t *size) +{ + unsigned int idx = base + *index * 4; + u32 bar = pci_conf_read32(seg, bus, slot, func, idx); + u32 hi = 0; + + *addr = *size = 0; + + ASSERT((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_conf_write32(seg, bus, slot, func, idx, ~0); + if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64 ) + { + if ( *index >= max_bars ) + { + dprintk(XENLOG_WARNING, + "device %04x:%02x:%02x.%u with 64-bit BAR in last slot\n", + seg, bus, slot, func); + return -EINVAL; + } + hi = pci_conf_read32(seg, bus, slot, func, idx + 4); + pci_conf_write32(seg, bus, slot, func, idx + 4, ~0); + } + *size = pci_conf_read32(seg, bus, slot, func, idx) & + PCI_BASE_ADDRESS_MEM_MASK; + if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64 ) + { + *size |= (u64)pci_conf_read32(seg, bus, slot, func, idx + 4) << 32; + pci_conf_write32(seg, bus, slot, func, idx + 4, hi); + } + else if ( *size ) + *size |= (u64)~0 << 32; + pci_conf_write32(seg, bus, slot, func, idx, bar); + *size = -(*size); + *addr = (bar & PCI_BASE_ADDRESS_MEM_MASK) | ((u64)hi << 32); + if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64 ) + ++*index; + + return 0; +} + int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct pci_dev_info *info, nodeid_t node) { @@ -652,7 +697,7 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, { unsigned int idx = pos + PCI_SRIOV_BAR + i * 4; u32 bar = pci_conf_read32(seg, bus, slot, func, idx); - u32 hi = 0; + uint64_t addr; if ( (bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO ) @@ -663,38 +708,13 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, seg, bus, slot, func, i); continue; } - pci_conf_write32(seg, bus, slot, func, idx, ~0); - if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == - PCI_BASE_ADDRESS_MEM_TYPE_64 ) - { - if ( i >= PCI_SRIOV_NUM_BARS ) - { - printk(XENLOG_WARNING - "SR-IOV device %04x:%02x:%02x.%u with 64-bit" - " vf BAR in last slot\n", - seg, bus, slot, func); - break; - } - hi = pci_conf_read32(seg, bus, slot, func, idx + 4); - pci_conf_write32(seg, bus, slot, func, idx + 4, ~0); - } - pdev->vf_rlen[i] = pci_conf_read32(seg, bus, slot, func, idx) & - PCI_BASE_ADDRESS_MEM_MASK; - if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == - PCI_BASE_ADDRESS_MEM_TYPE_64 ) - { - pdev->vf_rlen[i] |= (u64)pci_conf_read32(seg, bus, - slot, func, - idx + 4) << 32; - pci_conf_write32(seg, bus, slot, func, idx + 4, hi); - } - else if ( pdev->vf_rlen[i] ) - pdev->vf_rlen[i] |= (u64)~0 << 32; - pci_conf_write32(seg, bus, slot, func, idx, bar); - pdev->vf_rlen[i] = -pdev->vf_rlen[i]; - if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == - PCI_BASE_ADDRESS_MEM_TYPE_64 ) - ++i; + ret = pci_size_bar(seg, bus, slot, func, pos + PCI_SRIOV_BAR, + PCI_SRIOV_NUM_BARS, &i, &addr, + &pdev->vf_rlen[i]); + if ( ret ) + dprintk(XENLOG_WARNING, + "%04x:%02x:%02x.%u: failed to size SR-IOV BAR%u\n", + seg, bus, slot, func, i); } } else diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index a83c4a1276..3d3853fd6f 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -165,6 +165,9 @@ const char *parse_pci(const char *, unsigned int *seg, unsigned int *bus, unsigned int *dev, unsigned int *func); const char *parse_pci_seg(const char *, unsigned int *seg, unsigned int *bus, unsigned int *dev, unsigned int *func, bool *def_seg); +int pci_size_bar(unsigned int seg, unsigned int bus, unsigned int slot, + unsigned int func, unsigned int base, unsigned int max_bars, + unsigned int *index, uint64_t *addr, uint64_t *size); bool_t pcie_aer_get_firmware_first(const struct pci_dev *);