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 v3 10/11] vpci: Add initial support for virtual PCI bus topology
Date: Thu, 30 Sep 2021 10:52:22 +0300	[thread overview]
Message-ID: <20210930075223.860329-11-andr2000@gmail.com> (raw)
In-Reply-To: <20210930075223.860329-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>

---
Since v2:
 - remove casts that are (a) malformed and (b) unnecessary
 - add new line for better readability
 - remove CONFIG_HAS_VPCI_GUEST_SUPPORT ifdef's as the relevant vPCI
    functions are now completely gated with this config
 - gate common code with CONFIG_HAS_VPCI_GUEST_SUPPORT
New in v2
---
 xen/common/domain.c           |  3 ++
 xen/drivers/passthrough/pci.c | 60 +++++++++++++++++++++++++++++++++++
 xen/drivers/vpci/vpci.c       | 14 +++++++-
 xen/include/xen/pci.h         | 22 +++++++++++++
 xen/include/xen/sched.h       |  8 +++++
 5 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index 40d67ec34232..e0170087612d 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -601,6 +601,9 @@ struct domain *domain_create(domid_t domid,
 
 #ifdef CONFIG_HAS_PCI
     INIT_LIST_HEAD(&d->pdev_list);
+#ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
+    INIT_LIST_HEAD(&d->vdev_list);
+#endif
 #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 805ab86ed555..5b963d75d1ba 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -831,6 +831,66 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn)
     return ret;
 }
 
+#ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
+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. */
+    vdev->seg = 0;
+
+    /*
+     * The bus number is set to 0, so virtual devices are seen
+     * as embedded endpoints behind the root complex.
+     */
+    vdev->bus = 0;
+    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;
+}
+#endif /* CONFIG_HAS_VPCI_GUEST_SUPPORT */
+
 /* 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 702f7b5d5dda..d787f13e679e 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -91,20 +91,32 @@ 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)
 {
+    int rc;
+
     /* It only makes sense to assign for hwdom or guest domain. */
     if ( is_system_domain(d) || !has_vpci(d) )
         return 0;
 
-    return vpci_bar_add_handlers(d, dev);
+    rc = vpci_bar_add_handlers(d, dev);
+    if ( rc )
+        return rc;
+
+    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;
+
     return vpci_bar_remove_handlers(d, dev);
 }
 #endif /* CONFIG_HAS_VPCI_GUEST_SUPPORT */
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 43b8a0817076..33033a3a8f8d 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -137,6 +137,24 @@ struct pci_dev {
     struct vpci *vpci;
 };
 
+#ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
+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. */
+    union {
+        struct {
+            uint8_t devfn;
+            uint8_t bus;
+            uint16_t seg;
+        };
+        pci_sbdf_t sbdf;
+    };
+    struct domain *domain;
+};
+#endif
+
 #define for_each_pdev(domain, pdev) \
     list_for_each_entry(pdev, &(domain)->pdev_list, domain_list)
 
@@ -167,6 +185,10 @@ 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_remove_device(u16 seg, u8 bus, u8 devfn);
+#ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
+int pci_add_virtual_device(struct domain *d, const struct pci_dev *pdev);
+int pci_remove_virtual_device(struct domain *d, const struct pci_dev *pdev);
+#endif
 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..ecdb04b4f7fc 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -444,6 +444,14 @@ struct domain
 
 #ifdef CONFIG_HAS_PCI
     struct list_head pdev_list;
+#ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
+    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
 #endif
 
 #ifdef CONFIG_HAS_PASSTHROUGH
-- 
2.25.1



  parent reply	other threads:[~2021-09-30  7:57 UTC|newest]

