From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.151; helo=mga17.intel.com; envelope-from=jiewen.yao@intel.com; receiver=edk2-devel@lists.01.org Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) (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 0730A21295C89 for ; Tue, 12 Jun 2018 08:23:36 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Jun 2018 08:23:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,215,1526367600"; d="scan'208";a="48743702" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by orsmga008.jf.intel.com with ESMTP; 12 Jun 2018 08:23:26 -0700 Received: from fmsmsx111.amr.corp.intel.com (10.18.116.5) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.319.2; Tue, 12 Jun 2018 08:23:25 -0700 Received: from shsmsx151.ccr.corp.intel.com (10.239.6.50) by fmsmsx111.amr.corp.intel.com (10.18.116.5) with Microsoft SMTP Server (TLS) id 14.3.319.2; Tue, 12 Jun 2018 08:23:24 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.223]) by SHSMSX151.ccr.corp.intel.com ([169.254.3.116]) with mapi id 14.03.0319.002; Tue, 12 Jun 2018 23:23:20 +0800 From: "Yao, Jiewen" To: Ard Biesheuvel , "edk2-devel@lists.01.org" CC: "leif.lindholm@linaro.org" , "Zeng, Star" , "Kinney, Michael D" Thread-Topic: [PATCH v3 1/4] MdeModulePkg/CapsuleRuntimeDxe: clean the capsule payload to DRAM Thread-Index: AQHUAj/UQY0xRA7lp0SG4/6j8D4tbKRcvOrw Date: Tue, 12 Jun 2018 15:23:20 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503AC40191@shsmsx102.ccr.corp.intel.com> References: <20180612112329.664-1-ard.biesheuvel@linaro.org> <20180612112329.664-2-ard.biesheuvel@linaro.org> In-Reply-To: <20180612112329.664-2-ard.biesheuvel@linaro.org> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMWVkMDdlZTAtMTA3Mi00OWE4LWI0NmYtMDdiZGNkZTJmYTIxIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiMXAzVWRJTVZvck9LT05teDhFRFdHTWFFUXEzb1NhK0lEcEdcL1U4dWtxVk5GS0VhalM1b0dcL0Ira2xTT2ROc2NZIn0= x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.200.100 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v3 1/4] MdeModulePkg/CapsuleRuntimeDxe: clean the capsule payload to DRAM X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jun 2018 15:23:37 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Ard Do you think we also need update QueryCapsuleCapabilities() to return UNSUP= PORTED for CAPSULE_FLAGS_PERSIST_ACROSS_RESET? Thank you Yao Jiewen > -----Original Message----- > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] > Sent: Tuesday, June 12, 2018 4:23 AM > To: edk2-devel@lists.01.org > Cc: leif.lindholm@linaro.org; Zeng, Star ; Yao, Jiew= en > ; Kinney, Michael D ; A= rd > Biesheuvel > Subject: [PATCH v3 1/4] MdeModulePkg/CapsuleRuntimeDxe: clean the capsule > payload to DRAM >=20 > When capsule updates are staged for processing after a warm reboot, > they are copied into memory with the MMU and caches enabled. When > the capsule PEI gets around to coalescing the capsule, the MMU and > caches may still be disabled, and so on architectures where uncached > accesses are incoherent with the caches (such as ARM and AARCH64), > we need to ensure that the data passed into UpdateCapsule() is > written back to main memory before performing the warm reboot. >=20 > Unfortunately, on ARM, the only type of cache maintenance instructions > that are suitable for this purpose operate on virtual addresses only, > and given that the UpdateCapsule() prototype includes the physical > address of a linked list of scatter/gather data structures that are > mapped at an address that is unknown to the firmware (and may not even > be mapped at all when UpdateCapsule() is invoked), we can only perform > this cache maintenance at boot time. Fortunately, both Windows and Linux > only invoke UpdateCapsule() before calling ExitBootServices(), so this > is not a problem in practice. >=20 > In the future, we may propose adding a secure firmware service that > permits performing the cache maintenance at OS runtime, in which case > this code may be enhanced to call that service if available. For now, > we just fail any UpdateCapsule() calls performed at OS runtime on ARM. >=20 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > --- > MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CacheMaintenance.c | 70 > ++++++++++++++++++++ > MdeModulePkg/Universal/CapsuleRuntimeDxe/CacheMaintenance.c | 39 > +++++++++++ > MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf | 13 > +++- > MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c | 24 > +++++++ > 4 files changed, 144 insertions(+), 2 deletions(-) >=20 > diff --git > a/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CacheMaintenance.c > b/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CacheMaintenance.c > new file mode 100644 > index 000000000000..dc05e345fb8d > --- /dev/null > +++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CacheMaintenance.c > @@ -0,0 +1,70 @@ > + /** @file > + Capsule cache maintenance as is required on ARM and AARCH64 > + > + Copyright (c) 2018, Linaro, Ltd. 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 th= is > + distribution. The full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#include > + > +#include > +#include > + > +/** > + Writes Back a range of data cache lines covering a set of capsules in = memory. > + > + Writes Back the data cache lines specified by ScatterGatherList. > + > + @param ScatterGatherList Physical address of the data structure that > + describes a set of capsules in memory > + > + @return EFI_SUCCESS if the operation succeeded. > + EFI_UNSUPPORTED if cache maintenance cannot be performed > at this > + time. > + > +**/ > +EFI_STATUS > +EFIAPI > +CapsuleCacheWriteBack ( > + IN EFI_PHYSICAL_ADDRESS ScatterGatherList > + ) > +{ > + EFI_CAPSULE_BLOCK_DESCRIPTOR *Desc; > + > + // > + // ARM requires the capsule payload to be cleaned to the point of cohe= rency > + // (PoC), but only permits doing so using cache maintenance instructio= ns that > + // operate on virtual addresses. Since at runtime, we don't know the v= irtual > + // addresses of the data structures that make up the scatter/gather li= st, we > + // cannot perform the maintenance, and all we can do is give up. > + // > + if (EfiAtRuntime ()) { > + return EFI_UNSUPPORTED; > + } > + > + Desc =3D (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)ScatterGatherList; > + do { > + WriteBackDataCacheRange (Desc, sizeof *Desc); > + > + if (Desc->Length > 0) { > + WriteBackDataCacheRange ((VOID *)(UINTN)Desc->Union.DataBlock, > + Desc->Length > + ); > + Desc++; > + } else if (Desc->Union.ContinuationPointer > 0) { > + Desc =3D (EFI_CAPSULE_BLOCK_DESCRIPTOR > *)(UINTN)Desc->Union.ContinuationPointer; > + } > + } while (Desc->Length > 0 || Desc->Union.ContinuationPointer > 0); > + > + WriteBackDataCacheRange (Desc, sizeof *Desc); > + > + return EFI_SUCCESS; > +} > diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CacheMaintenance.c > b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CacheMaintenance.c > new file mode 100644 > index 000000000000..fb7504bb3e1d > --- /dev/null > +++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CacheMaintenance.c > @@ -0,0 +1,39 @@ > +/** @file > + Create NULL function for capsule cache maintenance which is only neede= d > + on ARM and AARCH64 > + > + Copyright (c) 2018, Linaro, Ltd. 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 th= is > + distribution. The full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#include > + > +/** > + Writes Back a range of data cache lines covering a set of capsules in = memory. > + > + Writes Back the data cache lines specified by ScatterGatherList. > + > + @param ScatterGatherList Physical address of the data structure that > + describes a set of capsules in memory > + > + @return EFI_SUCCESS if the operation succeeded. > + EFI_UNSUPPORTED if cache maintenance cannot be performed > at this > + time. > + > +**/ > +EFI_STATUS > +EFIAPI > +CapsuleCacheWriteBack ( > + IN EFI_PHYSICAL_ADDRESS ScatterGatherList > + ) > +{ > + return EFI_SUCCESS; > +} > diff --git > a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf > b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf > index 9ab04ce1b301..3ceebc5d9646 100644 > --- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf > +++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf > @@ -27,17 +27,23 @@ [Defines] > # > # The following information is for reference only and not required by th= e build > tools. > # > -# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC ARM AARCH64 > # >=20 > [Sources] > CapsuleService.c >=20 > -[Sources.Ia32, Sources.IPF, Sources.EBC, Sources.ARM, Sources.AARCH64] > +[Sources.Ia32, Sources.IPF, Sources.EBC] > SaveLongModeContext.c > + CacheMaintenance.c >=20 > [Sources.X64] > X64/SaveLongModeContext.c > + CacheMaintenance.c > + > +[Sources.ARM, Sources.AARCH64] > + SaveLongModeContext.c > + Arm/CacheMaintenance.c >=20 > [Packages] > MdePkg/MdePkg.dec > @@ -59,6 +65,9 @@ [LibraryClasses.X64] > UefiLib > BaseMemoryLib >=20 > +[LibraryClasses.ARM, LibraryClasses.AARCH64] > + CacheMaintenanceLib > + > [Guids] > ## SOMETIMES_PRODUCES ## Variable:L"CapsuleUpdateData" # (Process > across reset capsule image) for capsule updated data > ## SOMETIMES_PRODUCES ## Variable:L"CapsuleLongModeBuffer" # > The long mode buffer used by IA32 Capsule PEIM to call X64 CapsuleCoalesc= e > code to handle >4GB capsule blocks > diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c > b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c > index 216798d1617e..ee8515adf62f 100644 > --- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c > +++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c > @@ -53,6 +53,25 @@ SaveLongModeContext ( > VOID > ); >=20 > +/** > + Writes Back a range of data cache lines covering a set of capsules in = memory. > + > + Writes Back the data cache lines specified by ScatterGatherList. > + > + @param ScatterGatherList Physical address of the data structure that > + describes a set of capsules in memory > + > + @return EFI_SUCCESS if the operation succeeded. > + EFI_UNSUPPORTED if cache maintenance cannot be performed > at this > + time. > + > +**/ > +EFI_STATUS > +EFIAPI > +CapsuleCacheWriteBack ( > + IN EFI_PHYSICAL_ADDRESS ScatterGatherList > + ); > + > /** > Passes capsules to the firmware with both virtual and physical mapping= . > Depending on the intended > consumption, the firmware may process the capsule immediately. If the > payload should persist > @@ -214,6 +233,11 @@ UpdateCapsule ( > ); > } >=20 > + Status =3D CapsuleCacheWriteBack (ScatterGatherList); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > // > // ScatterGatherList is only referenced if the capsules are defined to= persist > across > // system reset. Set its value into NV storage to let pre-boot driver = to pick it > up > -- > 2.17.1