Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Jul 2025 18:15:47 GMT
From:      "Simon J. Gerraty" <sjg@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: d1f0ee548c73 - main - Allow net_cleanup for loader.efi
Message-ID:  <202507101815.56AIFlTP010436@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by sjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=d1f0ee548c73fa4d6e097539b9be01dae683b99b

commit d1f0ee548c73fa4d6e097539b9be01dae683b99b
Author:     Simon J. Gerraty <sjg@FreeBSD.org>
AuthorDate: 2025-07-10 18:14:38 +0000
Commit:     Simon J. Gerraty <sjg@FreeBSD.org>
CommitDate: 2025-07-10 18:14:38 +0000

    Allow net_cleanup for loader.efi
    
    While netbooting with loader.efi on at least one arm64 platform
    which uses u-boot emulating UEFI, the kernel gets corrupted, we
    suspected the u-boot ethernet driver was still running.
    
    Use netdev.dv_cleanup for efinet_dev to address this.
    
    This in turn requires calling dev_cleanup() before bi_load() to avoid
    a loader crash since bi_load() calls ExitBootServices.
    
    Reviewed by:    imp
    Sponsored by:   Juniper Networks, Inc.
    Differential Revision:  https://reviews.freebsd.org/D51186
---
 stand/efi/libefi/efinet.c                   |  2 ++
 stand/efi/loader/arch/amd64/elf64_freebsd.c |  8 ++++++--
 stand/efi/loader/arch/arm/exec.c            | 11 ++++++-----
 stand/efi/loader/arch/arm64/exec.c          |  8 ++++++--
 stand/efi/loader/arch/i386/elf64_freebsd.c  |  9 +++++++--
 stand/efi/loader/arch/riscv/exec.c          | 12 ++++++------
 6 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/stand/efi/libefi/efinet.c b/stand/efi/libefi/efinet.c
index 186d816cd323..e872110ef08f 100644
--- a/stand/efi/libefi/efinet.c
+++ b/stand/efi/libefi/efinet.c
@@ -256,6 +256,7 @@ efi_env_net_params(struct iodesc *desc)
 	rootip.s_addr = rootaddr;
 
 #ifdef EFINET_DEBUG
+	printf("%s: proto=%d\n", __func__, netproto);
 	printf("%s: ip=%s\n", __func__, inet_ntoa(myip));
 	printf("%s: mask=%s\n", __func__, intoa(netmask));
 	printf("%s: gateway=%s\n", __func__, inet_ntoa(gateip));
@@ -427,6 +428,7 @@ efinet_dev_init(void)
 		dif->dif_private = handles2[i];
 	}
 
+	efinet_dev.dv_cleanup = netdev.dv_cleanup;
 	efinet_dev.dv_open = netdev.dv_open;
 	efinet_dev.dv_close = netdev.dv_close;
 	efinet_dev.dv_strategy = netdev.dv_strategy;
diff --git a/stand/efi/loader/arch/amd64/elf64_freebsd.c b/stand/efi/loader/arch/amd64/elf64_freebsd.c
index c4265aca035e..35bd4d6c1419 100644
--- a/stand/efi/loader/arch/amd64/elf64_freebsd.c
+++ b/stand/efi/loader/arch/amd64/elf64_freebsd.c
@@ -209,6 +209,12 @@ elf64_exec(struct preloaded_file *fp)
 	    trampoline, PT4);
 	printf("Start @ 0x%lx ...\n", ehdr->e_entry);
 
+	/*
+	 * we have to cleanup here because net_cleanup() doesn't work after
+	 * we call ExitBootServices
+	 */
+	dev_cleanup();
+
 	efi_time_fini();
 	err = bi_load(fp->f_args, &modulep, &kernend, true);
 	if (err != 0) {
@@ -218,8 +224,6 @@ elf64_exec(struct preloaded_file *fp)
 		return (err);
 	}
 
-	dev_cleanup();
-
 	trampoline(trampstack, copy_staging == COPY_STAGING_ENABLE ?
 	    efi_copy_finish : efi_copy_finish_nop, kernend, modulep,
 	    PT4, ehdr->e_entry);
