From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=209.132.183.28; helo=mx1.redhat.com; envelope-from=lersek@redhat.com; receiver=edk2-devel@lists.01.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (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 E04AD211B736F for ; Tue, 15 Jan 2019 03:58:13 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6519E3D962; Tue, 15 Jan 2019 11:58:13 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-120-50.rdu2.redhat.com [10.10.120.50]) by smtp.corp.redhat.com (Postfix) with ESMTP id D6319101962A; Tue, 15 Jan 2019 11:58:11 +0000 (UTC) To: Gary Lin , edk2-devel@lists.01.org Cc: Ruiyu Ni , Hao Wu , Star Zeng References: <20190115094548.10214-1-glin@suse.com> From: Laszlo Ersek Message-ID: <9497b88c-7025-e3bc-8f69-0a20a550930a@redhat.com> Date: Tue, 15 Jan 2019 12:58:10 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <20190115094548.10214-1-glin@suse.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 15 Jan 2019 11:58:13 +0000 (UTC) Subject: Re: [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 11:58:14 -0000 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit On 01/15/19 10:45, Gary Lin wrote: > 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) How does edk2 recognize the nested partition md0p1 in the first place? I would assume that the "outer" partitions (sda1, sdb1) start with some kind of MD RAID1 header that allows Linux to combine sda1 and sdb1 into md0p1. How does edk2 get past that header? Hmmm... based on , does Linux use "footers" instead of "headers"? Thanks, Laszlo > > 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; > } > > /** >