|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1 1/3] xen/dom0less: introduce free_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 free_phandle, as the pfdt may already contain a dummy
interrupt controller node with a phandle assigned to it. free_phandle
must therefore be initialized to one past the highest phandle already
present in the pfdt, to avoid collisions.
Since free_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 get_next_free_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>
---
xen/common/device-tree/dom0less-build.c | 44 ++++++++++++++++++-------
xen/include/xen/fdt-domain-build.h | 6 ++++
xen/include/xen/fdt-kernel.h | 3 ++
3 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/xen/common/device-tree/dom0less-build.c
b/xen/common/device-tree/dom0less-build.c
index 840d14419da2..9205f01f0a49 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 free_phandle starts
+ * above it, avoiding collisions with pfdt's own phandle assignments.
+ */
+ res = fdt_generate_phandle(pfdt, &kinfo->free_phandle);
+ if ( res )
+ {
+ res = (res == -FDT_ERR_NOPHANDLES) ? -EOVERFLOW : -EINVAL;
+ goto out;
+ }
+
+ if ( kinfo->free_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,8 @@ 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->free_phandle = 1;
+ BUILD_BUG_ON(GUEST_PHANDLE_GIC == 1);
#ifdef CONFIG_GRANT_TABLE
kinfo->gnttab_start = GUEST_GNTTAB_BASE;
@@ -499,6 +519,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 free_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 +548,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 1d9e77df0eb3..220ae46ddbe1 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 get_next_free_phandle(struct kernel_info *kinfo)
+{
+ return kinfo->free_phandle >= GUEST_PHANDLE_GIC ? 0 :
kinfo->free_phandle++;
+}
+
#endif /* __XEN_FDT_DOMAIN_BUILD_H__ */
/*
diff --git a/xen/include/xen/fdt-kernel.h b/xen/include/xen/fdt-kernel.h
index aa977a50f4fc..3527934b2a00 100644
--- a/xen/include/xen/fdt-kernel.h
+++ b/xen/include/xen/fdt-kernel.h
@@ -44,6 +44,9 @@ struct kernel_info {
/* Interrupt controller phandle */
uint32_t phandle_intc;
+ /* Next free phandle available for assigning to guest device nodes */
+ uint32_t free_phandle;
+
/* loader to use for this kernel */
void (*load)(struct kernel_info *info);
--
2.53.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |