From patchwork Sat Feb 10 00:10:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rustad, Mark D" X-Patchwork-Id: 871600 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=osuosl.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=intel-wired-lan-bounces@osuosl.org; receiver=) Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zdXPr5SYxz9s72 for ; Sat, 10 Feb 2018 11:10:24 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id DFF1E89F6E; Sat, 10 Feb 2018 00:10:22 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OgJmItCDzPSs; Sat, 10 Feb 2018 00:10:22 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by hemlock.osuosl.org (Postfix) with ESMTP id 2E3CB89F68; Sat, 10 Feb 2018 00:10:22 +0000 (UTC) X-Original-To: intel-wired-lan@lists.osuosl.org Delivered-To: intel-wired-lan@lists.osuosl.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by ash.osuosl.org (Postfix) with ESMTP id ECDA31BFD9C for ; Sat, 10 Feb 2018 00:10:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id DF8E0304A7 for ; Sat, 10 Feb 2018 00:10:04 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WftK7cahBCFa for ; Sat, 10 Feb 2018 00:10:03 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by silver.osuosl.org (Postfix) with ESMTPS id CBDA126984 for ; Sat, 10 Feb 2018 00:10:03 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Feb 2018 16:10:03 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,486,1511856000"; d="scan'208";a="173297845" Received: from mdrustad-mac04.sj.intel.com (HELO mdrustad-mac04.local) ([10.233.80.205]) by orsmga004.jf.intel.com with ESMTP; 09 Feb 2018 16:10:02 -0800 To: intel-wired-lan@lists.osuosl.org From: Mark D Rustad Date: Fri, 09 Feb 2018 16:10:02 -0800 Message-ID: <20180210001001.24685.8117.stgit@mdrustad-mac04.local> User-Agent: StGit/0.15 MIME-Version: 1.0 Subject: [Intel-wired-lan] [PATCH] virtio_pci: Add SR-IOV support X-BeenThere: intel-wired-lan@osuosl.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Intel Wired Ethernet Linux Kernel Driver Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-wired-lan-bounces@osuosl.org Sender: "Intel-wired-lan" From: Mark Rustad Hardware-realized virtio devices can implement SR-IOV, so enable its use. Signed-off-by: Mark Rustad --- drivers/virtio/virtio_pci_common.c | 64 ++++++++++++++++++++++++++++++++++++ drivers/virtio/virtio_pci_common.h | 3 ++ 2 files changed, 67 insertions(+) diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 1c4797e53f68..c46bbad57e67 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -584,6 +584,67 @@ static void virtio_pci_remove(struct pci_dev *pci_dev) put_device(dev); } +#ifdef CONFIG_PCI_IOV +static int _virtio_pci_sriov_disable(struct virtio_pci_device *vp_dev, + struct pci_dev *pci_dev) +{ + vp_dev->num_vfs = 0; + /* If vfs are assigned we cannot shut down SR-IOV without causing + * issues, so just leave the hardware available. + */ + if (pci_vfs_assigned(pci_dev)) { + dev_warn(&pci_dev->dev, + "Unloading driver while VFs are assigned - VFs will not be deallocated\n"); + return -EPERM; + } + pci_disable_sriov(pci_dev); + return 0; +} + +static int virtio_pci_sriov_disable(struct pci_dev *pci_dev) +{ + struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); + + if (!vp_dev->num_vfs && !pci_num_vf(pci_dev)) + return -EINVAL; + + return _virtio_pci_sriov_disable(vp_dev, pci_dev); +} + +static int virtio_pci_sriov_enable(struct pci_dev *pci_dev, int num_vfs) +{ + struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); + int pre_existing_vfs = pci_num_vf(pci_dev); + int rc = 0; + + if (vp_dev->num_vfs == num_vfs) + return -EINVAL; + + if (pre_existing_vfs && pre_existing_vfs != num_vfs) + rc = _virtio_pci_sriov_disable(vp_dev, pci_dev); + else if (pre_existing_vfs && pre_existing_vfs == num_vfs) + return num_vfs; + if (rc) + return rc; + + rc = pci_enable_sriov(pci_dev, num_vfs); + if (rc) { + dev_warn(&pci_dev->dev, "Failed to enable PCI sriov: %d\n", rc); + return rc; + } + vp_dev->num_vfs = num_vfs; + dev_info(&pci_dev->dev, "SR-IOV enabled with %d VFs\n", num_vfs); + return num_vfs; +} + +static int virtio_pci_sriov_configure(struct pci_dev *dev, int num_vfs) +{ + if (!num_vfs) + return virtio_pci_sriov_disable(dev); + return virtio_pci_sriov_enable(dev, num_vfs); +} +#endif /* CONFIG_PCI_IOV */ + static struct pci_driver virtio_pci_driver = { .name = "virtio-pci", .id_table = virtio_pci_id_table, @@ -592,6 +653,9 @@ static void virtio_pci_remove(struct pci_dev *pci_dev) #ifdef CONFIG_PM_SLEEP .driver.pm = &virtio_pci_pm_ops, #endif +#ifdef CONFIG_PCI_IOV + .sriov_configure = virtio_pci_sriov_configure, +#endif }; module_pci_driver(virtio_pci_driver); diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h index 135ee3cf7175..7d3910c15e99 100644 --- a/drivers/virtio/virtio_pci_common.h +++ b/drivers/virtio/virtio_pci_common.h @@ -94,6 +94,9 @@ struct virtio_pci_device { /* Vectors allocated, excluding per-vq vectors if any */ unsigned msix_used_vectors; + /* Number of VFs allocated */ + int num_vfs; + /* Whether we have vector per vq */ bool per_vq_vectors;