]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Create a copy of the system flattened device tree, if present
authorMichael Brown <mcb30@ipxe.org>
Fri, 28 Mar 2025 14:10:55 +0000 (14:10 +0000)
committerMichael Brown <mcb30@ipxe.org>
Fri, 28 Mar 2025 15:29:20 +0000 (15:29 +0000)
EFI configuration tables may be freed at any time, and there is no way
to be notified when the table becomes invalidated.  Create a copy of
the system flattened device tree (if present), so that we do not risk
being left with an invalid pointer.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/fdt.c
src/include/ipxe/fdt.h
src/interface/efi/efi_fdt.c

index 9c2880c843ef49bbd33fa2729731e3bc8ca00490..4fd2b76bfe4bbd026611ee2e67f96deabac19904 100644 (file)
@@ -456,8 +456,7 @@ int fdt_mac ( struct fdt *fdt, unsigned int offset,
  * @v max_len          Maximum device tree length
  * @ret rc             Return status code
  */
-int fdt_parse ( struct fdt *fdt, const struct fdt_header *hdr,
-               size_t max_len ) {
+int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr, size_t max_len ) {
        const uint8_t *end;
 
        /* Sanity check */
index 70dc017909f9e733e1679c9154a55aca6fed33f7..2799e0d07f1eb766a4d595f93c4055896ea094ef 100644 (file)
@@ -78,9 +78,9 @@ struct fdt {
        /** Tree data */
        union {
                /** Tree header */
-               const struct fdt_header *hdr;
+               struct fdt_header *hdr;
                /** Raw data */
-               const void *raw;
+               void *raw;
        };
        /** Length of tree */
        size_t len;
@@ -107,7 +107,7 @@ extern int fdt_u64 ( struct fdt *fdt, unsigned int offset, const char *name,
                     uint64_t *value );
 extern int fdt_mac ( struct fdt *fdt, unsigned int offset,
                     struct net_device *netdev );
-extern int fdt_parse ( struct fdt *fdt, const struct fdt_header *hdr,
+extern int fdt_parse ( struct fdt *fdt, struct fdt_header *hdr,
                       size_t max_len );
 
 #endif /* _IPXE_FDT_H */
index e207f7e6d6930d67570d2bb9150dc1935a07d97b..71b788ae71ac24eb8e52e9f0da77e08499dfbd51 100644 (file)
@@ -44,6 +44,8 @@ EFI_USE_TABLE ( FDT_TABLE, &efi_fdt, 0 );
  *
  */
 static void efi_fdt_init ( void ) {
+       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+       EFI_STATUS efirc;
        int rc;
 
        /* Do nothing if no configuration table is present */
@@ -59,6 +61,15 @@ static void efi_fdt_init ( void ) {
                       strerror ( rc ) );
                return;
        }
+
+       /* Create copy, since table may be removed at any time */
+       if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, sysfdt.len,
+                                         &sysfdt.raw ) ) != 0 ) {
+               DBGC ( &efi_fdt, "EFIFDT could not create copy\n" );
+               sysfdt.len = 0;
+               return;
+       }
+       memcpy ( sysfdt.raw, efi_fdt, sysfdt.len );
 }
 
 /** EFI Flattened Device Tree initialisation function */