On Tue, Oct 06, 2015 at 01:48:19PM +0100, Ard Biesheuvel wrote:
> Use the refactored UpdateRegionMapping () to traverse the translation
> tables, splitting block entries along the way if required, and apply
> a mask + or on each to set or clear the PXN/UXN/XN or RO bits.
> 
> For now, the 32-bit ARM versions remain unimplemented.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
> ---
>  ArmPkg/Include/Library/ArmLib.h            | 24 ++++++
>  ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c | 90 ++++++++++++++++++++
>  ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c     | 36 ++++++++
>  3 files changed, 150 insertions(+)
> 
> diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
> index c83a5a7f1b3c..b4768841bd9d 100644
> --- a/ArmPkg/Include/Library/ArmLib.h
> +++ b/ArmPkg/Include/Library/ArmLib.h
> @@ -661,4 +661,28 @@ ArmUnsetCpuActlrBit (
>    IN  UINTN    Bits
>    );
>  
> +RETURN_STATUS
> +ArmSetMemoryRegionNoExec (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  );
> +
> +RETURN_STATUS
> +ArmClearMemoryRegionNoExec (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  );
> +
> +RETURN_STATUS
> +ArmSetMemoryRegionReadOnly (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  );
> +
> +RETURN_STATUS
> +ArmClearMemoryRegionReadOnly (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  );
> +
>  #endif // __ARM_LIB__
> diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c 
> b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
> index 60f5cf188db3..011b529e8d6b 100644
> --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
> +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
> @@ -512,6 +512,96 @@ SetMemoryAttributes (
>    return RETURN_SUCCESS;
>  }
>  
> +STATIC
> +RETURN_STATUS
> +SetMemoryRegionAttribute (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length,
> +  IN  UINT64                    Attributes,
> +  IN  UINT64                    BlockEntryMask
> +  )
> +{
> +  RETURN_STATUS                Status;
> +  UINT64                       *RootTable;
> +
> +  RootTable = ArmGetTTBR0BaseAddress ();
> +
> +  Status = UpdateRegionMapping (RootTable, BaseAddress, Length, Attributes, 
> BlockEntryMask);
> +  if (RETURN_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  // Invalidate all TLB entries so changes are synced
> +  ArmInvalidateTlb ();
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +RETURN_STATUS
> +ArmSetMemoryRegionNoExec (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  UINT64    Val;
> +
> +  if (ArmReadCurrentEL () == AARCH64_EL1) {
> +    Val = TT_PXN_MASK | TT_UXN_MASK;
> +  } else {
> +    Val = TT_XN_MASK;
> +  }
> +
> +  return ArmSetMemoryRegionAttribute (
> +           BaseAddress,
> +           Length,
> +           Val,
> +           ~TT_ADDRESS_MASK_BLOCK_ENTRY);
> +}
> +
> +RETURN_STATUS
> +ArmClearMemoryRegionNoExec (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  UINT64 Mask;
> +
> +  // XN maps to UXN in the EL1&0 translation regime
> +  Mask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_PXN_MASK | TT_XN_MASK);
> +
> +  return ArmSetMemoryRegionAttribute (
> +           BaseAddress,
> +           Length,
> +           0,
> +           Mask);
> +}
> +
> +RETURN_STATUS
> +ArmSetMemoryRegionReadOnly (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  return ArmSetMemoryRegionAttribute (
> +           BaseAddress,
> +           Length,
> +           TT_AP_RO_RO,
> +           ~TT_ADDRESS_MASK_BLOCK_ENTRY);
> +}
> +
> +RETURN_STATUS
> +ArmClearMemoryRegionReadOnly (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  return ArmSetMemoryRegionAttribute (
> +           BaseAddress,
> +           Length,
> +           TT_AP_NO_RO,
> +           ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK));
> +}
> +
>  RETURN_STATUS
>  EFIAPI
>  ArmConfigureMmu (
> diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c 
> b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
> index d035ff3caa40..1287dfb1a9bb 100644
> --- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
> +++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
> @@ -301,3 +301,39 @@ ArmConfigureMmu (
>    ArmEnableMmu();
>    return RETURN_SUCCESS;
>  }
> +
> +RETURN_STATUS
> +ArmSetMemoryRegionNoExec (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  return RETURN_UNSUPPORTED;
> +}
> +
> +RETURN_STATUS
> +ArmClearMemoryRegionNoExec (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  return RETURN_UNSUPPORTED;
> +}
> +
> +RETURN_STATUS
> +ArmSetMemoryRegionReadOnly (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  return RETURN_UNSUPPORTED;
> +}
> +
> +RETURN_STATUS
> +ArmClearMemoryRegionReadOnly (
> +  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
> +  IN  UINT64                    Length
> +  )
> +{
> +  return RETURN_UNSUPPORTED;
> +}
> -- 
> 1.9.1

Provided you sort out the ArmSetMemoryRegionAttribute to
SetMemoryRegionAttribute renaming before committing:

Reviewed-by: Leif Lindholm <leif.lindh...@linaro.org>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to