From nobody Sat Feb 7 04:47:26 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+99372+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+99372+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=kernel.org ARC-Seal: i=1; a=rsa-sha256; t=1675204570; cv=none; d=zohomail.com; s=zohoarc; b=L7iOgdPziqLL9aeRtVB0XTEudwRmfQS/lCXd80Gbhinslins7555ElufjGQw42za26q5SCpE3g4yXmZ/zXjDPlujv2FRASzSNtiFoNvFTWdXqP8Ybse3EEDecoxnBRSxfISaSXr2Cr6QC5hMynUZJd/CmPkzBwfH2ld3ksu4PSk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1675204570; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=/9oYU7DypgWTXWwgqzfTOTrK+C7cIee6xpIcvoJBO8o=; b=TwYTgB62Oz+l1KZopcWfYL9p4ofn/G9IVDyGmNwKGrFqOYz0JX3DFxHqvgzECZp2Xp4fuv0J3se7iWIx/fKprZ+faCebQPURJr928na1ZXuGQkKitlISvUtMkMYmR8CVy81D1LpD3/QR2XJ+tKE+ODDFSeLtk5xjCUIhmeN+kwU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+99372+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1675204570159779.0819464432216; Tue, 31 Jan 2023 14:36:10 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id jPZWYY1788612x89tFP7g4Jw; Tue, 31 Jan 2023 14:36:09 -0800 X-Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by mx.groups.io with SMTP id smtpd.web10.8582.1675204568949669377 for ; Tue, 31 Jan 2023 14:36:09 -0800 X-Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 777B061747; Tue, 31 Jan 2023 22:36:08 +0000 (UTC) X-Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4DAD4C4339C; Tue, 31 Jan 2023 22:36:06 +0000 (UTC) From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Michael Kinney , Liming Gao , Jiewen Yao , Michael Kubacki , Sean Brogan , Rebecca Cran , Leif Lindholm , Sami Mujawar Subject: [edk2-devel] [PATCH 4/4] ArmPkg/CpuDxe: Implement EFI memory attributes protocol Date: Tue, 31 Jan 2023 23:35:50 +0100 Message-Id: <20230131223550.1775834-5-ardb@kernel.org> In-Reply-To: <20230131223550.1775834-1-ardb@kernel.org> References: <20230131223550.1775834-1-ardb@kernel.org> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,ardb@kernel.org X-Gm-Message-State: aAN9Sc2rTLjxU7aitHidlR4Ax1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1675204569; bh=Zq1A4KagJyYVWIrU3tKwSa1OESlvx6weq09z1sld0g4=; h=Cc:Date:From:Reply-To:Subject:To; b=VvehMgSdXnWx2dg7lTavedokoyeyZcInn3sIU2mc9I8chQfdefx2CTtyUzkjEA84DdY J6Er04qK+E05VGTwaY5XFGLQ6t1U/NM6lyv+atDgFNNHZ5YZrEGMp7jHWONDYjZ56kih8 SI4yakcQ164oj44Ap4LpSFb5xF/GFYfoP8Y= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1675204571331100017 Content-Type: text/plain; charset="utf-8" Expose the protocol introduced in v2.10 that permits the caller to manage mapping permissions in the page tables. Signed-off-by: Ard Biesheuvel --- ArmPkg/Drivers/CpuDxe/CpuDxe.c | 2 + ArmPkg/Drivers/CpuDxe/CpuDxe.h | 3 + ArmPkg/Drivers/CpuDxe/CpuDxe.inf | 2 + ArmPkg/Drivers/CpuDxe/MemoryAttribute.c | 242 ++++++++++++++++++++ 4 files changed, 249 insertions(+) diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.c b/ArmPkg/Drivers/CpuDxe/CpuDxe.c index e6742f0a25fc..d04958e79e52 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.c +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.c @@ -244,6 +244,8 @@ CpuDxeInitialize ( &mCpuHandle, &gEfiCpuArchProtocolGuid, &mCpu, + &gEfiMemoryAttributeProtocolGuid, + &mMemoryAttribute, NULL ); =20 diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h index 8933fa90c4ed..f45d2bc101a3 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h @@ -30,9 +30,12 @@ #include #include #include +#include =20 extern BOOLEAN mIsFlushingGCD; =20 +extern EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute; + /** This function registers and enables the handler specified by InterruptHa= ndler for a processor interrupt or exception type specified by InterruptType. If InterruptHand= ler is NULL, then the diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Drivers/CpuDxe/CpuDx= e.inf index 10792b393fc8..e732e21cb94a 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf @@ -23,6 +23,7 @@ [Sources.Common] CpuDxe.h CpuMmuCommon.c Exception.c + MemoryAttribute.c =20 [Sources.ARM] Arm/Mmu.c @@ -53,6 +54,7 @@ [LibraryClasses] =20 [Protocols] gEfiCpuArchProtocolGuid + gEfiMemoryAttributeProtocolGuid =20 [Guids] gEfiDebugImageInfoTableGuid diff --git a/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c b/ArmPkg/Drivers/CpuDx= e/MemoryAttribute.c new file mode 100644 index 000000000000..9aeb83fff1b9 --- /dev/null +++ b/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c @@ -0,0 +1,242 @@ +/** @file + + Copyright (c) 2023, Google LLC. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuDxe.h" + +/** + This function retrieves the attributes of the memory region specified by + BaseAddress and Length. If different attributes are got from different p= art + of the memory region, EFI_NO_MAPPING will be returned. + + @param This The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address= of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes Pointer to attributes returned. + + @retval EFI_SUCCESS The attributes got for the memory region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes is NULL. + @retval EFI_NO_MAPPING Attributes are not consistent cross the me= mory + region. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specifi= ed + by BaseAddress and Length. + +**/ +STATIC +EFI_STATUS +GetMemoryAttributes ( + IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + OUT UINT64 *Attributes + ) +{ + UINTN RegionAddress; + UINTN RegionLength; + UINTN RegionAttributes; + UINTN Union; + UINTN Intersection; + EFI_STATUS Status; + + if ((Length =3D=3D 0) || (Attributes =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_INFO, + "%a: BaseAddress =3D=3D 0x%lx, Length =3D=3D 0x%lx\n", + __FUNCTION__, + (UINTN)BaseAddress, + (UINTN)Length + )); + + Union =3D 0; + Intersection =3D MAX_UINTN; + + for (RegionAddress =3D (UINTN)BaseAddress; + RegionAddress < (UINTN)(BaseAddress + Length); + RegionAddress +=3D RegionLength) { + + Status =3D GetMemoryRegion (&RegionAddress, + &RegionLength, + &RegionAttributes + ); + + DEBUG ((DEBUG_INFO, + "%a: RegionAddress =3D=3D 0x%lx, RegionLength =3D=3D 0x%lx, Re= gionAttributes =3D=3D 0x%lx\n", + __FUNCTION__, + RegionAddress, + RegionLength, + RegionAttributes + )); + + if (EFI_ERROR (Status)) { + return EFI_NO_MAPPING; + } + + Union |=3D RegionAttributes; + Intersection &=3D RegionAttributes; + } + + DEBUG ((DEBUG_INFO, + "%a: Union =3D=3D %lx, Intersection =3D=3D %lx\n", + __FUNCTION__, + Union, + Intersection + )); + + if (Union !=3D Intersection) { + return EFI_NO_MAPPING; + } + + *Attributes =3D PageAttributeToGcdAttribute (Union) & (EFI_MEMORY_RO | E= FI_MEMORY_XP); + return EFI_SUCCESS; +} + +/** + This function set given attributes of the memory region specified by + BaseAddress and Length. + + The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO. + + @param This The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address= of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to set for the memo= ry + region. + + @retval EFI_SUCCESS The attributes were set for the memory reg= ion. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combinatio= n of + attributes that cannot be set together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specifi= ed + by BaseAddress and Length. + The bit mask of attributes is not supporte= d for + the memory resource range specified by + BaseAddress and Length. + +**/ +STATIC +EFI_STATUS +SetMemoryAttributes ( + IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, + "%a: BaseAddress =3D=3D 0x%lx, Length =3D=3D 0x%lx, Attributes = =3D=3D 0x%lx\n", + __FUNCTION__, + (UINTN)BaseAddress, + (UINTN)Length, + (UINTN)Attributes + )); + + if ((Length =3D=3D 0) || + ((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != =3D 0)) { + return EFI_INVALID_PARAMETER; + } + + if ((Attributes & EFI_MEMORY_RP) !=3D 0) { + return EFI_UNSUPPORTED; + } + + if ((Attributes & EFI_MEMORY_RO) !=3D 0) { + Status =3D ArmSetMemoryRegionReadOnly (BaseAddress, Length); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } + + if ((Attributes & EFI_MEMORY_XP) !=3D 0) { + Status =3D ArmSetMemoryRegionNoExec (BaseAddress, Length); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } + + return EFI_SUCCESS; +} + +/** + This function clears given attributes of the memory region specified by + BaseAddress and Length. + + The valid Attributes is EFI_MEMORY_RP, EFI_MEMORY_XP, and EFI_MEMORY_RO. + + @param This The EFI_MEMORY_ATTRIBUTE_PROTOCOL instance. + @param BaseAddress The physical address that is the start address= of + a memory region. + @param Length The size in bytes of the memory region. + @param Attributes The bit mask of attributes to clear for the me= mory + region. + + @retval EFI_SUCCESS The attributes were cleared for the memory= region. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combinatio= n of + attributes that cannot be cleared together. + @retval EFI_UNSUPPORTED The processor does not support one or more + bytes of the memory resource range specifi= ed + by BaseAddress and Length. + The bit mask of attributes is not supporte= d for + the memory resource range specified by + BaseAddress and Length. + +**/ +STATIC +EFI_STATUS +ClearMemoryAttributes ( + IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, + "%a: BaseAddress =3D=3D 0x%lx, Length =3D=3D 0x%lx, Attributes = =3D=3D 0x%lx\n", + __FUNCTION__, + (UINTN)BaseAddress, + (UINTN)Length, + (UINTN)Attributes + )); + + if ((Length =3D=3D 0) || + ((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != =3D 0)) { + return EFI_INVALID_PARAMETER; + } + + if ((Attributes & EFI_MEMORY_RO) !=3D 0) { + Status =3D ArmClearMemoryRegionReadOnly (BaseAddress, Length); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } + + if ((Attributes & EFI_MEMORY_XP) !=3D 0) { + Status =3D ArmClearMemoryRegionNoExec (BaseAddress, Length); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } + + return EFI_SUCCESS; +} + +EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute =3D { + GetMemoryAttributes, + SetMemoryAttributes, + ClearMemoryAttributes +}; --=20 2.39.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#99372): https://edk2.groups.io/g/devel/message/99372 Mute This Topic: https://groups.io/mt/96664071/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-