From patchwork Fri Jun 30 15:01:13 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: 9819827 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 BC21B602B1 for ; Fri, 30 Jun 2017 15:03:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9CA4D28338 for ; Fri, 30 Jun 2017 15:03:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 913BE2853A; Fri, 30 Jun 2017 15:03:56 +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 1C90028338 for ; Fri, 30 Jun 2017 15:03: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 1dQxQX-0003AC-BV; Fri, 30 Jun 2017 15:01:45 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dQxQV-00038y-Mr for xen-devel@lists.xenproject.org; Fri, 30 Jun 2017 15:01:43 +0000 Received: from [85.158.143.35] by server-8.bemta-6.messagelabs.com id 7D/81-03704-6D766595; Fri, 30 Jun 2017 15:01:42 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrGIsWRWlGSWpSXmKPExsXitHSDve619LB Ig8ZPIhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8aCm7dZCv4ZVfx4dJO9gbFTsYuRk0NCwF/i 3PNHTCA2m4COxMW5O9m6GDk4RARUJG7vNQAJMwvMZZS4PU8MxBYW8JHYcncJE0gJi4CqxPdWJ ZAwr4ClxKrlu1ggJupJvJ34ghGkhFPASuLEJBmQsBBQycI/l5kgygUlTs58wgIxXVOidftvdg hbXqJ562xmiHpFif55D9gmMPLNQtIyC0nLLCQtCxiZVzFqFKcWlaUW6Rpa6iUVZaZnlOQmZub oGhqY6eWmFhcnpqfmJCYV6yXn525iBIYZAxDsYPyxLOAQoyQHk5Io78proZFCfEn5KZUZicUZ 8UWlOanFhxhlODiUJHhb08IihQSLUtNTK9Iyc4ABD5OW4OBREuGVDQJK8xYXJOYWZ6ZDpE4x6 nIcm/HzG5MQS15+XqqUOO9ZkBkCIEUZpXlwI2DRd4lRVkqYlxHoKCGegtSi3MwSVPlXjOIcjE rCvKdBpvBk5pXAbXoFdAQT0BHCM0JAjihJREhJNTD6yDEv2Ls28ItTCMe5ua3n355Yfyy2co1 ghRT7gvOpM9iuzdt/u2LGU0bu9WtTDv9o3nPWo/U28745y4PW3mr9df581oGr372qCieVzJfQ K9Kper8gPeB8SOL3owEN6Rt+/HikGMH0TyDl5smLV8TrHS4qmtfZz836VxfXc8V8meb+w2oRe ywclFiKMxINtZiLihMB43fsYrkCAAA= X-Env-Sender: prvs=3475c4a2e=roger.pau@citrix.com X-Msg-Ref: server-2.tower-21.messagelabs.com!1498834898!57200718!2 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.25; banners=-,-,- X-VirusChecked: Checked Received: (qmail 26888 invoked from network); 30 Jun 2017 15:01:41 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-2.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 30 Jun 2017 15:01:41 -0000 X-IronPort-AV: E=Sophos;i="5.40,287,1496102400"; d="scan'208";a="438474121" From: Roger Pau Monne To: Date: Fri, 30 Jun 2017 16:01:13 +0100 Message-ID: <20170630150117.88489-6-roger.pau@citrix.com> X-Mailer: git-send-email 2.11.0 (Apple Git-81) In-Reply-To: <20170630150117.88489-1-roger.pau@citrix.com> References: <20170630150117.88489-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 v4 5/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 --- Changes since v3: - Rename function to size BARs to pci_size_mem_bar. - Change the parameters passed to the function. Pass the position and whether the BAR is the last one, instead of the (base, max_bars, *index) tuple. - Make the function return the number of BARs consumed (1 for 32b, 2 for 64b BARs). - Change the dprintk back to printk. - Do not log another error message in pci_add_device in case pci_size_mem_bar fails. --- xen/drivers/passthrough/pci.c | 89 ++++++++++++++++++++++++++----------------- xen/include/xen/pci.h | 3 ++ 2 files changed, 58 insertions(+), 34 deletions(-) diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 2d38a5a297..656a2a316b 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -588,6 +588,54 @@ static void pci_enable_acs(struct pci_dev *pdev) pci_conf_write16(seg, bus, dev, func, pos + PCI_ACS_CTRL, ctrl); } +int pci_size_mem_bar(unsigned int seg, unsigned int bus, unsigned int slot, + unsigned int func, unsigned int pos, bool last, + uint64_t *paddr, uint64_t *psize) +{ + uint32_t hi = 0, bar = pci_conf_read32(seg, bus, slot, func, pos); + uint64_t addr, size; + + ASSERT((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY); + pci_conf_write32(seg, bus, slot, func, pos, ~0); + if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64 ) + { + if ( last ) + { + printk(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, pos + 4); + pci_conf_write32(seg, bus, slot, func, pos + 4, ~0); + } + size = pci_conf_read32(seg, bus, slot, func, pos) & + 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, pos + 4) << 32; + pci_conf_write32(seg, bus, slot, func, pos + 4, hi); + } + else if ( size ) + size |= (u64)~0 << 32; + pci_conf_write32(seg, bus, slot, func, pos, bar); + size = -(size); + addr = (bar & PCI_BASE_ADDRESS_MEM_MASK) | ((u64)hi << 32); + + if ( paddr ) + *paddr = addr; + if ( psize ) + *psize = size; + + if ( (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64 ) + return 2; + + return 1; +} + int pci_add_device(u16 seg, u8 bus, u8 devfn, const struct pci_dev_info *info, nodeid_t node) { @@ -648,11 +696,10 @@ int pci_add_device(u16 seg, u8 bus, u8 devfn, unsigned int i; BUILD_BUG_ON(ARRAY_SIZE(pdev->vf_rlen) != PCI_SRIOV_NUM_BARS); - for ( i = 0; i < PCI_SRIOV_NUM_BARS; ++i ) + for ( i = 0; i < PCI_SRIOV_NUM_BARS; ) { unsigned int idx = pos + PCI_SRIOV_BAR + i * 4; u32 bar = pci_conf_read32(seg, bus, slot, func, idx); - u32 hi = 0; if ( (bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO ) @@ -663,38 +710,12 @@ 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_mem_bar(seg, bus, slot, func, idx, + i == PCI_SRIOV_NUM_BARS - 1, NULL, + &pdev->vf_rlen[i]); + if ( ret < 0 ) + break; + i += ret; } } else diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index e550effcc9..11ad185cec 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_mem_bar(unsigned int seg, unsigned int bus, unsigned int slot, + unsigned int func, unsigned int pos, bool last, + uint64_t *addr, uint64_t *size); bool_t pcie_aer_get_firmware_first(const struct pci_dev *);