Skip to content

Commit 2b20a7c

Browse files
committed
malloc: efi_malloc: refactor to use the efi malloc with tlsf malloc
1 parent daa14a4 commit 2b20a7c

6 files changed

Lines changed: 57 additions & 95 deletions

File tree

arch/arm/configs/efi_v8_defconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,5 +264,4 @@ CONFIG_LZO_DECOMPRESS=y
264264
CONFIG_DIGEST_SHA1_ARM64_CE=y
265265
CONFIG_DIGEST_SHA256_ARM64_CE=y
266266
CONFIG_MALLOC_EFI=y
267-
# CONFIG_MALLOC_TLSF is not set
268267
# CONFIG_MISSING_FIRMWARE_ERROR is not set

common/Kconfig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -317,20 +317,20 @@ config EXPERIMENTAL
317317
bool
318318
prompt "Prompt for experimental code"
319319

320+
config MALLOC_EFI
321+
bool "efi malloc"
322+
depends on EFI_PAYLOAD
323+
help
324+
select this option to use a efi malloc implementation. With this
325+
This is suitable for efi payload.
326+
320327
choice
321328
prompt "malloc implementation"
322329
default MALLOC_TLSF
323330

324331
config MALLOC_TLSF
325332
bool "tlsf"
326333

327-
config MALLOC_EFI
328-
bool "efi malloc"
329-
depends on EFI_PAYLOAD
330-
help
331-
select this option to use a efi malloc implementation. With this
332-
This is suitable for efi payload.
333-
334334
config MALLOC_DUMMY
335335
bool "dummy malloc"
336336
depends on SHELL_NONE

common/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ obj-$(CONFIG_KALLSYMS) += kallsyms.o
5353
obj-$(CONFIG_MALLOC_TLSF) += tlsf_malloc.o tlsf.o calloc.o
5454
KASAN_SANITIZE_tlsf.o := n
5555
obj-$(CONFIG_MALLOC_DUMMY) += dummy_malloc.o calloc.o
56+
obj-$(CONFIG_MALLOC_EFI) += efi_malloc.o
5657
obj-y += malloc.o
5758
obj-$(CONFIG_MEMINFO) += meminfo.o
5859
obj-$(CONFIG_MENU) += menu.o

common/efi_malloc.c

Lines changed: 19 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -12,135 +12,69 @@
1212

1313
struct alloc_header {
1414
size_t size; /* requested size */
15-
int from_efi; /* 0 = memalign, 1 = EFI pages */
1615
};
1716

18-
void malloc_stats(void)
19-
{
20-
/* optional: implement stats if needed */
21-
}
22-
23-
static void *efi_malloc(size_t size) {
17+
void *efi_malloc(size_t size) {
2418
efi_status_t efiret;
2519
efi_physical_addr_t mem;
26-
size_t pages = DIV_ROUND_UP(size, EFI_PAGE_SIZE);
20+
struct alloc_header *hdr;
21+
size_t pages;
22+
23+
if (!size)
24+
return ZERO_SIZE_PTR;
2725

26+
pages= DIV_ROUND_UP(size, EFI_PAGE_SIZE);
2827
efiret = BS->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
2928
EFI_LOADER_DATA, pages, &mem);
3029
if (EFI_ERROR(efiret)) {
3130
errno = efi_errno(efiret);
3231
return NULL;
3332
}
3433

35-
return efi_phys_to_virt(mem);
36-
}
37-
38-
static void efi_free(void *ptr, size_t size) {
39-
efi_physical_addr_t phys = efi_virt_to_phys(ptr);
40-
size_t pages = DIV_ROUND_UP(size, EFI_PAGE_SIZE);
41-
BS->free_pages(phys, pages);
42-
}
43-
44-
void *memalign(size_t alignment, size_t bytes)
45-
{
46-
void *mem = NULL;
47-
48-
if (!bytes)
49-
return ZERO_SIZE_PTR;
50-
51-
if (alignment <= MALLOC_MAX_SIZE && bytes <= MALLOC_MAX_SIZE)
52-
mem = sbrk(bytes + alignment);
53-
if (!mem) {
54-
errno = ENOMEM;
55-
return NULL;
56-
}
57-
58-
return PTR_ALIGN(mem, alignment);
59-
}
60-
61-
void *malloc(size_t size)
62-
{
63-
struct alloc_header *hdr;
64-
void *mem;
65-
66-
if (!size)
67-
return ZERO_SIZE_PTR;
68-
69-
/* if asked size is bigger than 1MB allocate from efi*/
70-
if (size >= SZ_1M)
71-
goto efi_alloc;
72-
73-
/* try memalign first, to use boot service memory */
74-
mem = memalign(CONFIG_MALLOC_ALIGNMENT, size + sizeof(*hdr));
75-
if (mem && !errno) {
76-
hdr = (struct alloc_header *)mem;
77-
hdr->from_efi = 0;
78-
goto return_ptr;
79-
}
80-
81-
efi_alloc:
82-
/* if no memory left from boot services fallback here*/
83-
mem = efi_malloc(size + sizeof(*hdr));
84-
if (!mem)
85-
return NULL;
86-
87-
hdr = (struct alloc_header *)mem;
88-
hdr->from_efi = 1;
89-
90-
return_ptr:
34+
hdr = (struct alloc_header *)efi_phys_to_virt(mem);
9135
hdr->size = size;
9236
return (void *)(hdr + 1);
9337
}
9438

