Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Feb 2023 15:50:55 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 045fa2801a8b - main - kboot: Try to read UEFI memory from physical memory on aarch64
Message-ID:  <202302031550.313Fot7T024155@gitrepo.freebsd.org>

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

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

commit 045fa2801a8bfd1cc05098757afa0f19df996027
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2023-02-03 15:40:45 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-02-03 15:41:41 +0000

    kboot: Try to read UEFI memory from physical memory on aarch64
    
    Try to open /dev/mem to read in the UEFI memory map. If we can't, then
    we'll read it in the trampoline.
    
    Retain reading in /proc/iomem to find reserved areas in Linux. We need
    to know them for good places to put the kernel. These are not reflected
    in the UEFI memory map. However, we should not adjust the UEFI memory
    map since these reserved areas of the Linux kernel are free to be used
    once we enter the kexec trampoline...
    
    Sponsored by:           Netflix
    Reviewed by:            tsoome, kevans, andrew
    Differential Revision:  https://reviews.freebsd.org/D38264
---
 stand/kboot/arch/aarch64/load_addr.c | 51 +++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 7 deletions(-)

diff --git a/stand/kboot/arch/aarch64/load_addr.c b/stand/kboot/arch/aarch64/load_addr.c
index ae8a599645c9..4cbbd5192f5b 100644
--- a/stand/kboot/arch/aarch64/load_addr.c
+++ b/stand/kboot/arch/aarch64/load_addr.c
@@ -28,7 +28,7 @@ do_memory_from_fdt(int fd)
 {
 	struct stat sb;
 	char *buf = NULL;
-	int len, offset;
+	int len, offset, fd2 = -1;
 	uint32_t sz, ver, esz, efisz;
 	uint64_t mmap_pa;
 	const uint32_t *u32p;
@@ -83,10 +83,10 @@ do_memory_from_fdt(int fd)
 	    ver, esz, sz, mmap_pa);
 
 	/*
-	 * We have no ability to read the PA that this map is in, so
-	 * pass the address to FreeBSD via a rather odd flag entry as
-	 * the first map so early boot can copy the memory map into
-	 * this space and have the rest of the code cope.
+	 * We may have no ability to read the PA that this map is in, so pass
+	 * the address to FreeBSD via a rather odd flag entry as the first map
+	 * so early boot can copy the memory map into this space and have the
+	 * rest of the code cope.
 	 */
 	efisz = (sizeof(*efihdr) + 0xf) & ~0xf;
 	buf = malloc(sz + efisz);
@@ -98,11 +98,45 @@ do_memory_from_fdt(int fd)
 	efihdr->memory_size = sz;
 	efihdr->descriptor_size = esz;
 	efihdr->descriptor_version = ver;
-	efi_map_phys_src = mmap_pa;
+
+	/*
+	 * Save EFI table. Either this will be an empty table filled in by the trampoline,
+	 * or we'll read it below. Either way, set these two variables so we share the best
+	 * UEFI memory map with the kernel.
+	 */
 	efi_map_hdr = efihdr;
 	efi_map_size = sz + efisz;
 
-	return true;
+	/*
+	 * Try to read in the actual UEFI map.
+	 */
+	fd2 = open("host:/dev/mem", O_RDONLY);
+	if (fd2 < 0) {
+		printf("Will read UEFI mem map in tramp: no /dev/mem, need CONFIG_DEVMEM=y\n");
+		goto no_read;
+	}
+	if (lseek(fd2, mmap_pa, SEEK_SET) < 0) {
+		printf("Will read UEFI mem map in tramp: lseek failed\n");
+		goto no_read;
+	}
+	len = read(fd2, map, sz);
+	if (len != sz) {
+		if (len < 0 && errno == EPERM)
+			printf("Will read UEFI mem map in tramp: kernel needs CONFIG_STRICT_DEVMEM=n\n");
+		else
+			printf("Will read UEFI mem map in tramp: lean = %d errno = %d\n", len, errno);
+		goto no_read;
+	}
+	printf("Read UEFI mem map from physmem\n");
+	efi_map_phys_src = 0; /* Mark MODINFOMD_EFI_MAP as valid */
+	close(fd2);
+	return true;	/* OK, we really have the memory map */
+
+no_read:
+	efi_map_phys_src = mmap_pa;
+	close(fd2);
+	return true;	/* We can get it the trampoline */
+
 errout:
 	free(buf);
 	return false;
@@ -157,6 +191,9 @@ void
 bi_loadsmap(struct preloaded_file *kfp)
 {
 
+	/*
+	 * Make a note of a systbl. This is nearly mandatory on AARCH64.
+	 */
 	if (efi_systbl_phys)
 		file_addmetadata(kfp, MODINFOMD_FW_HANDLE, sizeof(efi_systbl_phys), &efi_systbl_phys);
 



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