From patchwork Tue Apr 11 10:03:57 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: 9674847 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 6B33960381 for ; Tue, 11 Apr 2017 10:08:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 64F96284EF for ; Tue, 11 Apr 2017 10:08:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 59B9028537; Tue, 11 Apr 2017 10:08:12 +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 D45A3284EF for ; Tue, 11 Apr 2017 10:08:11 +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 1cxsgN-0006HC-Ka; Tue, 11 Apr 2017 10:05:55 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cxsgM-0006Gj-El for xen-devel@lists.xenproject.org; Tue, 11 Apr 2017 10:05:54 +0000 Received: from [85.158.139.211] by server-3.bemta-5.messagelabs.com id F1/07-01936-18AACE85; Tue, 11 Apr 2017 10:05:53 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprLIsWRWlGSWpSXmKPExsXitHRDpG7jqjc RBntOcFh83zKZyYHR4/CHKywBjFGsmXlJ+RUJrBkftrewF8zUr9j6/BVrA+N6uS5GTg4JAX+J vacPMoHYbAI6Ehfn7mTrYuTgEBFQkbi916CLkYuDWWAuo8SG5g+MIDXCAkESG75vZQWxWQRUJ T4tvcQCYvMKWEocOHyIDWKmnsTbiS/A6jkFrCTmnXoHFhcCqtl2YjsTRL2gxMmZT8B6mQU0JV q3/2aHsOUlmrfOZoaoV5Ton/eAbQIj3ywkLbOQtMxC0rKAkXkVo0ZxalFZapGukYFeUlFmekZ JbmJmjq6hgalebmpxcWJ6ak5iUrFecn7uJkZgsNUzMDDuYGyc7XeIUZKDSUmUN2Dm6wghvqT8 lMqMxOKM+KLSnNTiQ4wyHBxKErycK99ECAkWpaanVqRl5gDDHiYtwcGjJMI7ZwVQmre4IDG3O DMdInWKUVFKnJcJpE8AJJFRmgfXBou1S4yyUsK8jAwMDEI8BalFuZklqPKvGMU5GJWEeVtBxv Nk5pXATX8FtJgJaPGZXS9BFpckIqSkGhglCperbXxkIMVRHVJRzrxTsLvpcsG3lCderU5lnBs 3lFkmLdaIzLDgyUxd0VdhXHTp5MpVB5RamRd0pD/uFLOJevwzX3qL0leuwvlipuWXtq9N/Ddp 7l7pvfavi9Ye/ZPRNdWuasvUt8U7zl/N/PdAvnqT+wqG189cPzO9O780wnxmn4WFi5kSS3FGo qEWc1FxIgAgguECsAIAAA== X-Env-Sender: prvs=267e7865b=roger.pau@citrix.com X-Msg-Ref: server-13.tower-206.messagelabs.com!1491905150!77417040!1 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 19049 invoked from network); 11 Apr 2017 10:05:52 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-13.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 11 Apr 2017 10:05:52 -0000 X-IronPort-AV: E=Sophos;i="5.37,185,1488844800"; d="scan'208";a="418561174" From: Roger Pau Monne To: Date: Tue, 11 Apr 2017 11:03:57 +0100 Message-ID: <20170411100402.56246-2-roger.pau@citrix.com> X-Mailer: git-send-email 2.11.0 (Apple Git-81) In-Reply-To: <20170411100402.56246-1-roger.pau@citrix.com> References: <20170411100402.56246-1-roger.pau@citrix.com> MIME-Version: 1.0 Cc: julien.grall@arm.com, Roger Pau Monne , boris.ostrovsky@oracle.com, Jan Beulich Subject: [Xen-devel] [PATCH for-next 1/6] 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 c8e2d2d9a9..4e33442976 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -587,6 +587,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) { @@ -651,7 +696,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 ) @@ -662,38 +707,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 59b6e8a81c..74d828db38 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -161,6 +161,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 *);