All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleksandr Andrushchenko <andr2000@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: julien@xen.org, sstabellini@kernel.org,
	oleksandr_tyshchenko@epam.com, volodymyr_babchuk@epam.com,
	Artem_Mygaiev@epam.com, roger.pau@citrix.com, jbeulich@suse.com,
	bertrand.marquis@arm.com, rahul.singh@arm.com,
	Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Subject: [PATCH v2 10/11] vpci: Add initial support for virtual PCI bus topology
Date: Thu, 23 Sep 2021 15:55:00 +0300	[thread overview]
Message-ID: <20210923125501.234252-11-andr2000@gmail.com> (raw)
In-Reply-To: <20210923125501.234252-1-andr2000@gmail.com>

From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

Assign SBDF to the PCI devices being passed through with bus 0.
The resulting topology is where PCIe devices reside on the bus 0 of the
root complex itself (embedded endpoints).
This implementation is limited to 32 devices which are allowed on
a single PCI bus.

Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

---
New in v2
---
 xen/common/domain.c           |  1 +
 xen/drivers/passthrough/pci.c | 57 +++++++++++++++++++++++++++++++++++
 xen/drivers/vpci/vpci.c       | 18 +++++++++--
 xen/include/xen/pci.h         | 18 +++++++++++
 xen/include/xen/sched.h       |  6 ++++
 5 files changed, 97 insertions(+), 3 deletions(-)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index 40d67ec34232..b80ff2e5e2e6 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -601,6 +601,7 @@ struct domain *domain_create(domid_t domid,
 
 #ifdef CONFIG_HAS_PCI
     INIT_LIST_HEAD(&d->pdev_list);
+    INIT_LIST_HEAD(&d->vdev_list);
 #endif
 
     /* All error paths can depend on the above setup. */
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index e1da283d73ad..4552ace855e0 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -833,6 +833,63 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn)
     return ret;
 }
 
+static struct vpci_dev *pci_find_virtual_device(const struct domain *d,
+                                                const struct pci_dev *pdev)
+{
+    struct vpci_dev *vdev;
+
+    list_for_each_entry ( vdev, &d->vdev_list, list )
+        if ( vdev->pdev == pdev )
+            return vdev;
+    return NULL;
+}
+
+int pci_add_virtual_device(struct domain *d, const struct pci_dev *pdev)
+{
+    struct vpci_dev *vdev;
+
+    ASSERT(!pci_find_virtual_device(d, pdev));
+
+    /* Each PCI bus supports 32 devices/slots at max. */
+    if ( d->vpci_dev_next > 31 )
+        return -ENOSPC;
+
+    vdev = xzalloc(struct vpci_dev);
+    if ( !vdev )
+        return -ENOMEM;
+
+    /* We emulate a single host bridge for the guest, so segment is always 0. */
+    *(u16*) &vdev->seg = 0;
+    /*
+     * The bus number is set to 0, so virtual devices are seen
+     * as embedded endpoints behind the root complex.
+     */
+    *((u8*) &vdev->bus) = 0;
+    *((u8*) &vdev->devfn) = PCI_DEVFN(d->vpci_dev_next++, 0);
+
+    vdev->pdev = pdev;
+    vdev->domain = d;
+
+    pcidevs_lock();
+    list_add_tail(&vdev->list, &d->vdev_list);
+    pcidevs_unlock();
+
+    return 0;
+}
+
+int pci_remove_virtual_device(struct domain *d, const struct pci_dev *pdev)
+{
+    struct vpci_dev *vdev;
+
+    pcidevs_lock();
+    vdev = pci_find_virtual_device(d, pdev);
+    if ( vdev )
+        list_del(&vdev->list);
+    pcidevs_unlock();
+    xfree(vdev);
+    return 0;
+}
+
 /* Caller should hold the pcidevs_lock */
 static int deassign_device(struct domain *d, uint16_t seg, uint8_t bus,
                            uint8_t devfn)
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index 0cdc0c3f75c4..a40a138a14f7 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -90,24 +90,36 @@ int __hwdom_init vpci_add_handlers(struct pci_dev *pdev)
 /* Notify vPCI that device is assigned to guest. */
 int vpci_assign_device(struct domain *d, const struct pci_dev *dev)
 {
+#ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
+    int rc;
+#endif
+
     /* It only makes sense to assign for hwdom or guest domain. */
     if ( is_system_domain(d) || !has_vpci(d) )
         return 0;
 
 #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
-    return vpci_bar_add_handlers(d, dev);
-#else
-    return 0;
+    rc = vpci_bar_add_handlers(d, dev);
+    if ( rc )
+        return rc;
 #endif
+
+    return pci_add_virtual_device(d, dev);
 }
 
 /* Notify vPCI that device is de-assigned from guest. */
 int vpci_deassign_device(struct domain *d, const struct pci_dev *dev)
 {
+    int rc;
+
     /* It only makes sense to de-assign from hwdom or guest domain. */
     if ( is_system_domain(d) || !has_vpci(d) )
         return 0;
 
+    rc = pci_remove_virtual_device(d, dev);
+    if ( rc )
+        return rc;
+
 #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
     return vpci_bar_remove_handlers(d, dev);
 #else
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 2b2dfb6f1b49..35ae1d093921 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -136,6 +136,22 @@ struct pci_dev {
     struct vpci *vpci;
 };
 
+struct vpci_dev {
+    struct list_head list;
+    /* Physical PCI device this virtual device is connected to. */
+    const struct pci_dev *pdev;
+    /* Virtual SBDF of the device. */
+    const union {
+        struct {
+            uint8_t devfn;
+            uint8_t bus;
+            uint16_t seg;
+        };
+        pci_sbdf_t sbdf;
+    };
+    struct domain *domain;
+};
+
 #define for_each_pdev(domain, pdev) \
     list_for_each_entry(pdev, &(domain)->pdev_list, domain_list)
 
@@ -165,7 +181,9 @@ int pci_add_segment(u16 seg);
 const unsigned long *pci_get_ro_map(u16 seg);
 int pci_add_device(u16 seg, u8 bus, u8 devfn,
                    const struct pci_dev_info *, nodeid_t node);
+int pci_add_virtual_device(struct domain *d, const struct pci_dev *pdev);
 int pci_remove_device(u16 seg, u8 bus, u8 devfn);
+int pci_remove_virtual_device(struct domain *d, const struct pci_dev *pdev);
 int pci_ro_device(int seg, int bus, int devfn);
 int pci_hide_device(unsigned int seg, unsigned int bus, unsigned int devfn);
 struct pci_dev *pci_get_pdev(int seg, int bus, int devfn);
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 28146ee404e6..d304c7ebe766 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -444,6 +444,12 @@ struct domain
 
 #ifdef CONFIG_HAS_PCI
     struct list_head pdev_list;
+    struct list_head vdev_list;
+    /*
+     * Current device number used by the virtual PCI bus topology
+     * to assign a unique SBDF to a passed through virtual PCI device.
+     */
+    int vpci_dev_next;
 #endif
 
 #ifdef CONFIG_HAS_PASSTHROUGH
-- 
2.25.1



  parent reply	other threads:[~2021-09-23 13:08 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-23 12:54 [PATCH v2 00/11] PCI devices passthrough on Arm, part 3 Oleksandr Andrushchenko
2021-09-23 12:54 ` [PATCH v2 01/11] vpci: Make vpci registers removal a dedicated function Oleksandr Andrushchenko
2021-09-28 11:15   ` Michal Orzel
2021-09-23 12:54 ` [PATCH v2 02/11] vpci: Add hooks for PCI device assign/de-assign Oleksandr Andrushchenko
2021-09-29  9:35   ` Michal Orzel
2021-09-23 12:54 ` [PATCH v2 03/11] vpci/header: Move register assignments from init_bars Oleksandr Andrushchenko
2021-09-23 12:54 ` [PATCH v2 04/11] vpci/header: Add and remove register handlers dynamically Oleksandr Andrushchenko
2021-09-23 12:54 ` [PATCH v2 05/11] vpci/header: Implement guest BAR register handlers Oleksandr Andrushchenko
2021-09-29  9:27   ` Michal Orzel
2021-09-23 12:54 ` [PATCH v2 06/11] vpci/header: Handle p2m range sets per BAR Oleksandr Andrushchenko
2021-09-23 12:54 ` [PATCH v2 07/11] vpci/header: program p2m with guest BAR view Oleksandr Andrushchenko
2021-09-29  8:13   ` Michal Orzel
2021-09-29  8:16     ` Jan Beulich
2021-09-29  8:24       ` Oleksandr Andrushchenko
2021-09-29  8:36         ` Jan Beulich
2021-09-29  8:58           ` Oleksandr Andrushchenko
2021-09-29  8:16     ` Oleksandr Andrushchenko
2021-09-23 12:54 ` [PATCH v2 08/11] vpci/header: Emulate PCI_COMMAND register for guests Oleksandr Andrushchenko
2021-09-28  7:34   ` Michal Orzel
2021-09-23 12:54 ` [PATCH v2 09/11] vpci/header: Reset the command register when adding devices Oleksandr Andrushchenko
2021-09-28  7:38   ` Michal Orzel
2021-09-23 12:55 ` Oleksandr Andrushchenko [this message]
2021-09-28  7:48   ` [PATCH v2 10/11] vpci: Add initial support for virtual PCI bus topology Michal Orzel
2021-09-28  7:59     ` Jan Beulich
2021-09-28  8:17       ` Michal Orzel
2021-09-28 12:58         ` Oleksandr Andrushchenko
2021-09-29  9:03           ` Oleksandr Andrushchenko
2021-09-29  9:09             ` Jan Beulich
2021-09-29 11:56               ` Oleksandr Andrushchenko
2021-09-29 12:54                 ` Jan Beulich
2021-09-29 13:16                   ` Oleksandr Andrushchenko
2021-09-29 13:23                     ` Jan Beulich
2021-09-29 13:49                       ` Oleksandr Andrushchenko
2021-09-29 14:07                         ` Jan Beulich
2021-09-29 14:16                           ` Oleksandr Andrushchenko
2021-09-23 12:55 ` [PATCH v2 11/11] xen/arm: Translate virtual PCI bus topology for guests Oleksandr Andrushchenko
2021-09-27 11:31   ` Jan Beulich
2021-09-27 12:08     ` Oleksandr Andrushchenko
2021-09-27 13:34       ` Jan Beulich
2021-09-27 13:43         ` Oleksandr Andrushchenko
2021-09-27 13:51           ` Jan Beulich
2021-09-27 14:04             ` Oleksandr Andrushchenko
2021-09-27 14:16               ` Jan Beulich
2021-09-27 14:20                 ` Oleksandr Andrushchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210923125501.234252-11-andr2000@gmail.com \
    --to=andr2000@gmail.com \
    --cc=Artem_Mygaiev@epam.com \
    --cc=bertrand.marquis@arm.com \
    --cc=jbeulich@suse.com \
    --cc=julien@xen.org \
    --cc=oleksandr_andrushchenko@epam.com \
    --cc=oleksandr_tyshchenko@epam.com \
    --cc=rahul.singh@arm.com \
    --cc=roger.pau@citrix.com \
    --cc=sstabellini@kernel.org \
    --cc=volodymyr_babchuk@epam.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.