mirror of https://github.com/acidanthera/audk.git
ArmPkg/ArmMmuLib: Implement EFI_MEMORY_RP using access flag
Implement support for read-protected memory by wiring it up to the access flag in the page table descriptor. The resulting mapping is implicitly non-writable and non-executable as well, but this is good enough for implementing this attribute, as we never rely on write or execute permissions without read permissions. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
This commit is contained in:
parent
041c7a31c2
commit
6b821be140
|
@ -64,6 +64,10 @@ PageAttributeToGcdAttribute (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine protection attributes
|
// Determine protection attributes
|
||||||
|
if ((PageAttributes & TT_AF) == 0) {
|
||||||
|
GcdAttributes |= EFI_MEMORY_RP;
|
||||||
|
}
|
||||||
|
|
||||||
if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) ||
|
if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) ||
|
||||||
((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO))
|
((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO))
|
||||||
{
|
{
|
||||||
|
@ -301,7 +305,9 @@ EfiAttributeToArmAttribute (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the access flag to match the block attributes
|
// Set the access flag to match the block attributes
|
||||||
ArmAttributes |= TT_AF;
|
if ((EfiAttributes & EFI_MEMORY_RP) == 0) {
|
||||||
|
ArmAttributes |= TT_AF;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine protection attributes
|
// Determine protection attributes
|
||||||
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
|
if ((EfiAttributes & EFI_MEMORY_RO) != 0) {
|
||||||
|
|
|
@ -21,6 +21,40 @@ ArmConfigureMmu (
|
||||||
OUT UINTN *TranslationTableSize OPTIONAL
|
OUT UINTN *TranslationTableSize OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert a region of memory to read-protected, by clearing the access flag.
|
||||||
|
|
||||||
|
@param BaseAddress The start of the region.
|
||||||
|
@param Length The size of the region.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The attributes were set successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The operation failed due to insufficient memory.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ArmSetMemoryRegionNoAccess (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert a region of memory to read-enabled, by setting the access flag.
|
||||||
|
|
||||||
|
@param BaseAddress The start of the region.
|
||||||
|
@param Length The size of the region.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The attributes were set successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The operation failed due to insufficient memory.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ArmClearMemoryRegionNoAccess (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
);
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmSetMemoryRegionNoExec (
|
ArmSetMemoryRegionNoExec (
|
||||||
|
|
|
@ -438,7 +438,11 @@ GcdAttributeToPageAttribute (
|
||||||
PageAttributes |= TT_AP_NO_RO;
|
PageAttributes |= TT_AP_NO_RO;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PageAttributes | TT_AF;
|
if ((GcdAttributes & EFI_MEMORY_RP) == 0) {
|
||||||
|
PageAttributes |= TT_AF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PageAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
@ -459,9 +463,9 @@ ArmSetMemoryAttributes (
|
||||||
// No memory type was set in Attributes, so we are going to update the
|
// No memory type was set in Attributes, so we are going to update the
|
||||||
// permissions only.
|
// permissions only.
|
||||||
//
|
//
|
||||||
PageAttributes &= TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK;
|
PageAttributes &= TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK | TT_AF;
|
||||||
PageAttributeMask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK |
|
PageAttributeMask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK |
|
||||||
TT_PXN_MASK | TT_XN_MASK);
|
TT_PXN_MASK | TT_XN_MASK | TT_AF);
|
||||||
}
|
}
|
||||||
|
|
||||||
return UpdateRegionMapping (
|
return UpdateRegionMapping (
|
||||||
|
@ -534,6 +538,54 @@ ArmClearMemoryRegionNoExec (
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert a region of memory to read-protected, by clearing the access flag.
|
||||||
|
|
||||||
|
@param BaseAddress The start of the region.
|
||||||
|
@param Length The size of the region.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The attributes were set successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The operation failed due to insufficient memory.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
ArmSetMemoryRegionNoAccess (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return SetMemoryRegionAttribute (
|
||||||
|
BaseAddress,
|
||||||
|
Length,
|
||||||
|
0,
|
||||||
|
~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AF)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert a region of memory to read-enabled, by setting the access flag.
|
||||||
|
|
||||||
|
@param BaseAddress The start of the region.
|
||||||
|
@param Length The size of the region.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The attributes were set successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The operation failed due to insufficient memory.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
ArmClearMemoryRegionNoAccess (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return SetMemoryRegionAttribute (
|
||||||
|
BaseAddress,
|
||||||
|
Length,
|
||||||
|
TT_AF,
|
||||||
|
~TT_ADDRESS_MASK_BLOCK_ENTRY
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
ArmSetMemoryRegionReadOnly (
|
ArmSetMemoryRegionReadOnly (
|
||||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
|
|
@ -523,3 +523,51 @@ ArmClearMemoryRegionReadOnly (
|
||||||
TT_DESCRIPTOR_SECTION_AP_MASK
|
TT_DESCRIPTOR_SECTION_AP_MASK
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert a region of memory to read-protected, by clearing the access flag.
|
||||||
|
|
||||||
|
@param BaseAddress The start of the region.
|
||||||
|
@param Length The size of the region.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The attributes were set successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The operation failed due to insufficient memory.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
ArmSetMemoryRegionNoAccess (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return SetMemoryAttributes (
|
||||||
|
BaseAddress,
|
||||||
|
Length,
|
||||||
|
EFI_MEMORY_RP,
|
||||||
|
TT_DESCRIPTOR_SECTION_AF
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert a region of memory to read-enabled, by setting the access flag.
|
||||||
|
|
||||||
|
@param BaseAddress The start of the region.
|
||||||
|
@param Length The size of the region.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The attributes were set successfully.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES The operation failed due to insufficient memory.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
ArmClearMemoryRegionNoAccess (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||||
|
IN UINT64 Length
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return SetMemoryAttributes (
|
||||||
|
BaseAddress,
|
||||||
|
Length,
|
||||||
|
0,
|
||||||
|
TT_DESCRIPTOR_SECTION_AF
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue