Skip to content

Commit 5975202

Browse files
committed
EFI: add heap memory support
Signed-off-by: Stephan Mueller <smueller@chronox.de>
1 parent 0f9c220 commit 5975202

File tree

4 files changed

+102
-25
lines changed

4 files changed

+102
-25
lines changed

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,6 @@ implement the exact algorithms required.
130130
When programming with `leancrypto` in the EFI environment, the following
131131
considerations must be applied:
132132

133-
* Only stack support is currently provided. All memory allocations using heap
134-
will fail with `ENOMEM` as an appropriate implementation of `free` and
135-
`posix_memalign` is not available in `internal/api/ext_headers.h`. If you want
136-
heap support, feel free to provide patches for these functions.
137-
138133
* The API specified by the header files installed as part of the
139134
`meson install -C build` command for the user space library is applicable to
140135
the EFI environment as well.

internal/src/memory_support.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,6 @@ int posix_memalign(void **ptr, size_t align, size_t size)
5050
return 0;
5151
}
5252

53-
#elif defined(LC_EFI_ENVIRONMENT)
54-
55-
int posix_memalign(void **ptr, size_t align, size_t size);
56-
int posix_memalign(void **memptr, size_t alignment, size_t size)
57-
{
58-
(void)memptr;
59-
(void)alignment;
60-
(void)size;
61-
return ENOMEM;
62-
}
63-
64-
void free(void *ptr);
65-
void free(void *ptr)
66-
{
67-
(void)ptr;
68-
}
69-
70-
7153
#endif
7254

7355
LC_INTERFACE_FUNCTION(int, lc_alloc_aligned, void **memptr, size_t alignment,

internal/src/memory_support_efi.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright (C) 2024, Stephan Mueller <smueller@chronox.de>
3+
*
4+
* License: see LICENSE file in root directory
5+
*
6+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
7+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
9+
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
10+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
11+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
12+
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
13+
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
14+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
16+
* USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
17+
* DAMAGE.
18+
*/
19+
20+
#include "ext_headers.h"
21+
#include "lc_memory_support.h"
22+
#include "visibility.h"
23+
24+
#define LC_EFI_PAGESIZE 4096
25+
26+
/*
27+
* Implementation follows guidance outlined at
28+
* https://tianocore-docs.github.io/edk2-UefiDriverWritersGuide/draft/5_uefi_services/51_services_that_uefi_drivers_commonly_use/511_memory_allocation_services.html
29+
*/
30+
31+
LC_INTERFACE_FUNCTION(int, lc_alloc_aligned, void **memptr, size_t alignment,
32+
size_t size)
33+
{
34+
if (alignment > 8)
35+
return lc_alloc_high_aligned(memptr, alignment, size);
36+
37+
*memptr = AllocatePool(size);
38+
39+
if (!*memptr)
40+
return -ENOMEM;
41+
42+
return 0;
43+
}
44+
45+
LC_INTERFACE_FUNCTION(int, lc_alloc_aligned_secure, void **memptr,
46+
size_t alignment, size_t size)
47+
{
48+
return lc_alloc_aligned(memptr, alignment, size);
49+
}
50+
51+
LC_INTERFACE_FUNCTION(int, lc_alloc_high_aligned, void **memptr,
52+
size_t alignment, size_t size)
53+
{
54+
EFI_PHYSICAL_ADDRESS PhysicalBuffer = 0;
55+
EFI_STATUS efi_status;
56+
size_t pages = (size + LC_EFI_PAGESIZE - 1) / LC_EFI_PAGESIZE;
57+
58+
if (alignment > LC_EFI_PAGESIZE)
59+
return -ENOMEM;
60+
61+
#pragma GCC diagnostic push
62+
#pragma GCC diagnostic ignored "-Wpedantic"
63+
efi_status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages,
64+
EfiBootServicesData, pages,
65+
&PhysicalBuffer);
66+
#pragma GCC diagnostic pop
67+
if (EFI_ERROR(efi_status))
68+
return -ENOMEM;
69+
70+
*memptr = (VOID *)(UINTN)PhysicalBuffer;
71+
72+
return 0;
73+
}
74+
75+
LC_INTERFACE_FUNCTION(void, lc_free, void *ptr)
76+
{
77+
if (!ptr)
78+
return;
79+
FreePool(ptr);
80+
}
81+
82+
LC_INTERFACE_FUNCTION(void, lc_free_high_aligned, void *ptr, size_t size)
83+
{
84+
EFI_STATUS efi_status;
85+
EFI_PHYSICAL_ADDRESS PhysicalBuffer;
86+
size_t pages = (size + LC_EFI_PAGESIZE - 1) / LC_EFI_PAGESIZE;
87+
88+
if (!ptr)
89+
return;
90+
91+
PhysicalBuffer = (UINTN)ptr;
92+
93+
#pragma GCC diagnostic push
94+
#pragma GCC diagnostic ignored "-Wpedantic"
95+
efi_status = uefi_call_wrapper(BS->FreePages, 2, PhysicalBuffer, pages);
96+
#pragma GCC diagnostic pop
97+
98+
(void)efi_status;
99+
}

internal/src/meson.build

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ if get_option('efi').disabled()
1414
])
1515
endif
1616

17-
if (host_machine.system() == 'linux' and
18-
get_option('efi').disabled())
17+
if get_option('efi').enabled()
18+
internal_src += files([ 'memory_support_efi.c' ])
19+
elif host_machine.system() == 'linux'
1920
internal_src += files([ 'memory_support_linux.c' ])
2021
else
2122
internal_src += files([ 'memory_support.c' ])

0 commit comments

Comments
 (0)