|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 1/5] xen/arm: copy dtb fragment to guest dtb
Read the dtb fragment corresponding to a passthrough device from memory
at the location referred to by the "multiboot,dtb" compatible node.
Copy the fragment to the guest dtb.
Add a dtb_bootmodule field to struct kernel_info to find the dtb
fragment for a guest.
Some of the code below is taken from tools/libxl/libxl_arm.c. Note that
it is OK to take LGPL 2.1 code and including it into a GPLv2 code base.
The result is GPLv2 code.
Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx>
----
Changes in v2:
- add a note about the code coming from libxl in the commit message
- copy /aliases
- code style
---
xen/arch/arm/domain_build.c | 88 ++++++++++++++++++++++++++++++++++++++++++++
xen/include/asm-arm/kernel.h | 2 +-
2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index b0ec3f0..2e04902 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -14,6 +14,7 @@
#include <xen/guest_access.h>
#include <xen/iocap.h>
#include <xen/acpi.h>
+#include <xen/vmap.h>
#include <xen/warning.h>
#include <acpi/actables.h>
#include <asm/device.h>
@@ -1669,6 +1670,61 @@ static int __init make_vpl011_uart_node(const struct
domain *d, void *fdt)
}
#endif
+static int __init copy_properties(void *fdt, void *pfdt, int nodeoff)
+{
+ int propoff, nameoff, r;
+ const struct fdt_property *prop;
+
+ for ( propoff = fdt_first_property_offset(pfdt, nodeoff);
+ propoff >= 0;
+ propoff = fdt_next_property_offset(pfdt, propoff) )
+ {
+
+ if ( !(prop = fdt_get_property_by_offset(pfdt, propoff, NULL)) )
+ return -FDT_ERR_INTERNAL;
+
+ nameoff = fdt32_to_cpu(prop->nameoff);
+ r = fdt_property(fdt, fdt_string(pfdt, nameoff),
+ prop->data, fdt32_to_cpu(prop->len));
+ if ( r )
+ return r;
+ }
+
+ /* FDT_ERR_NOTFOUND => There is no more properties for this node */
+ return ( propoff != -FDT_ERR_NOTFOUND ) ? propoff : 0;
+}
+
+static int __init copy_node(void *fdt, void *pfdt, int nodeoff, int depth)
+{
+ int r;
+
+ r = fdt_begin_node(fdt, fdt_get_name(pfdt, nodeoff, NULL));
+ if ( r )
+ return r;
+
+ r = copy_properties(fdt, pfdt, nodeoff);
+ if ( r )
+ return r;
+
+ for ( nodeoff = fdt_first_subnode(pfdt, nodeoff);
+ nodeoff >= 0;
+ nodeoff = fdt_next_subnode(pfdt, nodeoff) )
+ {
+ r = copy_node(fdt, pfdt, nodeoff, depth + 1);
+ if ( r )
+ return r;
+ }
+
+ if ( nodeoff != -FDT_ERR_NOTFOUND )
+ return nodeoff;
+
+ r = fdt_end_node(fdt);
+ if ( r )
+ return r;
+
+ return 0;
+}
+
/*
* The max size for DT is 2MB. However, the generated DT is small, 4KB
* are enough for now, but we might have to increase it in the future.
@@ -1740,6 +1796,38 @@ static int __init prepare_dtb_domU(struct domain *d,
struct kernel_info *kinfo)
goto err;
}
+ if ( kinfo->dtb_bootmodule ) {
+ int nodeoff, res;
+ void *pfdt;
+
+ pfdt = ioremap_cache(kinfo->dtb_bootmodule->start,
+ kinfo->dtb_bootmodule->size);
+ if ( pfdt == NULL )
+ return -EFAULT;
+
+ if ( fdt_magic(pfdt) != FDT_MAGIC )
+ return -EINVAL;
+
+ nodeoff = fdt_path_offset(pfdt, "/passthrough");
+ if (nodeoff < 0)
+ return nodeoff;
+
+ res = copy_node(kinfo->fdt, pfdt, nodeoff, 0);
+ if ( res )
+ return res;
+
+ nodeoff = fdt_path_offset(pfdt, "/aliases");
+ if ( nodeoff >= 0 )
+ {
+ res = copy_node(kinfo->fdt, pfdt, nodeoff, 0);
+ if ( res )
+ return res;
+ }
+
+
+ iounmap(pfdt);
+ }
+
ret = fdt_end_node(kinfo->fdt);
if ( ret < 0 )
goto err;
diff --git a/xen/include/asm-arm/kernel.h b/xen/include/asm-arm/kernel.h
index 33f3e72..720dec4 100644
--- a/xen/include/asm-arm/kernel.h
+++ b/xen/include/asm-arm/kernel.h
@@ -28,7 +28,7 @@ struct kernel_info {
paddr_t gnttab_size;
/* boot blob load addresses */
- const struct bootmodule *kernel_bootmodule, *initrd_bootmodule;
+ const struct bootmodule *kernel_bootmodule, *initrd_bootmodule,
*dtb_bootmodule;
const char* cmdline;
paddr_t dtb_paddr;
paddr_t initrd_paddr;
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |