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, bertrand.marquis@arm.com,
rahul.singh@arm.com,
Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>,
Julien Grall <jgrall@amazon.com>
Subject: [PATCH v8 1/4] xen/arm: add pci-domain for disabled devices
Date: Thu, 9 Dec 2021 09:29:15 +0200 [thread overview]
Message-ID: <20211209072918.460902-2-andr2000@gmail.com> (raw)
In-Reply-To: <20211209072918.460902-1-andr2000@gmail.com>
From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
If a PCI host bridge device is present in the device tree, but is
disabled, then its PCI host bridge driver was not instantiated.
This results in the failure of the pci_get_host_bridge_segment()
and the following panic during Xen start:
(XEN) Device tree generation failed (-22).
(XEN)
(XEN) ****************************************
(XEN) Panic on CPU 0:
(XEN) Could not set up DOM0 guest OS
(XEN) ****************************************
Fix this by adding "linux,pci-domain" property for all device tree nodes
which have "pci" device type, so we know which segments will be used by
the guest for which bridges.
Fixes: 4cfab4425d39 ("xen/arm: Add linux,pci-domain property for hwdom if not available.")
Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Reviewed-by: Rahul Singh <rahul.singh@arm.com>
Tested-by: Rahul Singh <rahul.singh@arm.com>
Acked-by: Julien Grall <jgrall@amazon.com>
---
Since v6:
- use use_dt_domains in pci_get_new_domain_nr and return -1 if set
- do not set "linux,pci-domain" if parent device is "pci"
- move the code to a new helper handle_linux_pci_domain (Julien)
New in v6
---
xen/arch/arm/domain_build.c | 66 +++++++++++++++++++++++-------
xen/arch/arm/pci/pci-host-common.c | 8 +++-
xen/include/asm-arm/pci.h | 8 ++++
3 files changed, 66 insertions(+), 16 deletions(-)
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index d02bacbcd1ed..6c5d22d9be1a 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -654,6 +654,55 @@ static void __init allocate_static_memory(struct domain *d,
}
#endif
+/*
+ * When PCI passthrough is available we want to keep the
+ * "linux,pci-domain" in sync for every host bridge.
+ *
+ * Xen may not have a driver for all the host bridges. So we have
+ * to write an heuristic to detect whether a device node describes
+ * a host bridge.
+ *
+ * The current heuristic assumes that a device is a host bridge
+ * if the type is "pci" and then parent type is not "pci".
+ */
+static int handle_linux_pci_domain(struct kernel_info *kinfo,
+ const struct dt_device_node *node)
+{
+ uint16_t segment;
+ int res;
+
+ if ( !is_pci_passthrough_enabled() )
+ return 0;
+
+ if ( !dt_device_type_is_equal(node, "pci") )
+ return 0;
+
+ if ( node->parent && dt_device_type_is_equal(node->parent, "pci") )
+ return 0;
+
+ if ( dt_find_property(node, "linux,pci-domain", NULL) )
+ return 0;
+
+ /* Allocate and create the linux,pci-domain */
+ res = pci_get_host_bridge_segment(node, &segment);
+ if ( res < 0 )
+ {
+ res = pci_get_new_domain_nr();
+ if ( res < 0 )
+ {
+ printk(XENLOG_DEBUG "Can't assign PCI segment to %s\n",
+ node->full_name);
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ segment = res;
+ printk(XENLOG_DEBUG "Assigned segment %d to %s\n",
+ segment, node->full_name);
+ }
+
+ return fdt_property_cell(kinfo->fdt, "linux,pci-domain", segment);
+}
+
static int __init write_properties(struct domain *d, struct kernel_info *kinfo,
const struct dt_device_node *node)
{
@@ -755,21 +804,10 @@ static int __init write_properties(struct domain *d, struct kernel_info *kinfo,
return res;
}
- if ( is_pci_passthrough_enabled() && dt_device_type_is_equal(node, "pci") )
- {
- if ( !dt_find_property(node, "linux,pci-domain", NULL) )
- {
- uint16_t segment;
-
- res = pci_get_host_bridge_segment(node, &segment);
- if ( res < 0 )
- return res;
+ res = handle_linux_pci_domain(kinfo, node);
- res = fdt_property_cell(kinfo->fdt, "linux,pci-domain", segment);
- if ( res )
- return res;
- }
- }
+ if ( res )
+ return res;
/*
* Override the property "status" to disable the device when it's
diff --git a/xen/arch/arm/pci/pci-host-common.c b/xen/arch/arm/pci/pci-host-common.c
index ae79a0c19b93..40e779b5d803 100644
--- a/xen/arch/arm/pci/pci-host-common.c
+++ b/xen/arch/arm/pci/pci-host-common.c
@@ -30,6 +30,8 @@ static LIST_HEAD(pci_host_bridges);
static atomic_t domain_nr = ATOMIC_INIT(-1);
+static int use_dt_domains = -1;
+
static inline void __iomem *pci_remap_cfgspace(paddr_t start, size_t len)
{
return ioremap_nocache(start, len);
@@ -137,14 +139,16 @@ void pci_add_host_bridge(struct pci_host_bridge *bridge)
list_add_tail(&bridge->node, &pci_host_bridges);
}
-static int pci_get_new_domain_nr(void)
+int pci_get_new_domain_nr(void)
{
+ if ( use_dt_domains )
+ return -1;
+
return atomic_inc_return(&domain_nr);
}
static int pci_bus_find_domain_nr(struct dt_device_node *dev)
{
- static int use_dt_domains = -1;
int domain;
domain = dt_get_pci_domain_nr(dev);
diff --git a/xen/include/asm-arm/pci.h b/xen/include/asm-arm/pci.h
index 9736d6816da3..c313423cdcb2 100644
--- a/xen/include/asm-arm/pci.h
+++ b/xen/include/asm-arm/pci.h
@@ -109,6 +109,8 @@ static always_inline bool is_pci_passthrough_enabled(void)
void arch_pci_init_pdev(struct pci_dev *pdev);
+int pci_get_new_domain_nr(void);
+
#else /*!CONFIG_HAS_PCI*/
struct arch_pci_dev { };
@@ -129,5 +131,11 @@ static inline int pci_get_host_bridge_segment(const struct dt_device_node *node,
return -EINVAL;
}
+static inline int pci_get_new_domain_nr(void)
+{
+ ASSERT_UNREACHABLE();
+ return -1;
+}
+
#endif /*!CONFIG_HAS_PCI*/
#endif /* __ARM_PCI_H__ */
--
2.25.1
next prev parent reply other threads:[~2021-12-09 7:29 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-09 7:29 [PATCH v8 0/4] PCI devices passthrough on Arm, part 2 Oleksandr Andrushchenko
2021-12-09 7:29 ` Oleksandr Andrushchenko [this message]
2021-12-09 7:29 ` [PATCH v8 2/4] xen/arm: setup MMIO range trap handlers for hardware domain Oleksandr Andrushchenko
2021-12-09 10:18 ` Rahul Singh
2021-12-10 17:52 ` Julien Grall
2021-12-10 18:37 ` Oleksandr Andrushchenko
2021-12-15 17:36 ` Julien Grall
2021-12-09 7:29 ` [PATCH v8 3/4] xen/arm: account IO handler for emulated PCI host bridge Oleksandr Andrushchenko
2021-12-09 10:19 ` Rahul Singh
2021-12-09 7:29 ` [PATCH v8 4/4] xen/arm: do not map PCI ECAM and MMIO space to Domain-0's p2m Oleksandr Andrushchenko
2021-12-09 10:19 ` Rahul Singh
2021-12-15 17:48 ` [PATCH v8 0/4] PCI devices passthrough on Arm, part 2 Julien Grall
2021-12-15 18:00 ` 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=20211209072918.460902-2-andr2000@gmail.com \
--to=andr2000@gmail.com \
--cc=artem_mygaiev@epam.com \
--cc=bertrand.marquis@arm.com \
--cc=jgrall@amazon.com \
--cc=julien@xen.org \
--cc=oleksandr_andrushchenko@epam.com \
--cc=oleksandr_tyshchenko@epam.com \
--cc=rahul.singh@arm.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.