|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] xen/dom0less: introduce next_phandle in struct kernel_info
commit a010efd323d252c13c814c528b2421c04626d6a2
Author: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
AuthorDate: Mon Apr 27 17:34:23 2026 +0200
Commit: Michal Orzel <michal.orzel@xxxxxxx>
CommitDate: Wed Apr 29 07:39:07 2026 +0200
xen/dom0less: introduce next_phandle in struct kernel_info
There are cases where it is necessary to know the next available phandle
number in order to generate phandles for guest device nodes.
When a partial FDT (pfdt) is provided, special care is needed during
initialization of next_phandle, as the pfdt may already contain a dummy
interrupt controller node with a phandle assigned to it. next_phandle
must therefore be initialized to one past the highest phandle already
present in the pfdt, to avoid collisions.
Since next_phandle may be needed for the very first guest node generated,
domain_handle_dtb_boot_module() is moved earlier in prepare_dtb_domU().
The new call site also aligns better with the existing comment stating
that domain_handle_dtb_boot_module() must be called before the rest of
the device tree is generated.
Introduce alloc_phandle() to ensure that phandles allocated for guest
nodes do not overlap the Xen-reserved phandle range. This helper will
be used by subsequent patches (by RISC-V at the moment).
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
Reviewed-by: Michal Orzel <michal.orzel@xxxxxxx>
---
xen/common/device-tree/dom0less-build.c | 43 ++++++++++++++++++++++++---------
xen/include/xen/fdt-domain-build.h | 6 +++++
xen/include/xen/fdt-kernel.h | 6 +++++
3 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/xen/common/device-tree/dom0less-build.c
b/xen/common/device-tree/dom0less-build.c
index 840d14419d..9787ee2649 100644
--- a/xen/common/device-tree/dom0less-build.c
+++ b/xen/common/device-tree/dom0less-build.c
@@ -389,6 +389,24 @@ static int __init domain_handle_dtb_boot_module(struct
domain *d,
if ( res < 0 )
goto out;
+ /*
+ * Find the highest phandle in the partial FDT so next_phandle starts
+ * above it, avoiding collisions with pfdt's own phandle assignments.
+ */
+ res = fdt_generate_phandle(pfdt, &kinfo->next_phandle);
+ if ( res )
+ {
+ res = (res == -FDT_ERR_NOPHANDLES) ? -EOVERFLOW : -EINVAL;
+ goto out;
+ }
+
+ if ( kinfo->next_phandle >= GUEST_PHANDLE_GIC )
+ {
+ dprintk(XENLOG_ERR, "Phandle allocation overlaps Xen reserved
range\n");
+ res = -EOVERFLOW;
+ goto out;
+ }
+
for ( node_next = fdt_first_subnode(pfdt, 0);
node_next > 0;
node_next = fdt_next_subnode(pfdt, node_next) )
@@ -459,6 +477,7 @@ static int __init prepare_dtb_domU(struct domain *d, struct
kernel_info *kinfo)
BUILD_BUG_ON(DOMU_DTB_SIZE > SZ_2M);
kinfo->phandle_intc = GUEST_PHANDLE_GIC;
+ kinfo->next_phandle = 1;
#ifdef CONFIG_GRANT_TABLE
kinfo->gnttab_start = GUEST_GNTTAB_BASE;
@@ -499,6 +518,18 @@ static int __init prepare_dtb_domU(struct domain *d,
struct kernel_info *kinfo)
if ( ret )
goto err;
+ /*
+ * domain_handle_dtb_boot_module() must be called before the rest of the
+ * device tree is generated because it sets phandle_intc and next_phandle,
+ * which subsequent node generation depends on.
+ */
+ if ( kinfo->dtb )
+ {
+ ret = domain_handle_dtb_boot_module(d, kinfo);
+ if ( ret )
+ goto err;
+ }
+
ret = make_chosen_node(kinfo);
if ( ret )
goto err;
@@ -516,18 +547,6 @@ static int __init prepare_dtb_domU(struct domain *d,
struct kernel_info *kinfo)
if ( ret )
goto err;
- /*
- * domain_handle_dtb_boot_module has to be called before the rest of
- * the device tree is generated because it depends on the value of
- * the field phandle_intc.
- */
- if ( kinfo->dtb )
- {
- ret = domain_handle_dtb_boot_module(d, kinfo);
- if ( ret )
- goto err;
- }
-
ret = make_intc_domU_node(kinfo);
if ( ret )
goto err;
diff --git a/xen/include/xen/fdt-domain-build.h
b/xen/include/xen/fdt-domain-build.h
index 886a853816..fd2ba01ff0 100644
--- a/xen/include/xen/fdt-domain-build.h
+++ b/xen/include/xen/fdt-domain-build.h
@@ -63,6 +63,12 @@ int find_unallocated_memory(const struct kernel_info *kinfo,
unsigned long e_gfn,
void *data));
+/* Return 0 (invalid phandle) if the Xen-reserved range has been reached */
+static inline uint32_t alloc_phandle(struct kernel_info *kinfo)
+{
+ return kinfo->next_phandle >= GUEST_PHANDLE_GIC ? 0 :
kinfo->next_phandle++;
+}
+
#endif /* __XEN_FDT_DOMAIN_BUILD_H__ */
/*
diff --git a/xen/include/xen/fdt-kernel.h b/xen/include/xen/fdt-kernel.h
index 33a60597bb..4d0467bb39 100644
--- a/xen/include/xen/fdt-kernel.h
+++ b/xen/include/xen/fdt-kernel.h
@@ -44,6 +44,12 @@ struct kernel_info {
/* Interrupt controller phandle */
uint32_t phandle_intc;
+ /*
+ * Next free phandle for guest device nodes; do not access directly, use
+ * alloc_phandle().
+ */
+ uint32_t next_phandle;
+
/* loader to use for this kernel */
void (*load)(struct kernel_info *info);
--
generated by git-patchbot for /home/xen/git/xen.git#staging
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |