From: Artur Kowalski Date: Thu, 29 Jan 2026 17:42:24 +0000 (+0100) Subject: boot: introduce xmalloc_aligned_pages X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd7c6d1ac1deac4ea76b9f7e7db69ce30b360cbd;p=thirdparty%2Fsystemd.git boot: introduce xmalloc_aligned_pages To be used for block I/O which may require specific buffer alignment. --- diff --git a/src/boot/util.c b/src/boot/util.c index 63bf21ae50f..4a4c4e93650 100644 --- a/src/boot/util.c +++ b/src/boot/util.c @@ -517,6 +517,51 @@ void *xmalloc(size_t size) { return p; } +Pages xmalloc_aligned_pages( + EFI_ALLOCATE_TYPE type, + EFI_MEMORY_TYPE memory_type, + size_t n_pages, + size_t alignment, + EFI_PHYSICAL_ADDRESS addr) { + + EFI_PHYSICAL_ADDRESS aligned = addr; + + /* Allow to pass block_io->Media->IoAlign to this function directly. + * alignment <= 1 means no alignment is required, in that case just + * allocate pages directly. + */ + if (alignment <= 1) + alignment = EFI_PAGE_SIZE; + + assert(ISPOWEROF2(alignment)); + + if (alignment <= EFI_PAGE_SIZE) { + assert_se(BS->AllocatePages(type, memory_type, n_pages, &aligned) == EFI_SUCCESS); + return (Pages) { + .addr = aligned, + .n_pages = n_pages, + }; + } + + size_t total_pages = n_pages + EFI_SIZE_TO_PAGES(alignment); + assert_se(BS->AllocatePages(type, memory_type, total_pages, &addr) == EFI_SUCCESS); + + aligned = ALIGN_TO(addr, alignment); + size_t unaligned_pages = EFI_SIZE_TO_PAGES(aligned - addr); + if (unaligned_pages > 0) + assert_se(BS->FreePages(addr, unaligned_pages) == EFI_SUCCESS); + + addr = aligned + n_pages * EFI_PAGE_SIZE; + unaligned_pages = total_pages - n_pages - unaligned_pages; + if (unaligned_pages > 0) + assert_se(BS->FreePages(addr, unaligned_pages) == EFI_SUCCESS); + + return (Pages) { + .addr = aligned, + .n_pages = n_pages, + }; +} + bool free_and_xstrdup16(char16_t **p, const char16_t *s) { char16_t *t; diff --git a/src/boot/util.h b/src/boot/util.h index 59f61c6c39e..2c8cc36ea58 100644 --- a/src/boot/util.h +++ b/src/boot/util.h @@ -96,6 +96,13 @@ static inline Pages xmalloc_pages( }; } +Pages xmalloc_aligned_pages( + EFI_ALLOCATE_TYPE type, + EFI_MEMORY_TYPE memory_type, + size_t n_pages, + size_t alignment, + EFI_PHYSICAL_ADDRESS addr); + static inline Pages xmalloc_initrd_pages(size_t n_pages) { /* The original native x86 boot protocol of the Linux kernel was not 64bit safe, hence we try to * allocate memory for the initrds below the 4G boundary on x86, since we don't know early enough