[PATCH 1/1] efi_loader: correct EFI_BLOCK_IO_PROTOCOL.Media.LastBlock
Heinrich Schuchardt
xypron.glpk at gmx.de
Sat Jan 23 07:42:23 CET 2021
The field Media.LastBlock of the EFI_BLOCK_IO_PROTOCOL.Media was filled
incorrectly both for block devices as well as for partitions.
The field must be filled with the index of the last logical block (LBA):
* block devices: device size minus 1
* partitions: partition size minus 1
Reported-by: Alexander von Gluck IV <kallisti5 at unixzen.com>
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
lib/efi_loader/efi_disk.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 26b953461b..c0804effde 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -343,7 +343,7 @@ static int efi_fs_exists(struct blk_desc *desc, int part)
* @if_typename: interface name for block device
* @desc: internal block device
* @dev_index: device index for block device
- * @offset: offset into disk for simple partitions
+ * @part_info: partition info
* @part: partition
* @disk: pointer to receive the created handle
* Return: disk object
@@ -354,7 +354,7 @@ static efi_status_t efi_disk_add_dev(
const char *if_typename,
struct blk_desc *desc,
int dev_index,
- lbaint_t offset,
+ struct disk_partition *part_info,
unsigned int part,
struct efi_disk_obj **disk)
{
@@ -374,7 +374,7 @@ static efi_status_t efi_disk_add_dev(
efi_add_handle(&diskobj->header);
/* Fill in object data */
- if (part) {
+ if (part_info) {
struct efi_device_path *node = efi_dp_part_node(desc, part);
struct efi_handler *handler;
void *protocol_interface;
@@ -396,8 +396,12 @@ static efi_status_t efi_disk_add_dev(
diskobj->dp = efi_dp_append_node(dp_parent, node);
efi_free_pool(node);
+ diskobj->offset = part_info->start;
+ diskobj->media.last_block = part_info->size - 1;
} else {
diskobj->dp = efi_dp_from_part(desc, part);
+ diskobj->offset = 0;
+ diskobj->media.last_block = desc->lba - 1;
}
diskobj->part = part;
@@ -432,7 +436,6 @@ static efi_status_t efi_disk_add_dev(
diskobj->ops = block_io_disk_template;
diskobj->ifname = if_typename;
diskobj->dev_index = dev_index;
- diskobj->offset = offset;
diskobj->desc = desc;
/* Fill in EFI IO Media info (for read/write callbacks) */
@@ -445,13 +448,21 @@ static efi_status_t efi_disk_add_dev(
diskobj->media.media_id = 1;
diskobj->media.block_size = desc->blksz;
diskobj->media.io_align = desc->blksz;
- diskobj->media.last_block = desc->lba - offset;
if (part)
diskobj->media.logical_partition = 1;
diskobj->ops.media = &diskobj->media;
if (disk)
*disk = diskobj;
+ EFI_PRINT("BlockIO: part %u, present %d, logical %d, removable %d"
+ ", offset " LBAF ", last_block %llu\n",
+ diskobj->part,
+ diskobj->media.media_present,
+ diskobj->media.logical_partition,
+ diskobj->media.removable_media,
+ diskobj->offset,
+ diskobj->media.last_block);
+
/* Store first EFI system partition */
if (part && !efi_system_partition.if_type) {
int r;
@@ -493,7 +504,6 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
{
int disks = 0;
char devname[32] = { 0 }; /* dp->str is u16[32] long */
- struct disk_partition info;
int part;
struct efi_device_path *dp = NULL;
efi_status_t ret;
@@ -506,12 +516,14 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
/* Add devices for each partition */
for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
+ struct disk_partition info;
+
if (part_get_info(desc, part, &info))
continue;
snprintf(devname, sizeof(devname), "%s:%d", pdevname,
part);
ret = efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
- info.start, part, NULL);
+ &info, part, NULL);
if (ret != EFI_SUCCESS) {
log_err("Adding partition %s failed\n", pdevname);
continue;
@@ -553,7 +565,7 @@ efi_status_t efi_disk_register(void)
/* Add block device for the full device */
log_info("Scanning disk %s...\n", dev->name);
ret = efi_disk_add_dev(NULL, NULL, if_typename,
- desc, desc->devnum, 0, 0, &disk);
+ desc, desc->devnum, NULL, 0, &disk);
if (ret == EFI_NOT_READY) {
log_notice("Disk %s not ready\n", dev->name);
continue;
@@ -599,7 +611,7 @@ efi_status_t efi_disk_register(void)
/* Add block device for the full device */
ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
- i, 0, 0, &disk);
+ i, NULL, 0, &disk);
if (ret == EFI_NOT_READY) {
log_notice("Disk %s not ready\n", devname);
continue;
--
2.29.2
More information about the U-Boot
mailing list