From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:4864:20::142; helo=mail-it1-x142.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-it1-x142.google.com (mail-it1-x142.google.com [IPv6:2607:f8b0:4864:20::142]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 6DC2321193595 for ; Tue, 20 Nov 2018 06:34:50 -0800 (PST) Received: by mail-it1-x142.google.com with SMTP id a185so3628046itc.0 for ; Tue, 20 Nov 2018 06:34:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=/UPlOoh81iQtgL1fg3UgMPm6Zb0DE+6Gfp7vcv8ecg4=; b=M9M8auBRMGr8MzP0wv5P4NfCNYkEHqEZS/psRtwM1Esvw4hec24dinrBEbtbmMCoyi ExusatS45N1noZNoBRZlDtBAYb2hlfuYhl7q8weo9rvgacP6yfJLta4NE2TCco2u0VmT X6JF+5H9WNd2dGhEJXUWunMvthJQj7lxd9W/o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=/UPlOoh81iQtgL1fg3UgMPm6Zb0DE+6Gfp7vcv8ecg4=; b=a2bOWsenRUcFQCKuFZjPKJVMtobckYs7cM+VxHdQDLPoZk3EWIiY5UOmbzcq03xNud gzmhy+Ok/U3b0Z8ozQYriHOyxuW9/PI1y8GCBHZUY9pkDiP8/JQCN00ZiDkKBN+rbC8S U4njR6cd/dSo8cdnyG+1dnkqFOCHqahunBUP5I3jSli/XhCA94pLt6BwictZqkEfR2yp khaS5E5Dbwhm/Ze25M+H37x8XGSN2Vt/ykSZkNkqbeaLRqtrgMf/hLJGHVmssBaKM25t ss4ms2cnsUv6vnO6u6hq9sYJ7DHSm39M1+Eq6YPyOx3WKKejN8iWFJI5kOaCYCmYPqHa yLiw== X-Gm-Message-State: AGRZ1gLiGgEd2QmDDjHoTeGsx8haGYfz8W4tXl/aJpmd2gZjbGgTjDCs W6RIRE4OM1ERz/PLJYQYfS/rJWnLmtMpbuCbD5riEl/Ww3Y= X-Google-Smtp-Source: AFSGD/UGPXlVw1HCB7I5wst0d1Lb82RMaY9iJFzKWJDtMbpo5w71SuFUVkqspwbD8+xIuZEPfeJJjbYSFQiK3BNCA6I= X-Received: by 2002:a24:710:: with SMTP id f16mr2070605itf.121.1542724489525; Tue, 20 Nov 2018 06:34:49 -0800 (PST) MIME-Version: 1.0 References: <20181120143300.26751-1-ard.biesheuvel@linaro.org> In-Reply-To: <20181120143300.26751-1-ard.biesheuvel@linaro.org> From: Ard Biesheuvel Date: Tue, 20 Nov 2018 15:34:38 +0100 Message-ID: To: "edk2-devel@lists.01.org" Subject: Re: [PATCH] ArmPkg/ArmSmcPsciResetSystemLib: add missing call to ExitBootServices() 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, 20 Nov 2018 14:34:50 -0000 Content-Type: text/plain; charset="UTF-8" On Tue, 20 Nov 2018 at 15:33, Ard Biesheuvel wrote: > > Our poor man's implementation of EnterS3WithImmediateWake () currently > sets a high TPL level to disable interrupts, and simply calls the > PEI entrypoint again after disabling the MMU. > > Unfortunately, this is not sufficient: DMA capable devices such as > network controllers or USB controllers may still be enabled and > writing to memory, e.g., in response to incoming network packets. > > So instead, do the full ExitBootServices() dance: allocate space and > get the memory map, call ExitBootServices(), and in case it fails, get > the memory map again and call ExitBootServices() again. This ensures > that all cleanup related to DMA capable devices is performed before > doing the warm reset. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > --- > ArmPkg/Include/Library/ArmLib.h | 1 + > ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c | 51 ++++++++++++++++++-- > 2 files changed, 49 insertions(+), 3 deletions(-) > > diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h > index e46df447b33d..ffda50e9d767 100644 > --- a/ArmPkg/Include/Library/ArmLib.h > +++ b/ArmPkg/Include/Library/ArmLib.h > @@ -59,6 +59,7 @@ typedef enum { > > typedef struct { > EFI_PHYSICAL_ADDRESS PhysicalBase; > + EFI_VIRTUAL_ADDRESS VirtualBase; > UINT64 Length; > ARM_MEMORY_REGION_ATTRIBUTES Attributes; > } ARM_MEMORY_REGION_DESCRIPTOR; This first hunk was included by accident - please disregard. > diff --git a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c b/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c > index 10ceafd14d5d..c9c42ab3b244 100644 > --- a/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c > +++ b/ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.c > @@ -1,7 +1,7 @@ > /** @file > ResetSystemLib implementation using PSCI calls > > - Copyright (c) 2017, Linaro Ltd. All rights reserved.
> + Copyright (c) 2017 - 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 > @@ -92,7 +92,13 @@ EnterS3WithImmediateWake ( > VOID > ) > { > - VOID (*Reset)(VOID); > + VOID (*Reset)(VOID); > + EFI_PHYSICAL_ADDRESS Alloc; > + EFI_MEMORY_DESCRIPTOR *MemMap; > + UINTN MemMapSize; > + UINTN MapKey, DescriptorSize; > + UINT32 DescriptorVersion; > + EFI_STATUS Status; > > if (FeaturePcdGet (PcdArmReenterPeiForCapsuleWarmReboot) && > !EfiAtRuntime ()) { > @@ -103,7 +109,46 @@ EnterS3WithImmediateWake ( > // > Reset = (VOID (*)(VOID))(UINTN)FixedPcdGet64 (PcdFvBaseAddress); > > - gBS->RaiseTPL (TPL_HIGH_LEVEL); > + // > + // Obtain the size of the memory map > + // > + MemMapSize = 0; > + Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, > + &DescriptorVersion); > + ASSERT (Status == EFI_BUFFER_TOO_SMALL); > + > + // > + // Add some slack to the allocation to cater for changes in the memory > + // map if ExitBootServices () fails the first time around. > + // > + MemMapSize += SIZE_4KB; > + Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, > + EFI_SIZE_TO_PAGES (MemMapSize), &Alloc); > + ASSERT_EFI_ERROR (Status); > + > + MemMap = (EFI_MEMORY_DESCRIPTOR *)(UINTN)Alloc; > + > + Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, > + &DescriptorVersion); > + ASSERT_EFI_ERROR (Status); > + > + Status = gBS->ExitBootServices (gImageHandle, MapKey); > + if (EFI_ERROR (Status)) { > + // > + // ExitBootServices () may fail the first time around if an event fired > + // right after the call to GetMemoryMap() which allocated or freed memory. > + // Since that first call to ExitBootServices () will disarm the timer, > + // this is guaranteed not to happen again, so one additional attempt > + // should suffice. > + // > + Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, > + &DescriptorVersion); > + ASSERT_EFI_ERROR (Status); > + > + Status = gBS->ExitBootServices (gImageHandle, MapKey); > + ASSERT_EFI_ERROR (Status); > + } > + > ArmDisableMmu (); > Reset (); > } > -- > 2.17.1 >