diff --git a/stand/efi/loader/arch/arm/exec.c b/stand/efi/loader/arch/arm/exec.c
index c2a79523c02a..3963b6c0104b 100644
--- a/stand/efi/loader/arch/arm/exec.c
+++ b/stand/efi/loader/arch/arm/exec.c
@@ -74,16 +74,17 @@ __elfN(arm_exec)(struct preloaded_file *fp)
 	printf("Kernel entry at %p...\n", entry);
 	printf("Kernel args: %s\n", fp->f_args);
 
+	/*
+	 * we have to cleanup here because net_cleanup() doesn't work after
+	 * we call ExitBootServices
+	 */
+	dev_cleanup();
+	
 	if ((error = bi_load(fp->f_args, &modulep, &kernend, true)) != 0) {
 		efi_time_init();
 		return (error);
 	}
 
-	/* At this point we've called ExitBootServices, so we can't call
-	 * printf or any other function that uses Boot Services */
-
-	dev_cleanup();
-
 	(*entry)((void *)modulep);
 	panic("exec returned");
 }
diff --git a/stand/efi/loader/arch/arm64/exec.c b/stand/efi/loader/arch/arm64/exec.c
index 91a0503a976f..89e2ad7521a8 100644
--- a/stand/efi/loader/arch/arm64/exec.c
+++ b/stand/efi/loader/arch/arm64/exec.c
@@ -69,6 +69,12 @@ elf64_exec(struct preloaded_file *fp)
 	ehdr = (Elf_Ehdr *)&(md->md_data);
 	entry = efi_translate(ehdr->e_entry);
 
+	/*
+	 * we have to cleanup here because net_cleanup() doesn't work after
+	 * we call ExitBootServices
+	 */
+	dev_cleanup();
+
 	efi_time_fini();
 	err = bi_load(fp->f_args, &modulep, &kernendp, true);
 	if (err != 0) {
@@ -76,8 +82,6 @@ elf64_exec(struct preloaded_file *fp)
 		return (err);
 	}
 
-	dev_cleanup();
-
 	/* Clean D-cache under kernel area and invalidate whole I-cache */
 	clean_addr = (vm_offset_t)efi_translate(fp->f_addr);
 	clean_size = (vm_offset_t)efi_translate(kernendp) - clean_addr;
diff --git a/stand/efi/loader/arch/i386/elf64_freebsd.c b/stand/efi/loader/arch/i386/elf64_freebsd.c
index b02cda2269bc..22cdd685ea9b 100644
--- a/stand/efi/loader/arch/i386/elf64_freebsd.c
+++ b/stand/efi/loader/arch/i386/elf64_freebsd.c
@@ -252,6 +252,13 @@ elf64_exec(struct preloaded_file *fp)
 	    ehdr->e_entry
 	);
 
+
+	/*
+	 * we have to cleanup here because net_cleanup() doesn't work after
+	 * we call ExitBootServices
+	 */
+	dev_cleanup();
+
 	efi_time_fini();
 	err = bi_load(fp->f_args, &modulep, &kernend, true);
 	if (err != 0) {
@@ -259,8 +266,6 @@ elf64_exec(struct preloaded_file *fp)
 		return (err);
 	}
 
-	dev_cleanup();
-
 	trampoline(trampstack, type == AllocateMaxAddress ? efi_copy_finish :
 	    efi_copy_finish_nop, kernend, modulep, PT4, gdtr, ehdr->e_entry);
 
diff --git a/stand/efi/loader/arch/riscv/exec.c b/stand/efi/loader/arch/riscv/exec.c
index 9da61229ef68..a53fbd9442b0 100644
--- a/stand/efi/loader/arch/riscv/exec.c
+++ b/stand/efi/loader/arch/riscv/exec.c
@@ -86,17 +86,17 @@ __elfN(exec)(struct preloaded_file *fp)
 	printf("Kernel entry at %p...\n", entry);
 	printf("Kernel args: %s\n", fp->f_args);
 
+	/*
+	 * we have to cleanup here because net_cleanup() doesn't work after
+	 * we call ExitBootServices
+	 */
+	dev_cleanup();
+
 	if ((error = bi_load(fp->f_args, &modulep, &kernend, true)) != 0) {
 		efi_time_init();
 		return (error);
 	}
 
-	/*
-	 * At this point we've called ExitBootServices, so we can't call
-	 * printf or any other function that uses Boot Services
-	 */
-	dev_cleanup();
-
 	(*entry)((void *)modulep);
 	panic("exec returned");
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202507101815.56AIFlTP010436>