From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=195.135.221.5; helo=smtp.nue.novell.com; envelope-from=glin@suse.com; receiver=edk2-devel@lists.01.org Received: from smtp.nue.novell.com (smtp.nue.novell.com [195.135.221.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id CE8B7211B63F0 for ; Tue, 15 Jan 2019 01:46:07 -0800 (PST) Received: from localhost.localdomain (unknown.telstraglobal.net [134.159.103.118]) by smtp.nue.novell.com with ESMTP (NOT encrypted); Tue, 15 Jan 2019 10:46:03 +0100 From: Gary Lin To: edk2-devel@lists.01.org Cc: Ruiyu Ni , Star Zeng , Jian J Wang , Hao Wu Date: Tue, 15 Jan 2019 17:45:48 +0800 Message-Id: <20190115094548.10214-1-glin@suse.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [PATCH] MdeModulePkg/UefiBootManagerLib: Match the nested partitions X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jan 2019 09:46:08 -0000 Content-Transfer-Encoding: 8bit In some cases, such as MD RAID1 in Linux, the bootloader may be in a nested EFI system partition partition. For example, sda1 and sdb1 are combined as md0 and the first partition of md0, md0p1, is an EFI system partition. Then, the bootloader can be located by the following device paths: PCI()/SATA(sda)/Partition(sda1)/Partition(md0p1)/File(bootloader.efi) PCI()/SATA(sdb)/Partition(sdb1)/Partition(md0p1)/File(bootloader.efi) To make the boot option more resilient, we may create a boot option with the short-form device path like "Partition(md0p1)/File(bootloader.efi)". However, BmMatchPartitionDevicePathNode() only matched the first partition node and ignored the nested partitions, so the firmware would refuse to load bootloader.efi since "Partition(md0p1)" doesn't match either "Partition(sda1)" or "Partition(sda2)". This commit modifies BmMatchPartitionDevicePathNode() to iterate all nested partitions so that the above boot option could work. Cc: Ruiyu Ni Cc: Star Zeng Cc: Jian J Wang Cc: Hao Wu Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Gary Lin --- .../Library/UefiBootManagerLib/BmBoot.c | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c index 6a23477eb873..8354c2af674b 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c @@ -1995,21 +1995,30 @@ BmMatchPartitionDevicePathNode ( return FALSE; } - // - // See if the harddrive device path in blockio matches the orig Hard Drive Node - // - Node = (HARDDRIVE_DEVICE_PATH *) BlockIoDevicePath; + do { + // + // See if the harddrive device path in blockio matches the orig Hard Drive Node + // + Node = (HARDDRIVE_DEVICE_PATH *) BlockIoDevicePath; - // - // Match Signature and PartitionNumber. - // Unused bytes in Signature are initiaized with zeros. - // - return (BOOLEAN) ( - (Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) && - (Node->MBRType == HardDriveDevicePath->MBRType) && - (Node->SignatureType == HardDriveDevicePath->SignatureType) && - (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0) - ); + // + // Match Signature and PartitionNumber. + // Unused bytes in Signature are initiaized with zeros. + // + if ((Node->PartitionNumber == HardDriveDevicePath->PartitionNumber) && + (Node->MBRType == HardDriveDevicePath->MBRType) && + (Node->SignatureType == HardDriveDevicePath->SignatureType) && + (CompareMem (Node->Signature, HardDriveDevicePath->Signature, sizeof (Node->Signature)) == 0)) { + return TRUE; + } + + // See if a nested partition exists + BlockIoDevicePath = NextDevicePathNode (BlockIoDevicePath); + } while (!IsDevicePathEnd (BlockIoDevicePath) && + (DevicePathType (BlockIoDevicePath) == MEDIA_DEVICE_PATH) && + (DevicePathSubType (BlockIoDevicePath) == MEDIA_HARDDRIVE_DP)); + + return FALSE; } /** -- 2.20.1