On 8/26/24 5:44 AM, Sergii Dmytruk wrote:
From: Daniel Kiper <daniel.ki...@oracle.com>
The functions calculate lowest and highest available RAM
addresses respectively.
Both functions are needed to calculate PMR boundaries for
Intel TXT secure launcher introduced by subsequent patches.
After discussing this we think the best course of action is to submit
the first 7 patches standalone (also see my response to patch 11 that is
coming). For this patch I would just remove the last sentence about TXT
so it is not tied to the DRTM work.
Then you can submit this set (with the couple of the changes I suggested
earlier) and we can more easily get this part in.
Thanks
Ross
Signed-off-by: Daniel Kiper <daniel.ki...@oracle.com>
---
grub-core/mmap/mmap.c | 83 +++++++++++++++++++++++++++++++++++++++++++
include/grub/memory.h | 3 ++
2 files changed, 86 insertions(+)
diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c
index c8c8312c5..80d6c60b8 100644
--- a/grub-core/mmap/mmap.c
+++ b/grub-core/mmap/mmap.c
@@ -26,6 +26,7 @@
#include <grub/command.h>
#include <grub/dl.h>
#include <grub/i18n.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -343,6 +344,88 @@ grub_mmap_unregister (int handle)
#endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */
+typedef struct
+{
+ grub_uint64_t addr;
+ grub_uint64_t limit;
+} addr_limit_t;
+
+/* Helper for grub_mmap_get_lowest(). */
+static int
+lowest_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data)
+{
+ addr_limit_t *al = data;
+ grub_uint64_t end;
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+
+ if (grub_add (addr, size, &end))
+ return 0;
+
+ if (addr >= al->limit)
+ al->addr = grub_min (al->addr, addr);
+
+ if ((addr < al->limit) && (end > al->limit))
+ al->addr = al->limit;
+
+ return 0;
+}
+
+/*
+ * This function calculates lowest available RAM address that is at or above
+ * the passed limit. If no RAM exists above the limit, ~0 is returned.
+ */
+grub_uint64_t
+grub_mmap_get_lowest (grub_uint64_t limit)
+{
+ addr_limit_t al = {~0, limit};
+
+ grub_mmap_iterate (lowest_hook, &al);
+
+ return al.addr;
+}
+
+/* Helper for grub_mmap_get_highest(). */
+static int
+highest_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
+ void *data)
+{
+ addr_limit_t *al = data;
+ grub_uint64_t end;
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+
+ if (grub_add (addr, size, &end))
+ return 0;
+
+ if (end < al->limit)
+ al->addr = grub_max (al->addr, end);
+
+ if ((addr < al->limit) && (end >= al->limit))
+ al->addr = al->limit;
+
+ return 0;
+}
+
+/*
+ * This function calculates highest available RAM address that is below the
+ * passed limit. Returned address is either one byte after last byte of RAM or
+ * equal to limit, whichever is lower. If no RAM exists below limit, 0 is
+ * returned.
+ */
+grub_uint64_t
+grub_mmap_get_highest (grub_uint64_t limit)
+{
+ addr_limit_t al = {0, limit};
+
+ grub_mmap_iterate (highest_hook, &al);
+
+ return al.addr;
+}
+
#define CHUNK_SIZE 0x400
struct badram_entry {
diff --git a/include/grub/memory.h b/include/grub/memory.h
index 6da114a1b..8f22f7525 100644
--- a/include/grub/memory.h
+++ b/include/grub/memory.h
@@ -69,6 +69,9 @@ void *grub_mmap_malign_and_register (grub_uint64_t align,
grub_uint64_t size,
void grub_mmap_free_and_unregister (int handle);
+extern grub_uint64_t grub_mmap_get_lowest (grub_uint64_t limit);
+extern grub_uint64_t grub_mmap_get_highest (grub_uint64_t limit);
+
#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
struct grub_mmap_region
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel