From nobody Wed Dec 25 14:14:13 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1509087292480607.0576107030528; Thu, 26 Oct 2017 23:54:52 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 98F022034A89A; Thu, 26 Oct 2017 23:51:00 -0700 (PDT) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (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 ED98821CEB149 for ; Thu, 26 Oct 2017 23:50:58 -0700 (PDT) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Oct 2017 23:54:45 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.7]) by orsmga003.jf.intel.com with ESMTP; 26 Oct 2017 23:54:44 -0700 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.88; helo=mga01.intel.com; envelope-from=ruiyu.ni@intel.com; receiver=edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,303,1505804400"; d="scan'208";a="1030015311" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Fri, 27 Oct 2017 14:54:38 +0800 Message-Id: <20171027065438.284440-4-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.12.2.windows.2 In-Reply-To: <20171027065438.284440-1-ruiyu.ni@intel.com> References: <20171027065438.284440-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 3/3] MdeModulePkg/PciBus: Fix bug that doesn't produce BusOverride X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" It's a regression of below commit: SHA-1: 8be37a5cee700777ca8e8e8a34cc2225b21931a7 * MdeModulePkg/SecurityStubDxe: Defer 3rd party image before EndOfDxe When PciBus driver fails to load the Option ROM, it doesn't produce BusOverride protocol. It was a correct behavior before the above commit. But due to the above commit, BusOverride protocol never is produced by PciBus driver. The patch fixes this issue using the following solution: 1. PciBus records the image device path when LoadImage fails. 2. Override.GetDriver() tries to look for the image handle using the stored image device path. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ruiyu Ni Reviewed-by: Star Zeng --- MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 3 +- MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c | 147 ++++++++++++++---= ---- MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h | 17 ++- .../Bus/Pci/PciBusDxe/PciOptionRomSupport.c | 17 ++- MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c | 2 +- 5 files changed, 124 insertions(+), 62 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bu= s/Pci/PciBusDxe/PciBusDxe.inf index 5da094f582..97608bfcf2 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf @@ -2,7 +2,7 @@ # The PCI bus driver will probe all PCI devices and allocate MMIO and IO = space for these devices. # Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable hot= plug supporting. # -# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the B= SD License @@ -96,6 +96,7 @@ [Protocols] gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES gEdkiiIoMmuProtocolGuid ## SOMETIMES_CONSUMES + gEfiLoadedImageDevicePathProtocolGuid ## CONSUMES =20 [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CON= SUMES diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c b/MdeModule= Pkg/Bus/Pci/PciBusDxe/PciDriverOverride.c index 97f45e42d0..e8fae17e8b 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c @@ -1,7 +1,7 @@ /** @file Functions implementation for Bus Specific Driver Override protoocl. =20 -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD = License which accompanies this distribution. The full text of the license may be = found at @@ -28,6 +28,56 @@ InitializePciDriverOverrideInstance ( PciIoDevice->PciDriverOverride.GetDriver =3D GetDriver; } =20 +/** + Find the image handle whose path equals to ImagePath. + + @param ImagePath Image path. + + @return Image handle. +**/ +EFI_HANDLE +LocateImageHandle ( + IN EFI_DEVICE_PATH_PROTOCOL *ImagePath + ) +{ + EFI_STATUS Status; + EFI_HANDLE *Handles; + UINTN Index; + UINTN HandleNum; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN ImagePathSize; + EFI_HANDLE ImageHandle; + + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiLoadedImageDevicePathProtocolGuid, + NULL, + &HandleNum, + &Handles + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + ImageHandle =3D NULL; + ImagePathSize =3D GetDevicePathSize (ImagePath); + + for (Index =3D 0; Index < HandleNum; Index++) { + Status =3D gBS->HandleProtocol (Handles[Index], &gEfiLoadedImageDevice= PathProtocolGuid, (VOID **) &DevicePath); + if (EFI_ERROR (Status)) { + continue; + } + if ((ImagePathSize =3D=3D GetDevicePathSize (DevicePath)) && + (CompareMem (ImagePath, DevicePath, ImagePathSize) =3D=3D 0) + ) { + ImageHandle =3D Handles[Index]; + break; + } + } + + FreePool (Handles); + return ImageHandle; +} =20 /** Uses a bus specific algorithm to retrieve a driver image handle for a co= ntroller. @@ -53,49 +103,60 @@ GetDriver ( ) { PCI_IO_DEVICE *PciIoDevice; - LIST_ENTRY *CurrentLink; - PCI_DRIVER_OVERRIDE_LIST *Node; + LIST_ENTRY *Link; + PCI_DRIVER_OVERRIDE_LIST *Override; + BOOLEAN ReturnNext; =20 + Override =3D NULL; PciIoDevice =3D PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This); + ReturnNext =3D (BOOLEAN) (*DriverImageHandle =3D=3D NULL); + for ( Link =3D GetFirstNode (&PciIoDevice->OptionRomDriverList) + ; !IsNull (&PciIoDevice->OptionRomDriverList, Link) + ; Link =3D GetNextNode (&PciIoDevice->OptionRomDriverList, Link) + ) { =20 - CurrentLink =3D PciIoDevice->OptionRomDriverList.ForwardLink; - - while (CurrentLink !=3D NULL && CurrentLink !=3D &PciIoDevice->OptionRom= DriverList) { - - Node =3D DRIVER_OVERRIDE_FROM_LINK (CurrentLink); - - if (*DriverImageHandle =3D=3D NULL) { + Override =3D DRIVER_OVERRIDE_FROM_LINK (Link); =20 - *DriverImageHandle =3D Node->DriverImageHandle; - return EFI_SUCCESS; - } - - if (*DriverImageHandle =3D=3D Node->DriverImageHandle) { - - if (CurrentLink->ForwardLink =3D=3D &PciIoDevice->OptionRomDriverLis= t || - CurrentLink->ForwardLink =3D=3D NULL) { - return EFI_NOT_FOUND; + if (ReturnNext) { + if (Override->DriverImageHandle =3D=3D NULL) { + Override->DriverImageHandle =3D LocateImageHandle (Override->Drive= rImagePath); } =20 - // - // Get next node - // - Node =3D DRIVER_OVERRIDE_FROM_LINK (CurrentLink->Forw= ardLink); - *DriverImageHandle =3D Node->DriverImageHandle; - return EFI_SUCCESS; + if (Override->DriverImageHandle =3D=3D NULL) { + // + // The Option ROM identified by Override->DriverImagePath is not l= oaded. + // + continue; + } else { + *DriverImageHandle =3D Override->DriverImageHandle; + return EFI_SUCCESS; + } } =20 - CurrentLink =3D CurrentLink->ForwardLink; + if (*DriverImageHandle =3D=3D Override->DriverImageHandle) { + ReturnNext =3D TRUE; + } } =20 - return EFI_INVALID_PARAMETER; + ASSERT (IsNull (&PciIoDevice->OptionRomDriverList, Link)); + // + // ReturnNext indicates a handle match happens. + // If all nodes are checked without handle match happening, + // the DriverImageHandle should be a invalid handle. + // + if (ReturnNext) { + return EFI_NOT_FOUND; + } else { + return EFI_INVALID_PARAMETER; + } } =20 /** Add an overriding driver image. =20 @param PciIoDevice Instance of PciIo device. - @param DriverImageHandle new added driver image. + @param DriverImageHandle Image handle of newly added driver image. + @param DriverImagePath Device path of newly added driver image. =20 @retval EFI_SUCCESS Successfully added driver. @retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance. @@ -104,40 +165,30 @@ GetDriver ( **/ EFI_STATUS AddDriver ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_HANDLE DriverImageHandle + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_HANDLE DriverImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath ) { - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; PCI_DRIVER_OVERRIDE_LIST *Node; =20 - Status =3D gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProto= colGuid, (VOID **) &LoadedImage); - if (EFI_ERROR (Status)) { - return Status; - } + // + // Caller should pass in either Image Handle or Image Path, but not both. + // + ASSERT ((DriverImageHandle =3D=3D NULL) || (DriverImagePath =3D=3D NULL)= ); =20 - Node =3D AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST)); + Node =3D AllocateZeroPool (sizeof (PCI_DRIVER_OVERRIDE_LIST)); if (Node =3D=3D NULL) { return EFI_OUT_OF_RESOURCES; } =20 Node->Signature =3D DRIVER_OVERRIDE_SIGNATURE; Node->DriverImageHandle =3D DriverImageHandle; + Node->DriverImagePath =3D DuplicateDevicePath (DriverImagePath); =20 - InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link)); + InsertTailList (&PciIoDevice->OptionRomDriverList, &Node->Link); =20 PciIoDevice->BusOverride =3D TRUE; - - ImageContext.Handle =3D LoadedImage->ImageBase; - ImageContext.ImageRead =3D PeCoffLoaderImageReadFromMemory; - - // - // Get information about the image - // - PeCoffLoaderGetImageInfo (&ImageContext); - return EFI_SUCCESS; } =20 diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h b/MdeModule= Pkg/Bus/Pci/PciBusDxe/PciDriverOverride.h index bf8efff8f1..f0679c51ec 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h @@ -1,7 +1,7 @@ /** @file Functions declaration for Bus Specific Driver Override protoocl. =20 -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD = License which accompanies this distribution. The full text of the license may be = found at @@ -22,9 +22,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHE= R EXPRESS OR IMPLIED. // PCI driver override driver image list // typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_HANDLE DriverImageHandle; + UINT32 Signature; + LIST_ENTRY Link; + EFI_HANDLE DriverImageHandle; + EFI_DEVICE_PATH_PROTOCOL *DriverImagePath; } PCI_DRIVER_OVERRIDE_LIST; =20 =20 @@ -46,7 +47,8 @@ InitializePciDriverOverrideInstance ( Add an overriding driver image. =20 @param PciIoDevice Instance of PciIo device. - @param DriverImageHandle new added driver image. + @param DriverImageHandle Image handle of newly added driver image. + @param DriverImagePath Device path of newly added driver image. =20 @retval EFI_SUCCESS Successfully added driver. @retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance. @@ -55,8 +57,9 @@ InitializePciDriverOverrideInstance ( **/ EFI_STATUS AddDriver ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_HANDLE DriverImageHandle + IN PCI_IO_DEVICE *PciIoDevice, + IN EFI_HANDLE DriverImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath ); =20 =20 diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c b/MdeModu= lePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c index 4382d79c2d..d390bb655a 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c @@ -753,13 +753,19 @@ ProcessOpRomImage ( BufferSize, &ImageHandle ); - - FreePool (PciOptionRomImageDevicePath); - - if (!EFI_ERROR (Status)) { + if (EFI_ERROR (Status)) { + // + // Record the Option ROM Image device path when LoadImage fails. + // PciOverride.GetDriver() will try to look for the Image Handle usi= ng the device path later. + // + AddDriver (PciDevice, NULL, PciOptionRomImageDevicePath); + } else { Status =3D gBS->StartImage (ImageHandle, NULL, NULL); if (!EFI_ERROR (Status)) { - AddDriver (PciDevice, ImageHandle); + // + // Record the Option ROM Image Handle + // + AddDriver (PciDevice, ImageHandle, NULL); PciRomAddImageMapping ( ImageHandle, PciDevice->PciRootBridgeIo->SegmentNumber, @@ -772,6 +778,7 @@ ProcessOpRomImage ( RetStatus =3D EFI_SUCCESS; } } + FreePool (PciOptionRomImageDevicePath); =20 NextImage: RomBarOffset +=3D ImageSize; diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c b/MdeModulePkg/Bu= s/Pci/PciBusDxe/PciRomTable.c index fc6f579293..aa7cfec232 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c @@ -129,7 +129,7 @@ PciRomGetImageMapping ( mRomImageTable[Index].Func =3D=3D PciIoDevice->FunctionNumber )= { =20 if (mRomImageTable[Index].ImageHandle !=3D NULL) { - AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle); + AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle, NULL); } PciIoDevice->PciIo.RomImage =3D mRomImageTable[Index].RomImage; PciIoDevice->PciIo.RomSize =3D mRomImageTable[Index].RomSize; --=20 2.12.2.windows.2 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel