[PATCH v3 09/17] x86/efi: Intersect ranges_to_free with MEMBLOCK_RSRV_KERN regions

Ard Biesheuvel <[email protected]>
Newsgroups org.kernel.vger.linux-efi,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
From: Ard Biesheuvel <[email protected]>

efi_mem_reserve() will mark reservations in memblock with the
MEMBLOCK_RSRV_KERN attribute, so take this into account when building
the ranges_to_free array. This removes the need to split EFI memory map
entries and tag them with the EFI_MEMORY_RUNTIME attribute.

Signed-off-by: Ard Biesheuvel <[email protected]>
---
 arch/x86/platform/efi/quirks.c | 44 +++++++++++++++-----
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index ce452e5c2f0a..ce06a388fc11 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -406,19 +406,41 @@ static int num_to_free __initdata;
 
 static int __init efi_add_range_to_free(u64 range_start, u64 range_end)
 {
+	struct memblock_region *region;
 	static int idx __initdata;
 
-	ranges_to_free[idx].start = range_start;
-	ranges_to_free[idx].end = range_end;
-
-	if (++idx >= num_to_free) {
-		num_to_free *= 2;
-		ranges_to_free = krealloc_array(ranges_to_free,
-						num_to_free,
-						sizeof(ranges_to_free[0]),
-						GFP_KERNEL);
-		if (!ranges_to_free)
-			return -ENOMEM;
+	for_each_reserved_mem_region(region) {
+		u64 region_end = region->base + region->size;
+		u64 start, end;
+
+		/* memblock tables are sorted so no need to carry on */
+		if (region->base >= range_end)
+			break;
+
+		if (region_end < range_start)
+			continue;
+
+		if (region->flags & MEMBLOCK_RSRV_KERN)
+			continue;
+
+		start = PAGE_ALIGN(max(range_start, region->base));
+		end = PAGE_ALIGN_DOWN(min(range_end, region_end));
+
+		if (start >= end)
+			continue;
+
+		ranges_to_free[idx].start = start;
+		ranges_to_free[idx].end = end;
+
+		if (++idx >= num_to_free) {
+			num_to_free *= 2;
+			ranges_to_free = krealloc_array(ranges_to_free,
+							num_to_free,
+							sizeof(ranges_to_free[0]),
+							GFP_KERNEL);
+			if (!ranges_to_free)
+				return -ENOMEM;
+		}
 	}
 
 	/* add a terminating entry at the end */
-- 
2.54.0.rc2.544.gc7ae2d5bb8-goog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.