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
This commit is contained in:
Roger Pau Monné 2021-02-05 11:15:19 +01:00
parent 3c40e1d52c
commit ed87efbe24
6 changed files with 20 additions and 14 deletions

View File

@ -54,7 +54,8 @@ __FBSDID("$FreeBSD$");
static EFI_GUID acpi_guid = ACPI_TABLE_GUID; static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
static EFI_GUID acpi20_guid = ACPI_20_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_exec(struct preloaded_file *amp);
static int elf64_obj_exec(struct preloaded_file *amp); static int elf64_obj_exec(struct preloaded_file *amp);
@ -186,7 +187,7 @@ elf64_exec(struct preloaded_file *fp)
printf("Start @ 0x%lx ...\n", ehdr->e_entry); printf("Start @ 0x%lx ...\n", ehdr->e_entry);
efi_time_fini(); efi_time_fini();
err = bi_load(fp->f_args, &modulep, &kernend); err = bi_load(fp->f_args, &modulep, &kernend, true);
if (err != 0) { if (err != 0) {
efi_time_init(); efi_time_init();
return(err); return(err);

View File

@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
#include "loader_efi.h" #include "loader_efi.h"
extern vm_offset_t md_load(char *, vm_offset_t *); 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 static int
__elfN(arm_load)(char *filename, uint64_t dest, __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 entry at %p...\n", entry);
printf("Kernel args: %s\n", fp->f_args); 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(); efi_time_init();
return (error); return (error);
} }

View File

@ -55,7 +55,8 @@ static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
static int elf64_exec(struct preloaded_file *amp); static int elf64_exec(struct preloaded_file *amp);
static int elf64_obj_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 = { static struct file_format arm64_elf = {
elf64_loadfile, elf64_loadfile,
@ -114,7 +115,7 @@ elf64_exec(struct preloaded_file *fp)
entry = efi_translate(ehdr->e_entry); entry = efi_translate(ehdr->e_entry);
efi_time_fini(); efi_time_fini();
err = bi_load(fp->f_args, &modulep, &kernendp); err = bi_load(fp->f_args, &modulep, &kernendp, true);
if (err != 0) { if (err != 0) {
efi_time_init(); efi_time_init();
return (err); return (err);

View File

@ -43,7 +43,8 @@ __FBSDID("$FreeBSD$");
#include "../btx/lib/btxv86.h" #include "../btx/lib/btxv86.h"
extern void __exec(caddr_t addr, ...); 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_exec(struct preloaded_file *amp);
static int elf32_obj_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); 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) { if (err != 0) {
efi_time_init(); efi_time_init();
return(err); return(err);

View File

@ -43,7 +43,7 @@ __FBSDID("$FreeBSD$");
#include "bootstrap.h" #include "bootstrap.h"
#include "loader_efi.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 static int
__elfN(exec)(struct preloaded_file *fp) __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 entry at %p...\n", entry);
printf("Kernel args: %s\n", fp->f_args); 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(); efi_time_init();
return (error); return (error);
} }

View File

@ -60,7 +60,8 @@ __FBSDID("$FreeBSD$");
#include "geliboot.h" #include "geliboot.h"
#endif #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; extern EFI_SYSTEM_TABLE *ST;
@ -284,7 +285,7 @@ efi_do_vmap(EFI_MEMORY_DESCRIPTOR *mm, UINTN sz, UINTN mmsz, UINT32 mmver)
} }
static int 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_MEMORY_DESCRIPTOR *mm;
EFI_PHYSICAL_ADDRESS addr = 0; EFI_PHYSICAL_ADDRESS addr = 0;
@ -392,6 +393,8 @@ bi_load_efi_data(struct preloaded_file *kfp)
sz = (EFI_PAGE_SIZE * pages) - efisz; sz = (EFI_PAGE_SIZE * pages) - efisz;
} }
if (!exit_bs)
break;
status = BS->ExitBootServices(IH, efi_mapkey); status = BS->ExitBootServices(IH, efi_mapkey);
if (!EFI_ERROR(status)) if (!EFI_ERROR(status))
break; break;
@ -430,7 +433,7 @@ bi_load_efi_data(struct preloaded_file *kfp)
* - Module metadata are formatted and placed in kernel space. * - Module metadata are formatted and placed in kernel space.
*/ */
int 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 preloaded_file *xp, *kfp;
struct devdesc *rootdev; struct devdesc *rootdev;
@ -529,7 +532,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
#ifdef LOADER_GELI_SUPPORT #ifdef LOADER_GELI_SUPPORT
geli_export_key_metadata(kfp); geli_export_key_metadata(kfp);
#endif #endif
bi_load_efi_data(kfp); bi_load_efi_data(kfp, exit_bs);
/* Figure out the size and location of the metadata. */ /* Figure out the size and location of the metadata. */
*modulep = addr; *modulep = addr;