Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108322773
D22569.id64937.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D22569.id64937.diff
View Options
Index: stand/efi/loader/copy.c
===================================================================
--- stand/efi/loader/copy.c
+++ stand/efi/loader/copy.c
@@ -185,7 +185,7 @@
#endif
#endif
-EFI_PHYSICAL_ADDRESS staging, staging_end;
+EFI_PHYSICAL_ADDRESS staging, staging_end, staging_base;
int stage_offset_set = 0;
ssize_t stage_offset;
@@ -224,6 +224,7 @@
EFI_ERROR_CODE(status));
return (status);
}
+ staging_base = staging;
staging_end = staging + nr_pages * EFI_PAGE_SIZE;
#if defined(__aarch64__) || defined(__arm__)
@@ -240,6 +241,66 @@
return (0);
}
+static bool
+efi_check_space(vm_offset_t end)
+{
+ EFI_PHYSICAL_ADDRESS addr;
+ EFI_STATUS status;
+ unsigned long nr_pages;
+
+ /* There is already enough space */
+ if (end <= staging_end)
+ return (true);
+
+ end = roundup2(end, EFI_PAGE_SIZE);
+ nr_pages = EFI_SIZE_TO_PAGES(end - staging_end);
+
+#if defined(__i386__) || defined(__amd64__)
+ /* X86 needs all memory to be allocated under the 1G boundary */
+ if (end > 1024*1024*1024)
+ goto before_staging;
+#endif
+
+ /* Try to allocate more space after the previous allocation */
+ addr = staging_end;
+ status = BS->AllocatePages(AllocateAddress, EfiLoaderData, nr_pages,
+ &addr);
+ if (!EFI_ERROR(status)) {
+ staging_end = staging_end + nr_pages * EFI_PAGE_SIZE;
+ return (true);
+ }
+
+before_staging:
+ /* Try allocating space before the previous allocation */
+ if (staging < nr_pages * EFI_PAGE_SIZE) {
+ printf("Not enough space before allocation\n");
+ return (false);
+ }
+ addr = staging - nr_pages * EFI_PAGE_SIZE;
+#if defined(__aarch64__) || defined(__arm__)
+ /* See efi_copy_init for why this is needed */
+ addr = rounddown2(addr, 2 * 1024 * 1024);
+#endif
+ nr_pages = EFI_SIZE_TO_PAGES(staging_base - addr);
+ status = BS->AllocatePages(AllocateAddress, EfiLoaderData, nr_pages,
+ &addr);
+ if (!EFI_ERROR(status)) {
+ /*
+ * Move the old allocation and update the state so
+ * translation still works.
+ */
+ staging_base = addr;
+ memmove((void *)staging_base, (void *)staging,
+ staging_end - staging);
+ stage_offset -= (staging - staging_base);
+ staging = staging_base;
+ return (true);
+ }
+
+ printf("efi_check_space: Unable to expand staging area\n");
+ return (false);
+}
+
void *
efi_translate(vm_offset_t ptr)
{
@@ -257,7 +318,7 @@
}
/* XXX: Callers do not check for failure. */
- if (dest + stage_offset + len > staging_end) {
+ if (!efi_check_space(dest + stage_offset + len)) {
errno = ENOMEM;
return (-1);
}
@@ -283,7 +344,7 @@
efi_readin(const int fd, vm_offset_t dest, const size_t len)
{
- if (dest + stage_offset + len > staging_end) {
+ if (!efi_check_space(dest + stage_offset + len)) {
errno = ENOMEM;
return (-1);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 24, 8:55 PM (20 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16103093
Default Alt Text
D22569.id64937.diff (2 KB)
Attached To
Mode
D22569: Add support to allocate more space before and after a current allocation
Attached
Detach File
Event Timeline
Log In to Comment