git: b38b585da053 - stable/13 - stand/efi: allow not exiting boot services

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 24 Jan 2023 22:09:39 UTC
The branch stable/13 has been updated by imp:

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

commit b38b585da0533b47c9545d239d6fca28cf673cac
Author:     Roger Pau Monné <royger@FreeBSD.org>
AuthorDate: 2021-02-05 10:15:19 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-01-24 21:49:15 +0000

    stand/efi: allow not exiting boot services
    
    Xen requires that UEFI BootServices are enabled in order to boot, so
    introduce a new parameter to bi_load in order to select whether BS
    should be exited.
    
    No functional change introduced in this patch, as all current users of
    bi_load request BS to be exited. Further changes will make use of this
    functionality.
    
    Note the memory map is still appended to the kernel metadata, even
    when it could be modified by further calls to the Boot Services, as it
    will be used to detect if the kernel has been booted from UEFI.
    
    Sponsored by:           Citrix Systems R&D
    Reviewed by:            tsoome, imp
    Differential revision:  https://reviews.freebsd.org/D28495
    
    (cherry picked from commit ed87efbe24a5734c7150153cf201f3db42b6ddab)
---
 stand/efi/loader/arch/amd64/elf64_freebsd.c |  5 +++--
 stand/efi/loader/arch/arm/exec.c            |  4 ++--
 stand/efi/loader/arch/arm64/exec.c          |  5 +++--
 stand/efi/loader/arch/i386/elf32_freebsd.c  |  5 +++--
 stand/efi/loader/arch/riscv/exec.c          |  4 ++--
 stand/efi/loader/bootinfo.c                 | 13 ++++++++-----
 6 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/stand/efi/loader/arch/amd64/elf64_freebsd.c b/stand/efi/loader/arch/amd64/elf64_freebsd.c
index 7aa5735e0cfc..354f86f090ce 100644
--- a/stand/efi/loader/arch/amd64/elf64_freebsd.c
+++ b/stand/efi/loader/arch/amd64/elf64_freebsd.c
@@ -54,7 +54,8 @@ __FBSDID("$FreeBSD$");
 static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
 static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
 
-extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
+extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
+    bool exit_bs);
 
 static int	elf64_exec(struct preloaded_file *amp);
 static int	elf64_obj_exec(struct preloaded_file *amp);
@@ -269,7 +270,7 @@ elf64_exec(struct preloaded_file *fp)
 	printf("Start @ 0x%lx ...\n", ehdr->e_entry);
 
 	efi_time_fini();
-	err = bi_load(fp->f_args, &modulep, &kernend);
+	err = bi_load(fp->f_args, &modulep, &kernend, true);
 	if (err != 0) {
 		efi_time_init();
 		if (copy_auto)
diff --git a/stand/efi/loader/arch/arm/exec.c b/stand/efi/loader/arch/arm/exec.c
index 86c931bcbbe8..a110f3d07cbc 100644
--- a/stand/efi/loader/arch/arm/exec.c
+++ b/stand/efi/loader/arch/arm/exec.c
@@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
 #include "loader_efi.h"
 
 extern vm_offset_t md_load(char *, vm_offset_t *);
-extern int bi_load(char *, vm_offset_t *, vm_offset_t *);
+extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool);
 
 static int
 __elfN(arm_load)(char *filename, uint64_t dest,
@@ -80,7 +80,7 @@ __elfN(arm_exec)(struct preloaded_file *fp)
 	printf("Kernel entry at %p...\n", entry);
 	printf("Kernel args: %s\n", fp->f_args);
 
-	if ((error = bi_load(fp->f_args, &modulep, &kernend)) != 0) {
+	if ((error = bi_load(fp->f_args, &modulep, &kernend, true)) != 0) {
 		efi_time_init();
 		return (error);
 	}
diff --git a/stand/efi/loader/arch/arm64/exec.c b/stand/efi/loader/arch/arm64/exec.c
index a3021083dc08..6cf4a4fd8e4d 100644
--- a/stand/efi/loader/arch/arm64/exec.c
+++ b/stand/efi/loader/arch/arm64/exec.c
@@ -55,7 +55,8 @@ static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
 static int elf64_exec(struct preloaded_file *amp);
 static int elf64_obj_exec(struct preloaded_file *amp);
 
-int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
+int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
+    bool exit_bs);
 
 static struct file_format arm64_elf = {
 	elf64_loadfile,
@@ -114,7 +115,7 @@ elf64_exec(struct preloaded_file *fp)
 	entry = efi_translate(ehdr->e_entry);
 
 	efi_time_fini();
-	err = bi_load(fp->f_args, &modulep, &kernendp);
+	err = bi_load(fp->f_args, &modulep, &kernendp, true);
 	if (err != 0) {
 		efi_time_init();
 		return (err);
diff --git a/stand/efi/loader/arch/i386/elf32_freebsd.c b/stand/efi/loader/arch/i386/elf32_freebsd.c
index 847d6eead097..97d114f09610 100644
--- a/stand/efi/loader/arch/i386/elf32_freebsd.c
+++ b/stand/efi/loader/arch/i386/elf32_freebsd.c
@@ -43,7 +43,8 @@ __FBSDID("$FreeBSD$");
 #include "../btx/lib/btxv86.h"
 
 extern void __exec(caddr_t addr, ...);
-extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
+extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
+    bool exit_bs);
 
 static int	elf32_exec(struct preloaded_file *amp);
 static int	elf32_obj_exec(struct preloaded_file *amp);
@@ -80,7 +81,7 @@ elf32_exec(struct preloaded_file *fp)
 
     printf("Start @ 0x%x ...\n", entry);
 
-    err = bi_load(fp->f_args, &modulep, &kernend);
+    err = bi_load(fp->f_args, &modulep, &kernend, true);
     if (err != 0) {
 	efi_time_init();
 	return(err);
diff --git a/stand/efi/loader/arch/riscv/exec.c b/stand/efi/loader/arch/riscv/exec.c
index fe40003a475b..c7d90a4f31d0 100644
--- a/stand/efi/loader/arch/riscv/exec.c
+++ b/stand/efi/loader/arch/riscv/exec.c
@@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$");
 #include "bootstrap.h"
 #include "loader_efi.h"
 
-extern int bi_load(char *, vm_offset_t *, vm_offset_t *);
+extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool);
 
 static int
 __elfN(exec)(struct preloaded_file *fp)
@@ -66,7 +66,7 @@ __elfN(exec)(struct preloaded_file *fp)
 	printf("Kernel entry at %p...\n", entry);
 	printf("Kernel args: %s\n", fp->f_args);
 
-	if ((error = bi_load(fp->f_args, &modulep, &kernend)) != 0) {
+	if ((error = bi_load(fp->f_args, &modulep, &kernend, true)) != 0) {
 		efi_time_init();
 		return (error);
 	}
diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c
index b560bf268aad..1a6de233b8cf 100644
--- a/stand/efi/loader/bootinfo.c
+++ b/stand/efi/loader/bootinfo.c
@@ -60,7 +60,8 @@ __FBSDID("$FreeBSD$");
 #include "geliboot.h"
 #endif
 
-int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
+int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
+    bool exit_bs);
 
 extern EFI_SYSTEM_TABLE	*ST;
 
@@ -284,7 +285,7 @@ efi_do_vmap(EFI_MEMORY_DESCRIPTOR *mm, UINTN sz, UINTN mmsz, UINT32 mmver)
 }
 
 static int
-bi_load_efi_data(struct preloaded_file *kfp)
+bi_load_efi_data(struct preloaded_file *kfp, bool exit_bs)
 {
 	EFI_MEMORY_DESCRIPTOR *mm;
 	EFI_PHYSICAL_ADDRESS addr = 0;
@@ -393,7 +394,9 @@ bi_load_efi_data(struct preloaded_file *kfp)
 			sz = (EFI_PAGE_SIZE * pages) - efisz;
 		}
 
-		status = efi_exit_boot_services(efi_mapkey);
+		if (!exit_bs)
+			break;
+		status = BS->ExitBootServices(IH, efi_mapkey);
 		if (!EFI_ERROR(status))
 			break;
 	}
@@ -431,7 +434,7 @@ bi_load_efi_data(struct preloaded_file *kfp)
  * - Module metadata are formatted and placed in kernel space.
  */
 int
-bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
+bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs)
 {
 	struct preloaded_file *xp, *kfp;
 	struct devdesc *rootdev;
@@ -530,7 +533,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
 #ifdef LOADER_GELI_SUPPORT
 	geli_export_key_metadata(kfp);
 #endif
-	bi_load_efi_data(kfp);
+	bi_load_efi_data(kfp, exit_bs);
 
 	/* Figure out the size and location of the metadata. */
 	*modulep = addr;