From 3cd3b7029b173adad495931021ef1fa8846e57ad Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Sat, 23 Jan 2021 18:46:47 -0600 Subject: [PATCH] boot/efi/devices: Use aligned readBuffer for blockio access * Media->IoAlign dictates a memory alignment for block device read buffers. If this alignment fails, sanity checks within EFI bioses can prevent us from properly parsing filesystems via failed BlockIO ReadBlocks calls. * Use a static alignment of a sane 2048 which should meet most alignment requirements * Resolves RISCV64 not finding boot partitions. (and likely fixes a similar issue on ARM) Suggested-by: Heinrich Schuchardt Change-Id: I718511e8630a109414d90d0bae1470cc861a614f Reviewed-on: https://review.haiku-os.org/c/haiku/+/3676 Reviewed-by: Adrien Destugues Reviewed-by: Fredrik Holmqvist --- src/system/boot/platform/efi/devices.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/system/boot/platform/efi/devices.cpp b/src/system/boot/platform/efi/devices.cpp index 690a6a7858..c01ae1d861 100644 --- a/src/system/boot/platform/efi/devices.cpp +++ b/src/system/boot/platform/efi/devices.cpp @@ -64,12 +64,19 @@ EfiDevice::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) off_t offset = pos % BlockSize(); pos /= BlockSize(); - uint32 numBlocks = (offset + bufferSize + BlockSize()) / BlockSize(); - char readBuffer[numBlocks * BlockSize()]; + uint32 numBlocks = (offset + bufferSize + BlockSize() - 1) / BlockSize(); + + // TODO: We really should implement memalign and align all requests to + // fBlockIo->Media->IoAlign. This static alignment is large enough though + // to catch most required alignments. + char readBuffer[numBlocks * BlockSize()] + __attribute__((aligned(2048))); if (fBlockIo->ReadBlocks(fBlockIo, fBlockIo->Media->MediaId, - pos, sizeof(readBuffer), readBuffer) != EFI_SUCCESS) + pos, sizeof(readBuffer), readBuffer) != EFI_SUCCESS) { + dprintf("%s: blockIo error reading from device!\n", __func__); return B_ERROR; + } memcpy(buffer, readBuffer + offset, bufferSize); @@ -145,7 +152,7 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) panic("Cannot get block device handle!"); TRACE("%s: %p: present: %s, logical: %s, removeable: %s, " - "blocksize: %" B_PRIuSIZE ", lastblock: %" B_PRIu64 "\n", + "blocksize: %" B_PRIu32 ", lastblock: %" B_PRIu64 "\n", __func__, blockIo, blockIo->Media->MediaPresent ? "true" : "false", blockIo->Media->LogicalPartition ? "true" : "false",