* [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition
2023-02-02 11:27 [PATCH v2 0/3] ArmPkg: implement EFI memory attributes protocol Ard Biesheuvel
@ 2023-02-02 11:27 ` Ard Biesheuvel
2023-02-03 5:28 ` 回复: [edk2-devel] " gaoliming
2023-02-02 11:27 ` [PATCH v2 2/3] ArmPkg/CpuDxe: Unify PageAttributeToGcdAttribute helper Ard Biesheuvel
2023-02-02 11:27 ` [PATCH v2 3/3] ArmPkg/CpuDxe: Implement EFI memory attributes protocol Ard Biesheuvel
2 siblings, 1 reply; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-02 11:27 UTC (permalink / raw)
To: devel
Cc: Ard Biesheuvel, Michael Kinney, Liming Gao, Jiewen Yao,
Michael Kubacki, Sean Brogan, Rebecca Cran, Leif Lindholm,
Sami Mujawar, Taylor Beebe
Add the Memory Attribute Protocol definition, which was adopted and
included in version 2.10 of the UEFI specification.
Link: https://bugzilla.tianocore.org/show_bug.cgi?id=3519
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
MdePkg/Include/Protocol/MemoryAttribute.h | 142 ++++++++++++++++++++
MdePkg/MdePkg.dec | 3 +
2 files changed, 145 insertions(+)
diff --git a/MdePkg/Include/Protocol/MemoryAttribute.h b/MdePkg/Include/Protocol/MemoryAttribute.h
new file mode 100644
index 000000000000..ff930fb21aa6
--- /dev/null
+++ b/MdePkg/Include/Protocol/MemoryAttribute.h
@@ -0,0 +1,142 @@
+/** @file
+
+ EFI Memory Attribute Protocol provides retrieval and update service
+ for memory attributes in EFI environment.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2023, Google LLC. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_MEMORY_ATTRIBUTE_H__
+#define __EFI_MEMORY_ATTRIBUTE_H__
+
+#define EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID \
+ { \
+ 0xf4560cf6, 0x40ec, 0x4b4a, { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 } \
+ }
+
+typedef struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL EFI_MEMORY_ATTRIBUTE_PROTOCOL;
+
+/**
+ 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 memory
+ region.
+
+ @retval EFI_SUCCESS The attributes were set for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes specified an illegal combination of
+ attributes that cannot be set together.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not supported for
+ the memory resource range specified by
+ BaseAddress and Length.
+ @retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
+ lack of system resources.
+ @retval EFI_ACCESS_DENIED Attributes for the requested memory region are
+ controlled by system firmware and cannot be
+ updated via the protocol.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_MEMORY_ATTRIBUTES)(
+ IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ );
+
+/**
+ 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 memory
+ region.
+
+ @retval EFI_SUCCESS The attributes were cleared for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes specified an illegal combination of
+ attributes that cannot be cleared together.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not supported for
+ the memory resource range specified by
+ BaseAddress and Length.
+ @retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
+ lack of system resources.
+ @retval EFI_ACCESS_DENIED Attributes for the requested memory region are
+ controlled by system firmware and cannot be
+ updated via the protocol.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLEAR_MEMORY_ATTRIBUTES)(
+ IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ );
+
+/**
+ This function retrieves the attributes of the memory region specified by
+ BaseAddress and Length. If different attributes are got from different part
+ 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 memory
+ region.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_MEMORY_ATTRIBUTES)(
+ IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ OUT UINT64 *Attributes
+ );
+
+///
+/// EFI Memory Attribute Protocol provides services to retrieve or update
+/// attribute of memory in the EFI environment.
+///
+struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL {
+ EFI_GET_MEMORY_ATTRIBUTES GetMemoryAttributes;
+ EFI_SET_MEMORY_ATTRIBUTES SetMemoryAttributes;
+ EFI_CLEAR_MEMORY_ATTRIBUTES ClearMemoryAttributes;
+};
+
+extern EFI_GUID gEfiMemoryAttributeProtocolGuid;
+
+#endif
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 3d08f20d15b0..a8658403c8fd 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1915,6 +1915,9 @@ [Protocols]
## Include/Protocol/RedfishDiscover.h
gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347, { 0x96, 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f }}
+ ## Include/Protocol/MemoryAttribute.h
+ gEfiMemoryAttributeProtocolGuid = { 0xf4560cf6, 0x40ec, 0x4b4a, { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 }}
+
#
# Protocols defined in Shell2.0
#
--
2.39.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* 回复: [edk2-devel] [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition
2023-02-02 11:27 ` [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition Ard Biesheuvel
@ 2023-02-03 5:28 ` gaoliming
0 siblings, 0 replies; 5+ messages in thread
From: gaoliming @ 2023-02-03 5:28 UTC (permalink / raw)
To: devel, ardb
Cc: 'Michael Kinney', 'Jiewen Yao',
'Michael Kubacki', 'Sean Brogan',
'Rebecca Cran', 'Leif Lindholm',
'Sami Mujawar', 'Taylor Beebe'
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Ard
> Biesheuvel
> 发送时间: 2023年2月2日 19:27
> 收件人: devel@edk2.groups.io
> 抄送: Ard Biesheuvel <ardb@kernel.org>; Michael Kinney
> <michael.d.kinney@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>;
> Jiewen Yao <jiewen.yao@intel.com>; Michael Kubacki
> <michael.kubacki@microsoft.com>; Sean Brogan
> <sean.brogan@microsoft.com>; Rebecca Cran <quic_rcran@quicinc.com>;
> Leif Lindholm <quic_llindhol@quicinc.com>; Sami Mujawar
> <sami.mujawar@arm.com>; Taylor Beebe <t@taylorbeebe.com>
> 主题: [edk2-devel] [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol
> definition
>
> Add the Memory Attribute Protocol definition, which was adopted and
> included in version 2.10 of the UEFI specification.
>
> Link: https://bugzilla.tianocore.org/show_bug.cgi?id=3519
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> MdePkg/Include/Protocol/MemoryAttribute.h | 142
> ++++++++++++++++++++
> MdePkg/MdePkg.dec | 3 +
> 2 files changed, 145 insertions(+)
>
> diff --git a/MdePkg/Include/Protocol/MemoryAttribute.h
> b/MdePkg/Include/Protocol/MemoryAttribute.h
> new file mode 100644
> index 000000000000..ff930fb21aa6
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/MemoryAttribute.h
> @@ -0,0 +1,142 @@
> +/** @file
>
> +
>
> + EFI Memory Attribute Protocol provides retrieval and update service
>
> + for memory attributes in EFI environment.
>
> +
>
> + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
>
> + Copyright (c) 2023, Google LLC. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#ifndef __EFI_MEMORY_ATTRIBUTE_H__
>
> +#define __EFI_MEMORY_ATTRIBUTE_H__
>
> +
>
> +#define EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID \
>
> + { \
>
> + 0xf4560cf6, 0x40ec, 0x4b4a, { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0,
0xb1,
> 0x89 } \
>
> + }
>
> +
>
> +typedef struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL
> EFI_MEMORY_ATTRIBUTE_PROTOCOL;
>
> +
>
> +/**
>
> + 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
> memory
>
> + region.
>
> +
>
> + @retval EFI_SUCCESS The attributes were set for the
> memory region.
>
> + @retval EFI_INVALID_PARAMETER Length is zero.
>
> + Attributes specified an illegal
> combination of
>
> + attributes that cannot be set
> together.
>
> + @retval EFI_UNSUPPORTED The processor does not support one
> or more
>
> + bytes of the memory resource range
> specified
>
> + by BaseAddress and Length.
>
> + The bit mask of attributes is not
> supported for
>
> + the memory resource range
> specified by
>
> + BaseAddress and Length.
>
> + @retval EFI_OUT_OF_RESOURCES Requested attributes cannot be
> applied due to
>
> + lack of system resources.
>
> + @retval EFI_ACCESS_DENIED Attributes for the requested memory
> region are
>
> + controlled by system firmware and
> cannot be
>
> + updated via the protocol.
>
> +
>
> +**/
>
> +typedef
>
> +EFI_STATUS
>
> +(EFIAPI *EFI_SET_MEMORY_ATTRIBUTES)(
>
> + IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
>
> + IN EFI_PHYSICAL_ADDRESS BaseAddress,
>
> + IN UINT64 Length,
>
> + IN UINT64 Attributes
>
> + );
>
> +
>
> +/**
>
> + 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
> memory
>
> + region.
>
> +
>
> + @retval EFI_SUCCESS The attributes were cleared for the
> memory region.
>
> + @retval EFI_INVALID_PARAMETER Length is zero.
>
> + Attributes specified an illegal
> combination of
>
> + attributes that cannot be cleared
> together.
>
> + @retval EFI_UNSUPPORTED The processor does not support one
> or more
>
> + bytes of the memory resource range
> specified
>
> + by BaseAddress and Length.
>
> + The bit mask of attributes is not
> supported for
>
> + the memory resource range
> specified by
>
> + BaseAddress and Length.
>
> + @retval EFI_OUT_OF_RESOURCES Requested attributes cannot be
> applied due to
>
> + lack of system resources.
>
> + @retval EFI_ACCESS_DENIED Attributes for the requested memory
> region are
>
> + controlled by system firmware and
> cannot be
>
> + updated via the protocol.
>
> +
>
> +**/
>
> +typedef
>
> +EFI_STATUS
>
> +(EFIAPI *EFI_CLEAR_MEMORY_ATTRIBUTES)(
>
> + IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
>
> + IN EFI_PHYSICAL_ADDRESS BaseAddress,
>
> + IN UINT64 Length,
>
> + IN UINT64 Attributes
>
> + );
>
> +
>
> +/**
>
> + This function retrieves the attributes of the memory region specified
by
>
> + BaseAddress and Length. If different attributes are got from different
part
>
> + 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 memory
>
> + region.
>
> + @retval EFI_UNSUPPORTED The processor does not support one
> or more
>
> + bytes of the memory resource range
> specified
>
> + by BaseAddress and Length.
>
> +
>
> +**/
>
> +typedef
>
> +EFI_STATUS
>
> +(EFIAPI *EFI_GET_MEMORY_ATTRIBUTES)(
>
> + IN EFI_MEMORY_ATTRIBUTE_PROTOCOL *This,
>
> + IN EFI_PHYSICAL_ADDRESS BaseAddress,
>
> + IN UINT64 Length,
>
> + OUT UINT64 *Attributes
>
> + );
>
> +
>
> +///
>
> +/// EFI Memory Attribute Protocol provides services to retrieve or update
>
> +/// attribute of memory in the EFI environment.
>
> +///
>
> +struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL {
>
> + EFI_GET_MEMORY_ATTRIBUTES GetMemoryAttributes;
>
> + EFI_SET_MEMORY_ATTRIBUTES SetMemoryAttributes;
>
> + EFI_CLEAR_MEMORY_ATTRIBUTES ClearMemoryAttributes;
>
> +};
>
> +
>
> +extern EFI_GUID gEfiMemoryAttributeProtocolGuid;
>
> +
>
> +#endif
>
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index 3d08f20d15b0..a8658403c8fd 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -1915,6 +1915,9 @@ [Protocols]
> ## Include/Protocol/RedfishDiscover.h
>
> gEfiRedfishDiscoverProtocolGuid = { 0x5db12509, 0x4550, 0x4347,
> { 0x96, 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f }}
>
>
>
> + ## Include/Protocol/MemoryAttribute.h
>
> + gEfiMemoryAttributeProtocolGuid = { 0xf4560cf6, 0x40ec, 0x4b4a, { 0xa1,
> 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 }}
>
> +
>
> #
>
> # Protocols defined in Shell2.0
>
> #
>
> --
> 2.39.0
>
>
>
> -=-=-=-=-=-=
> Groups.io Links: You receive all messages sent to this group.
> View/Reply Online (#99466): https://edk2.groups.io/g/devel/message/99466
> Mute This Topic: https://groups.io/mt/96697936/4905953
> Group Owner: devel+owner@edk2.groups.io
> Unsubscribe: https://edk2.groups.io/g/devel/unsub
> [gaoliming@byosoft.com.cn]
> -=-=-=-=-=-=
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/3] ArmPkg/CpuDxe: Unify PageAttributeToGcdAttribute helper
2023-02-02 11:27 [PATCH v2 0/3] ArmPkg: implement EFI memory attributes protocol Ard Biesheuvel
2023-02-02 11:27 ` [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition Ard Biesheuvel
@ 2023-02-02 11:27 ` Ard Biesheuvel
2023-02-02 11:27 ` [PATCH v2 3/3] ArmPkg/CpuDxe: Implement EFI memory attributes protocol Ard Biesheuvel
2 siblings, 0 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-02 11:27 UTC (permalink / raw)
To: devel
Cc: Ard Biesheuvel, Michael Kinney, Liming Gao, Jiewen Yao,
Michael Kubacki, Sean Brogan, Rebecca Cran, Leif Lindholm,
Sami Mujawar, Taylor Beebe
In preparation for introducing an implementation of the EFI memory
attributes protocol that is shared between ARM and AArch64, unify the
existing code that converts a page table descriptor into a
EFI_MEMORY_xxx bitfield, so it can be called from the generic code.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c | 5 +--
ArmPkg/Drivers/CpuDxe/Arm/Mmu.c | 46 +++++++++++---------
ArmPkg/Drivers/CpuDxe/CpuDxe.h | 5 +++
3 files changed, 32 insertions(+), 24 deletions(-)
diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
index 8bb33046e707..4ec9fc0a582c 100644
--- a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c
@@ -30,13 +30,12 @@ GetRootTranslationTableInfo (
*RootTableEntryCount = TT_ENTRY_COUNT >> (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL;
}
-STATIC
UINT64
PageAttributeToGcdAttribute (
- IN UINT64 PageAttributes
+ IN UINTN PageAttributes
)
{
- UINT64 GcdAttributes;
+ UINTN GcdAttributes;
switch (PageAttributes & TT_ATTR_INDX_MASK) {
case TT_ATTR_INDX_DEVICE_MEMORY:
diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
index 2daf47ba6fe5..9545a1c1d2d3 100644
--- a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
+++ b/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c
@@ -77,39 +77,46 @@ SectionToGcdAttributes (
return EFI_SUCCESS;
}
-EFI_STATUS
-PageToGcdAttributes (
- IN UINT32 PageAttributes,
- OUT UINT64 *GcdAttributes
+UINT64
+PageAttributeToGcdAttribute (
+ IN UINTN PageAttributes
)
{
- *GcdAttributes = 0;
+ UINT64 GcdAttributes;
// determine cacheability attributes
switch (PageAttributes & TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK) {
case TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED:
- *GcdAttributes |= EFI_MEMORY_UC;
+ GcdAttributes = EFI_MEMORY_UC;
break;
case TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE:
- *GcdAttributes |= EFI_MEMORY_UC;
+ GcdAttributes = EFI_MEMORY_UC;
break;
case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC:
- *GcdAttributes |= EFI_MEMORY_WT;
+ GcdAttributes = EFI_MEMORY_WT;
break;
case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_NO_ALLOC:
- *GcdAttributes |= EFI_MEMORY_WB;
+ GcdAttributes = EFI_MEMORY_WB;
break;
case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE:
- *GcdAttributes |= EFI_MEMORY_WC;
+ GcdAttributes = EFI_MEMORY_WC;
break;
case TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC:
- *GcdAttributes |= EFI_MEMORY_WB;
+ GcdAttributes = EFI_MEMORY_WB;
break;
case TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_SHAREABLE_DEVICE:
- *GcdAttributes |= EFI_MEMORY_UC;
+ GcdAttributes = EFI_MEMORY_UC;
break;
default:
- return EFI_UNSUPPORTED;
+ DEBUG ((
+ DEBUG_ERROR,
+ "PageAttributeToGcdAttribute: PageAttributes:0x%X not supported.\n",
+ PageAttributes
+ ));
+ ASSERT (0);
+ // The Global Coherency Domain (GCD) value is defined as a bit set.
+ // Returning 0 means no attribute has been set.
+ GcdAttributes = 0;
}
// determine protection attributes
@@ -126,7 +133,7 @@ PageToGcdAttributes (
// read only cases map to write-protect
case TT_DESCRIPTOR_PAGE_AP_RO_NO:
case TT_DESCRIPTOR_PAGE_AP_RO_RO:
- *GcdAttributes |= EFI_MEMORY_RO;
+ GcdAttributes |= EFI_MEMORY_RO;
break;
default:
@@ -135,10 +142,10 @@ PageToGcdAttributes (
// now process eXectue Never attribute
if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0 ) {
- *GcdAttributes |= EFI_MEMORY_XP;
+ GcdAttributes |= EFI_MEMORY_XP;
}
- return EFI_SUCCESS;
+ return GcdAttributes;
}
EFI_STATUS
@@ -152,7 +159,6 @@ SyncCacheConfigPage (
IN OUT UINT32 *NextSectionAttributes
)
{
- EFI_STATUS Status;
UINT32 i;
volatile ARM_PAGE_TABLE_ENTRY *SecondLevelTable;
UINT32 NextPageAttributes;
@@ -183,8 +189,7 @@ SyncCacheConfigPage (
NextPageAttributes = PageAttributes;
} else if (PageAttributes != NextPageAttributes) {
// Convert Section Attributes into GCD Attributes
- Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
- ASSERT_EFI_ERROR (Status);
+ GcdAttributes = PageAttributeToGcdAttribute (NextPageAttributes);
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
@@ -196,8 +201,7 @@ SyncCacheConfigPage (
}
} else if (NextPageAttributes != 0) {
// Convert Page Attributes into GCD Attributes
- Status = PageToGcdAttributes (NextPageAttributes, &GcdAttributes);
- ASSERT_EFI_ERROR (Status);
+ GcdAttributes = PageAttributeToGcdAttribute (NextPageAttributes);
// update GCD with these changes (this will recurse into our own CpuSetMemoryAttributes below which is OK)
SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, *NextRegionBase, *NextRegionLength, GcdAttributes);
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
index ff672390ce51..8933fa90c4ed 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h
@@ -126,4 +126,9 @@ SetGcdMemorySpaceAttributes (
IN UINT64 Attributes
);
+UINT64
+PageAttributeToGcdAttribute (
+ IN UINTN PageAttributes
+ );
+
#endif // CPU_DXE_H_
--
2.39.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 3/3] ArmPkg/CpuDxe: Implement EFI memory attributes protocol
2023-02-02 11:27 [PATCH v2 0/3] ArmPkg: implement EFI memory attributes protocol Ard Biesheuvel
2023-02-02 11:27 ` [PATCH v2 1/3] MdePkg: Add Memory Attribute Protocol definition Ard Biesheuvel
2023-02-02 11:27 ` [PATCH v2 2/3] ArmPkg/CpuDxe: Unify PageAttributeToGcdAttribute helper Ard Biesheuvel
@ 2023-02-02 11:27 ` Ard Biesheuvel
2 siblings, 0 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-02 11:27 UTC (permalink / raw)
To: devel
Cc: Ard Biesheuvel, Michael Kinney, Liming Gao, Jiewen Yao,
Michael Kubacki, Sean Brogan, Rebecca Cran, Leif Lindholm,
Sami Mujawar, Taylor Beebe
Expose the protocol introduced in v2.10 that permits the caller to
manage mapping permissions in the page tables.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
ArmPkg/Drivers/CpuDxe/CpuDxe.c | 2 +
ArmPkg/Drivers/CpuDxe/CpuDxe.h | 3 +
ArmPkg/Drivers/CpuDxe/CpuDxe.inf | 2 +
ArmPkg/Drivers/CpuDxe/MemoryAttribute.c | 252 ++++++++++++++++++++
4 files changed, 259 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
);
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 <Protocol/Cpu.h>
#include <Protocol/DebugSupport.h>
#include <Protocol/LoadedImage.h>
+#include <Protocol/MemoryAttribute.h>
extern BOOLEAN mIsFlushingGCD;
+extern EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute;
+
/**
This function registers and enables the handler specified by InterruptHandler for a processor
interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Drivers/CpuDxe/CpuDxe.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
[Sources.ARM]
Arm/Mmu.c
@@ -53,6 +54,7 @@ [LibraryClasses]
[Protocols]
gEfiCpuArchProtocolGuid
+ gEfiMemoryAttributeProtocolGuid
[Guids]
gEfiDebugImageInfoTableGuid
diff --git a/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c b/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c
new file mode 100644
index 000000000000..827deb94dd99
--- /dev/null
+++ b/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c
@@ -0,0 +1,252 @@
+/** @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 part
+ 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 memory
+ region.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ 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 == 0) || (Attributes == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((DEBUG_INFO,
+ "%a: BaseAddress == 0x%lx, Length == 0x%lx\n",
+ __FUNCTION__,
+ (UINTN)BaseAddress,
+ (UINTN)Length
+ ));
+
+ Union = 0;
+ Intersection = MAX_UINTN;
+
+ for (RegionAddress = (UINTN)BaseAddress;
+ RegionAddress < (UINTN)(BaseAddress + Length);
+ RegionAddress += RegionLength) {
+
+ Status = GetMemoryRegion (&RegionAddress,
+ &RegionLength,
+ &RegionAttributes
+ );
+
+ DEBUG ((DEBUG_INFO,
+ "%a: RegionAddress == 0x%lx, RegionLength == 0x%lx, RegionAttributes == 0x%lx\n",
+ __FUNCTION__,
+ RegionAddress,
+ RegionLength,
+ RegionAttributes
+ ));
+
+ if (EFI_ERROR (Status)) {
+ return EFI_NO_MAPPING;
+ }
+
+ Union |= RegionAttributes;
+ Intersection &= RegionAttributes;
+ }
+
+ DEBUG ((DEBUG_INFO,
+ "%a: Union == %lx, Intersection == %lx\n",
+ __FUNCTION__,
+ Union,
+ Intersection
+ ));
+
+ if (Union != Intersection) {
+ return EFI_NO_MAPPING;
+ }
+
+ *Attributes = PageAttributeToGcdAttribute (Union) & (EFI_MEMORY_RO | EFI_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 memory
+ region.
+
+ @retval EFI_SUCCESS The attributes were set for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes specified an illegal combination of
+ attributes that cannot be set together.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not supported for
+ the memory resource range specified by
+ BaseAddress and Length.
+ @retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
+ lack of system resources.
+ @retval EFI_ACCESS_DENIED Attributes for the requested memory region are
+ controlled by system firmware and cannot be
+ updated via the protocol.
+
+**/
+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 == 0x%lx, Length == 0x%lx, Attributes == 0x%lx\n",
+ __FUNCTION__,
+ (UINTN)BaseAddress,
+ (UINTN)Length,
+ (UINTN)Attributes
+ ));
+
+ if ((Length == 0) ||
+ ((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Attributes & EFI_MEMORY_RP) != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((Attributes & EFI_MEMORY_RO) != 0) {
+ Status = ArmSetMemoryRegionReadOnly (BaseAddress, Length);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ if ((Attributes & EFI_MEMORY_XP) != 0) {
+ Status = 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 memory
+ region.
+
+ @retval EFI_SUCCESS The attributes were cleared for the memory region.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes specified an illegal combination of
+ attributes that cannot be cleared together.
+ @retval EFI_UNSUPPORTED The processor does not support one or more
+ bytes of the memory resource range specified
+ by BaseAddress and Length.
+ The bit mask of attributes is not supported for
+ the memory resource range specified by
+ BaseAddress and Length.
+ @retval EFI_OUT_OF_RESOURCES Requested attributes cannot be applied due to
+ lack of system resources.
+ @retval EFI_ACCESS_DENIED Attributes for the requested memory region are
+ controlled by system firmware and cannot be
+ updated via the protocol.
+
+**/
+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 == 0x%lx, Length == 0x%lx, Attributes == 0x%lx\n",
+ __FUNCTION__,
+ (UINTN)BaseAddress,
+ (UINTN)Length,
+ (UINTN)Attributes
+ ));
+
+ if ((Length == 0) ||
+ ((Attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Attributes & EFI_MEMORY_RO) != 0) {
+ Status = ArmClearMemoryRegionReadOnly (BaseAddress, Length);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ if ((Attributes & EFI_MEMORY_XP) != 0) {
+ Status = ArmClearMemoryRegionNoExec (BaseAddress, Length);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute = {
+ GetMemoryAttributes,
+ SetMemoryAttributes,
+ ClearMemoryAttributes
+};
--
2.39.0
^ permalink raw reply related [flat|nested] 5+ messages in thread