Thread overview: 98+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-30  7:52 [PATCH v3 00/11] PCI devices passthrough on Arm, part 3 Oleksandr Andrushchenko
2021-09-30  7:52 ` [PATCH v3 01/11] vpci: Make vpci registers removal a dedicated function Oleksandr Andrushchenko
2021-10-13 11:11   ` Roger Pau Monné
2021-10-27  9:12     ` Oleksandr Andrushchenko
2021-10-27  9:24       ` Roger Pau Monné
2021-10-27  9:41         ` Oleksandr Andrushchenko
2021-09-30  7:52 ` [PATCH v3 02/11] vpci: Add hooks for PCI device assign/de-assign Oleksandr Andrushchenko
2021-09-30  8:21   ` Jan Beulich
2021-09-30  8:45     ` Oleksandr Andrushchenko
2021-09-30  9:06       ` Jan Beulich
2021-09-30  9:21         ` Oleksandr Andrushchenko
2021-09-30 10:14           ` Jan Beulich
2021-09-30 10:30             ` Oleksandr Andrushchenko
2021-10-13 11:29   ` Roger Pau Monné
2021-10-13 12:47     ` Jan Beulich
2021-10-27  9:53     ` Oleksandr Andrushchenko
2021-09-30  7:52 ` [PATCH v3 03/11] vpci/header: Move register assignments from init_bars Oleksandr Andrushchenko
2021-10-13 13:51   ` Roger Pau Monné
2021-10-15  6:04     ` Jan Beulich
2021-10-25 14:28       ` Roger Pau Monné
2021-10-27 10:17     ` Oleksandr Andrushchenko
2021-10-27 11:59       ` Oleksandr Andrushchenko
2021-10-27 13:23         ` Roger Pau Monné
2021-10-27 14:06           ` Oleksandr Andrushchenko
2021-10-27 15:34             ` Roger Pau Monné
2021-09-30  7:52 ` [PATCH v3 04/11] vpci/header: Add and remove register handlers dynamically Oleksandr Andrushchenko
2021-10-01 13:26   ` Jan Beulich
2021-10-04  5:58     ` Oleksandr Andrushchenko
2021-10-07  7:22       ` Jan Beulich
2021-10-13 15:38         ` Roger Pau Monné
2021-10-15  6:09           ` Jan Beulich
2021-10-25 15:48   ` Roger Pau Monné
2021-11-01  9:18     ` Oleksandr Andrushchenko
2021-11-02 10:03       ` Roger Pau Monné
2021-11-02 10:29         ` Oleksandr Andrushchenko
2021-09-30  7:52 ` [PATCH v3 05/11] vpci/header: Implement guest BAR register handlers Oleksandr Andrushchenko
2021-10-01 13:31   ` Jan Beulich
2021-10-26  7:50   ` Roger Pau Monné
2021-10-26  8:09     ` Oleksandr Andrushchenko
2021-09-30  7:52 ` [PATCH v3 06/11] vpci/header: Handle p2m range sets per BAR Oleksandr Andrushchenko
2021-10-25 11:51   ` Oleksandr Andrushchenko
2021-10-26  9:40     ` Roger Pau Monné
2021-11-02 11:13       ` Jan Beulich
2021-10-26  9:08   ` Roger Pau Monné
2021-11-02 10:34     ` Oleksandr Andrushchenko
2021-09-30  7:52 ` [PATCH v3 07/11] vpci/header: program p2m with guest BAR view Oleksandr Andrushchenko
2021-10-01 13:38   ` Jan Beulich
2021-10-04  6:26     ` Oleksandr Andrushchenko
2021-10-26 10:35   ` Roger Pau Monné
2021-11-02 10:43     ` Oleksandr Andrushchenko
2021-09-30  7:52 ` [PATCH v3 08/11] vpci/header: Emulate PCI_COMMAND register for guests Oleksandr Andrushchenko
2021-10-26 10:52   ` Roger Pau Monné
2021-11-02 10:48     ` Oleksandr Andrushchenko
2021-11-02 11:19     ` Jan Beulich
2021-11-02 11:50       ` Roger Pau Monné
2021-11-02 13:54         ` Jan Beulich
2021-11-02 14:10           ` Oleksandr Andrushchenko
2021-11-03  8:53             ` Oleksandr Andrushchenko
2021-11-03  9:11               ` Jan Beulich
2021-11-03  9:18                 ` Oleksandr Andrushchenko
2021-11-03  9:24                   ` Jan Beulich
2021-11-03  9:30                     ` Oleksandr Andrushchenko
2021-11-03  9:49                       ` Jan Beulich
2021-11-03 10:24                         ` Oleksandr Andrushchenko
2021-11-03 10:34                           ` Jan Beulich
2021-11-03 10:36                             ` Oleksandr Andrushchenko
2021-11-03 11:01                               ` Roger Pau Monné
2021-11-03 11:02                                 ` Oleksandr Andrushchenko
2021-11-03 11:26                                   ` Roger Pau Monné
2021-11-03 11:34                                     ` Oleksandr Andrushchenko
2021-11-03  9:39                   ` Roger Pau Monné
2021-11-03  9:50                     ` Oleksandr Andrushchenko
2021-11-02 14:17         ` Julien Grall
2021-09-30  7:52 ` [PATCH v3 09/11] vpci/header: Reset the command register when adding devices Oleksandr Andrushchenko
2021-10-26 11:00   ` Roger Pau Monné
2021-11-02 11:11     ` Oleksandr Andrushchenko
2021-09-30  7:52 ` Oleksandr Andrushchenko [this message]
2021-09-30  8:51   ` [PATCH v3 10/11] vpci: Add initial support for virtual PCI bus topology Jan Beulich
2021-09-30  9:34     ` Oleksandr Andrushchenko
2021-09-30 10:23       ` Jan Beulich
2021-09-30 10:26         ` Oleksandr Andrushchenko
2021-10-26 11:33   ` Roger Pau Monné
2021-11-03  6:34     ` Oleksandr Andrushchenko
2021-11-03  8:41       ` Jan Beulich
2021-11-03  8:57         ` Oleksandr Andrushchenko
2021-11-03  8:52       ` Roger Pau Monné
2021-11-03  8:59         ` Oleksandr Andrushchenko
2021-09-30  7:52 ` [PATCH v3 11/11] xen/arm: Translate virtual PCI bus topology for guests Oleksandr Andrushchenko
2021-09-30  8:53   ` Jan Beulich
2021-09-30  9:35     ` Oleksandr Andrushchenko
2021-09-30 10:25       ` Jan Beulich
2021-09-30 16:57     ` Oleksandr Andrushchenko
2021-10-01  7:42       ` Jan Beulich
2021-10-01  7:57         ` Oleksandr Andrushchenko
2021-10-01  8:12           ` Jan Beulich
2021-10-18 18:32   ` Julien Grall
2021-10-26 13:30   ` Roger Pau Monné
2021-10-26 13:57     ` 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=20210930075223.860329-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.