From a3bdf33f3e46d37a2288faa0391e59ce65d430cb Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 30 May 2025 08:14:29 -0600 Subject: [PATCH] stand: Introduce md_align When we're loading metadata, we need to align it in a certain way. Right now that way is hard-coded to be PAGE_SIZE. Rather than do the actual physical thing in all these places, move this into a wrapper routine. We may want to load a 16k kernel and align all these on 16k or a 4k kernel and align on 4k on aarch64 (today you have to compile the loader with the right page size). This will also reduce the number of places we might have to touch to do that. Sponsored by: Netflix Reviewed by: tsoome, jhibbits Differential Revision: https://reviews.freebsd.org/D50585 --- stand/common/metadata.c | 8 ++++---- stand/common/modinfo.c | 22 ++++++++++++++++++++++ stand/common/modinfo.h | 1 + stand/efi/loader/bootinfo.c | 12 ++++++------ stand/i386/libi386/bootinfo32.c | 6 +++--- stand/i386/libi386/bootinfo64.c | 6 +++--- stand/userboot/userboot/bootinfo32.c | 6 +++--- stand/userboot/userboot/bootinfo64.c | 6 +++--- 8 files changed, 45 insertions(+), 22 deletions(-) diff --git a/stand/common/metadata.c b/stand/common/metadata.c index 715354aedd0..3b2ba3e4d79 100644 --- a/stand/common/metadata.c +++ b/stand/common/metadata.c @@ -123,14 +123,14 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) addr = xp->f_addr + xp->f_size; } /* Pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); /* Copy our environment */ envp = addr; addr = md_copyenv(addr); /* Pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); #if defined(LOADER_FDT_SUPPORT) /* Copy out FDT */ @@ -141,7 +141,7 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) { size = fdt_copy(addr); fdtp = addr; - addr = roundup(addr + size, PAGE_SIZE); + addr = md_align(addr + size); } #endif @@ -176,7 +176,7 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) *modulep = addr; size = md_copymodules(0, kern64); - kernend = roundup(addr + size, PAGE_SIZE); + kernend = md_align(addr + size); md = file_findmetadata(kfp, MODINFOMD_KERNEND); if (kern64) { diff --git a/stand/common/modinfo.c b/stand/common/modinfo.c index d00548c91c5..100f2c704d8 100644 --- a/stand/common/modinfo.c +++ b/stand/common/modinfo.c @@ -194,3 +194,25 @@ md_copyenv(vm_offset_t start) last = start; return(last); } + +/* + * Take the ending address and round it up to the currently required + * alignment. This typically is the page size, but is the larger of the compiled + * kernel page size, the loader page size, and the typical page size on the + * platform. + * + * XXX For the moment, it's just PAGE_SIZE to make the refactoring go faster, + * but needs to hook-in arch_loadaddr (or its replacement) functionality. + * + * Also, we may need other logical things when dealing with different types of + * page sizes and/or masking or sizes. This works well for addr and sizes, but + * not for masks. + * + * Also, this is different than the MOD_ALIGN macro above, which is used for + * aligning elements in the metadata lists, not for whare modules can begin. + */ +vm_offset_t +md_align(vm_offset_t addr) +{ + return (roundup(addr, PAGE_SIZE)); +} diff --git a/stand/common/modinfo.h b/stand/common/modinfo.h index d26129089fb..d613d8e27f1 100644 --- a/stand/common/modinfo.h +++ b/stand/common/modinfo.h @@ -16,5 +16,6 @@ int md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); vm_offset_t md_copymodules(vm_offset_t addr, bool kern64); vm_offset_t md_copyenv(vm_offset_t addr); +vm_offset_t md_align(vm_offset_t addr); #endif /* COMMON_MODINFO_H */ diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c index 75d75568665..b8f1a2ffd56 100644 --- a/stand/efi/loader/bootinfo.c +++ b/stand/efi/loader/bootinfo.c @@ -389,18 +389,18 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) } /* Pad to a page boundary. */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); #ifdef EFI addr = build_font_module(addr); /* Pad to a page boundary. */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); addr = build_splash_module(addr); /* Pad to a page boundary. */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); #endif /* Copy our environment. */ @@ -408,7 +408,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) addr = md_copyenv(addr); /* Pad to a page boundary. */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); #if defined(LOADER_FDT_SUPPORT) /* Handle device tree blob */ @@ -417,7 +417,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) /* Pad to a page boundary */ if (dtb_size) - addr += roundup(dtb_size, PAGE_SIZE); + addr += md_align(dtb_size); #endif kfp = file_findfile(NULL, md_kerntype); @@ -461,7 +461,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) #endif size = md_copymodules(0, is64); /* Find the size of the modules */ - kernend = roundup(addr + size, PAGE_SIZE); + kernend = md_align(addr + size); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ diff --git a/stand/i386/libi386/bootinfo32.c b/stand/i386/libi386/bootinfo32.c index 37b227b913b..6655e62f806 100644 --- a/stand/i386/libi386/bootinfo32.c +++ b/stand/i386/libi386/bootinfo32.c @@ -118,7 +118,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); addr = build_font_module(addr); @@ -127,7 +127,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t addr = md_copyenv(addr); /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) @@ -145,7 +145,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t /* Figure out the size and location of the metadata */ *modulep = addr; size = md_copymodules(0, false); - kernend = roundup(addr + size, PAGE_SIZE); + kernend = md_align(addr + size); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ diff --git a/stand/i386/libi386/bootinfo64.c b/stand/i386/libi386/bootinfo64.c index f7181dcd599..7d74a865ff4 100644 --- a/stand/i386/libi386/bootinfo64.c +++ b/stand/i386/libi386/bootinfo64.c @@ -136,7 +136,7 @@ bi_load64(char *args, vm_offset_t *modulep, addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); addr = build_font_module(addr); @@ -161,11 +161,11 @@ bi_load64(char *args, vm_offset_t *modulep, size = md_copymodules(0, true); /* copy our environment */ - envp = roundup(addr + size, PAGE_SIZE); + envp = md_align(addr + size); addr = md_copyenv(envp); /* set kernend */ - kernend = roundup(addr, PAGE_SIZE); + kernend = md_align(addr); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ diff --git a/stand/userboot/userboot/bootinfo32.c b/stand/userboot/userboot/bootinfo32.c index 75057491217..6ba76cc5647 100644 --- a/stand/userboot/userboot/bootinfo32.c +++ b/stand/userboot/userboot/bootinfo32.c @@ -99,14 +99,14 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); /* copy our environment */ envp = addr; addr = md_copyenv(addr); /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) @@ -123,7 +123,7 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t /* Figure out the size and location of the metadata */ *modulep = addr; size = md_copymodules(0, false); - kernend = roundup(addr + size, PAGE_SIZE); + kernend = md_align(addr + size); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ diff --git a/stand/userboot/userboot/bootinfo64.c b/stand/userboot/userboot/bootinfo64.c index d20202bf4fb..3e289bbebba 100644 --- a/stand/userboot/userboot/bootinfo64.c +++ b/stand/userboot/userboot/bootinfo64.c @@ -131,14 +131,14 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); /* copy our environment */ envp = addr; addr = md_copyenv(addr); /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + addr = md_align(addr); kfp = file_findfile(NULL, md_kerntype); if (kfp == NULL) @@ -152,7 +152,7 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) /* Figure out the size and location of the metadata */ *modulep = addr; size = md_copymodules(0, true); - kernend = roundup(addr + size, PAGE_SIZE); + kernend = md_align(addr + size); *kernendp = kernend; /* patch MODINFOMD_KERNEND */