aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Horne <mhorne@FreeBSD.org>2023-03-15 15:26:57 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2023-03-24 13:12:40 +0000
commit865b5640f8ef3c3a369f13b2c531737b7fb8fec4 (patch)
treecab9cfde02100d4cd17277859c32eb5ccc40ff26
parent9521266b82dfaa82ca4ac56276a049aee5f01ad9 (diff)
downloadsrc-865b5640f8ef3c3a369f13b2c531737b7fb8fec4.tar.gz
src-865b5640f8ef3c3a369f13b2c531737b7fb8fec4.zip
arm64: limit EFI excluded regions to physical memory types
Consolidate add_efi_map_entry() and exclude_efi_map_entry() into a single function, handle_efi_map_entry(), so that the exact set of entry types handled is the same in the addition or exclusion cases. Before, exclude_efi_map_entry() had a 'default' case that would exclude all entry types that were not listed explicitly in the switch statement. Logically, we do not need to exclude a range that could not possibly be added to physmem, and we do not need to exclude bus ranges that are not physical memory, for example EFI_MD_TYPE_IOMEM. Since physmem's ram0 device will reserve bus memory resources for its owned ranges, this was preventing attachment of the watchdog device on the RPI4B. For some reason its region of memory-mapped I/O appeared in the EFI memory map (with the aforementioned EFI_MD_TYPE_IOMEM type). This change fixes the attachment issue, as we prevent the physmem API from messing with this range of bus space. PR: 270044 Reported by: karels, Mark Millard Reviewed by: andrew, karels, imp MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D39003 (cherry picked from commit 8937bd37d07c5c75995e01457aec00fb0a05c462)
-rw-r--r--sys/arm64/arm64/machdep.c71
1 files changed, 39 insertions, 32 deletions
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index 283ca221d7f3..68fcf0257232 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -446,36 +446,25 @@ foreach_efi_map_entry(struct efi_map_header *efihdr, efi_map_entry_cb cb, void *
}
}
+/*
+ * Handle the EFI memory map list.
+ *
+ * We will make two passes at this, the first (exclude == false) to populate
+ * physmem with valid physical memory ranges from recognized map entry types.
+ * In the second pass we will exclude memory ranges from physmem which must not
+ * be used for general allocations, either because they are used by runtime
+ * firmware or otherwise reserved.
+ *
+ * Adding the runtime-reserved memory ranges to physmem and excluding them
+ * later ensures that they are included in the DMAP, but excluded from
+ * phys_avail[].
+ *
+ * Entry types not explicitly listed here are ignored and not mapped.
+ */
static void
-exclude_efi_map_entry(struct efi_md *p, void *argp __unused)
-{
-
- switch (p->md_type) {
- case EFI_MD_TYPE_CODE:
- case EFI_MD_TYPE_DATA:
- case EFI_MD_TYPE_BS_CODE:
- case EFI_MD_TYPE_BS_DATA:
- case EFI_MD_TYPE_FREE:
- /*
- * We're allowed to use any entry with these types.
- */
- break;
- default:
- physmem_exclude_region(p->md_phys, p->md_pages * EFI_PAGE_SIZE,
- EXFLAG_NOALLOC);
- }
-}
-
-static void
-exclude_efi_map_entries(struct efi_map_header *efihdr)
-{
-
- foreach_efi_map_entry(efihdr, exclude_efi_map_entry, NULL);
-}
-
-static void
-add_efi_map_entry(struct efi_md *p, void *argp __unused)
+handle_efi_map_entry(struct efi_md *p, void *argp)
{
+ bool exclude = *(bool *)argp;
switch (p->md_type) {
case EFI_MD_TYPE_RECLAIM:
@@ -487,7 +476,7 @@ add_efi_map_entry(struct efi_md *p, void *argp __unused)
/*
* Some UEFI implementations put the system table in the
* runtime code section. Include it in the DMAP, but will
- * be excluded from phys_avail later.
+ * be excluded from phys_avail.
*/
case EFI_MD_TYPE_RT_DATA:
/*
@@ -495,6 +484,12 @@ add_efi_map_entry(struct efi_md *p, void *argp __unused)
* region is created to stop it from being added
* to phys_avail.
*/
+ if (exclude) {
+ physmem_exclude_region(p->md_phys,
+ p->md_pages * EFI_PAGE_SIZE, EXFLAG_NOALLOC);
+ break;
+ }
+ /* FALLTHROUGH */
case EFI_MD_TYPE_CODE:
case EFI_MD_TYPE_DATA:
case EFI_MD_TYPE_BS_CODE:
@@ -503,8 +498,12 @@ add_efi_map_entry(struct efi_md *p, void *argp __unused)
/*
* We're allowed to use any entry with these types.
*/
- physmem_hardware_region(p->md_phys,
- p->md_pages * EFI_PAGE_SIZE);
+ if (!exclude)
+ physmem_hardware_region(p->md_phys,
+ p->md_pages * EFI_PAGE_SIZE);
+ break;
+ default:
+ /* Other types shall not be handled by physmem. */
break;
}
}
@@ -512,7 +511,15 @@ add_efi_map_entry(struct efi_md *p, void *argp __unused)
static void
add_efi_map_entries(struct efi_map_header *efihdr)
{
- foreach_efi_map_entry(efihdr, add_efi_map_entry, NULL);
+ bool exclude = false;
+ foreach_efi_map_entry(efihdr, handle_efi_map_entry, &exclude);
+}
+
+static void
+exclude_efi_map_entries(struct efi_map_header *efihdr)
+{
+ bool exclude = true;
+ foreach_efi_map_entry(efihdr, handle_efi_map_entry, &exclude);
}
static void