Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
StandaloneMmPkg: Arm: Call TextUpdate after ReadwriteUpdater
The StandaloneMm implementation for Arm sets up the stack in the early startup code using the data section reserved in the assembly code. When TF-A loads the StandaloneMM binary in the DRAM it maps the entire StandaloneMM memory region as Read Only. Therefore, the initial startup assembly code updates the mem permissions of the stack region to Read Write. However, when the StandaloneMmCore is loaded the function UpdateMmFoundationPeCoffPermissions() starts applying the memory permissions based on the PE COFF sections as below: A. If the section is not executable, it first removes the executable permission of the section by calling TextUpdate(). TextUpdate() is the StandaloneMM MMU library function ArmSetMemoryRegionNoExec(). B. It then checks if the section is writable, and if it is it calls ReadWriteUpdater(), which invokes the StandaloneMM MMU library function ArmClearMemoryRegionReadOnly() to make the section writable. However, this results in the stack being made read-only between A and B. To understand this please see the following flow. 1. TF-A sets the entire StandaloneMM region as Read Only. 2. The stack is reserved in the data section by the early assembly entry point code. +--------------------+ <--- Start of Data Section | | | Data Section | | | | +----------------+ | <--- Stack region | | Stack | | | +----------------+ | | | +--------------------+ 3. The StanaloneMM early entry point code updates the attributes of the stack to Read Write. 4. When UpdateMmFoundationPeCoffPermissions() sets the permission of the data section to remove the Execute attribute, it calls ArmSetMemoryRegionNoExec(). 5. The ArmSetMemoryRegionNoExec() implementation gets the attributes of the first granule which is at the start of the data section, then clears the execute permission and applies the attribute for the entire data section. 6. Since TF-A has mapped the entire section as read only the first granule of the data section is read only and therefore the stack region attributes are changed to Read Only no execute. 7. Since the stack is read only after point A any updates to the stack result in an exception. To resolve this issue, reverse the order of the PE COFF section permission initialisation (i.e. step A and B) so that the Read Write attribute is first set for the data section, and then the execute permission is removed. By doing this the write permission for the stack region is preserved. Signed-off-by: Levi Yun <[email protected]>
- Loading branch information