95-
void free(void *ptr)
96-
{
39+
void efi_free(void *ptr) {
40+
efi_physical_addr_t phys;
9741
struct alloc_header *hdr;
9842

9943
if (!ptr)
10044
return;
101-
45+
10246
hdr = (struct alloc_header *)ptr - 1;
47+
phys = efi_virt_to_phys(hdr);
10348

104-
if (hdr->from_efi)
105-
efi_free(hdr, hdr->size + sizeof(*hdr));
106-
}
107-
108-
size_t malloc_usable_size(void *mem)
109-
{
110-
struct alloc_header *hdr;
111-
112-
if (!mem)
113-
return 0;
114-
115-
hdr = (struct alloc_header *)mem - 1;
116-
return hdr->size;
49+
size_t pages = DIV_ROUND_UP(hdr->size, EFI_PAGE_SIZE);
50+
BS->free_pages(phys, pages);
11751
}
11852

119-
void *realloc(void *ptr, size_t size)
53+
void *efi_realloc(void *ptr, size_t size)
12054
{
12155
struct alloc_header *hdr;
12256
void *n_mem;
12357
size_t old_sz;
12458

12559
if (!ptr)
126-
return malloc(size);
60+
return efi_malloc(size);
12761

12862
if (!size) {
129-
free(ptr);
63+
efi_free(ptr);
13064
return NULL;
13165
}
13266

13367
hdr = (struct alloc_header *)ptr - 1;
13468
old_sz = hdr->size;
13569

136-
n_mem = malloc(size);
70+
n_mem = efi_malloc(size);
13771
if (!n_mem) {
13872
errno = ENOMEM;
13973
return NULL;
14074
}
14175

14276
memcpy(n_mem, ptr, (old_sz < size) ? old_sz : size);
143-
free(ptr);
77+
efi_free(ptr);
14478

14579
return n_mem;
14680
}

common/tlsf_malloc.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*/
77

88
#include <malloc.h>
9+
#include <efi.h>
10+
#include <memory.h>
911
#include <string.h>
1012

1113
#include <stdio.h>
@@ -29,15 +31,28 @@ void *malloc(size_t bytes)
2931
void *mem;
3032

3133
mem = tlsf_malloc(tlsf_mem_pool, bytes);
32-
if (!mem)
34+
if (!mem) {
35+
if (IS_ENABLED(CONFIG_MALLOC_EFI)) {
36+
return efi_malloc(bytes);
37+
}
38+
3339
errno = ENOMEM;
40+
}
3441

3542
return mem;
3643
}
3744
EXPORT_SYMBOL(malloc);
3845

3946
void free(void *mem)
4047
{
48+
if (IS_ENABLED(CONFIG_MALLOC_EFI)) {
49+
if (efi_virt_to_phys(mem) < mem_malloc_start() &&
50+
efi_virt_to_phys(mem) > mem_malloc_end()) {
51+
efi_free(mem);
52+
return;
53+
}
54+
}
55+
4156
tlsf_free(tlsf_mem_pool, mem);
4257
}
4358
EXPORT_SYMBOL(free);
@@ -51,8 +66,12 @@ EXPORT_SYMBOL(malloc_usable_size);
5166
void *realloc(void *oldmem, size_t bytes)
5267
{
5368
void *mem = tlsf_realloc(tlsf_mem_pool, oldmem, bytes);
54-
if (!mem)
69+
if (!mem) {
70+
if (IS_ENABLED(CONFIG_MALLOC_EFI)) {
71+
return efi_realloc(oldmem, bytes);
72+
}
5573
errno = ENOMEM;
74+
}
5675

5776
return mem;
5877
}

include/malloc.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424
#ifdef CONFIG_MALLOC_TLSF
2525
void *malloc_add_pool(void *mem, size_t bytes);
2626
#endif
27+
void *efi_malloc(size_t size);
28+
void efi_free(void *ptr);
29+
void *efi_realloc(void *ptr, size_t size);
30+
#ifdef MALLOC_EFI
31+
static inline void *efi_malloc(size_t size) { return ERR_PTR(-ENOMEM); }
32+
static inline void efi_free(void *ptr) {}
33+
static inline void *efi_realloc(void *ptr, size_t size) { return ERR_PTR(-ENOMEM); }
34+
#else
35+
#endif
2736

2837
#if IN_PROPER
2938
void *malloc(size_t) __alloc_size(1);

0 commit comments

Comments
 (0)