-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ArmPkg: ArmMmuLib: Pre-Allocate Page Table Memory #6286
base: master
Are you sure you want to change the base?
Conversation
I think this patch overall good to me about the table entry pool.
I don’t catch this sentence. Also,
If setting Because I couldn't find out discussion on maling list, above quetions seems silly. Thanks. |
@LeviYeoReum thanks for reviewing this PR! I apologize, I should have been clearer on the In the Please let me know if you have further questions. |
Hi @os-d.
Yes. but in
It seems to return EFI_SUCCESS without calling gCpu->SetAttributes() by line 1100. Am I missing? Thanks |
In the So |
I see. I've missed that code :) only see the Page.c. |
No worries, thanks for the review! @kraxel @leiflindholm @samimujawar can you please review? |
@samimujawar I addressed your comments, can you please re-review? |
e647c1e
to
72051a1
Compare
@samimujawar friendly ping to re-review |
Apologies for the delay. I will review this shortly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Oliver,
Apologies for the delay in getting back, and thank you for the updated patch series.
I have some minor comments marked inline.
Other than that do you plan to send a patch series to update the platforms in the edk2-platforms repo?
Regards,
Sami Mujawar
Thanks for reviewing! I have pushed an update addressing your comments, can you please re-review? I will put up a PR in edk2-platforms to resolve issues there and wait to check it in until this goes in. |
39f4f08
to
70a9896
Compare
edk2 PR tianocore/edk2#6286 is updating ArmMmuLib instances to a SEC, PEI, and BASE version to support pre-allocating page table memory. This commit makes the necessary changes in edk2-platforms to resolve the breaking change. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny <[email protected]>
Here is the edk2-platforms PR: tianocore/edk2-platforms#235. |
edk2 PR tianocore/edk2#6286 is updating ArmMmuLib instances to a SEC, PEI, and BASE version to support pre-allocating page table memory. This commit makes the necessary changes in edk2-platforms to resolve the breaking change. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny <[email protected]>
Allocating memory when memory protection is active can cause the below infinite loop: 1. gCpu->SetMemoryAttributes(EFI_MEMORY_RO) 2. ArmSetMemoryAttributes () 3. SetMemoryRegionAttribute() 4. UpdateRegionMapping() 5. UpdateRegionMappingRecursive() 6. AllocatePages() -> Need memory for a translation table entry 7. CoreAllocatePages() 8. ApplyMemoryProtectionPolicy() -> Policy says new page should be XN 9. gCpu->SetMemoryAttributes() 10. Back to 3 To fix this previously, CpuDxe would update conventional memory to be XN prior to installing the CpuArch protocol. However, when we transition to setting EFI_MEMORY_RP on free memory, this will no longer work. This PR updates ArmMmuLib to reserve page table memory for allocation during table spits to prevent the infinite loop. It also updates the consumers of ArmMmuLib to consume the PEI version of the lib in the same commit so as to not break them. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny <[email protected]>
edk2 PR tianocore/edk2#6286 is updating ArmMmuLib instances to a SEC, PEI, and BASE version to support pre-allocating page table memory. This commit makes the necessary changes in edk2-platforms to resolve the breaking change. Continuous-integration-options: PatchCheck.ignore-multi-package Signed-off-by: Oliver Smith-Denny <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is far too intrusive.
The page table walker does not actually require readable pages, only the CPU needs these pages to be read-/writable while it is manipulating the contents, but this could potentially happen via a different mapping altogether.
Also, I don't think we have fully explored other options, including mapping some or all of the VA space eagerly.
Hi @ardbiesheuvel ,
This is the same approach x86 CpuDxe takes: edk2/UefiCpuPkg/CpuDxe/CpuPageTable.c Line 1117 in f962adc
I'm not quite following, which part of this PR are you referencing as changing the semantics here? And what change would you like to see?
Do you have the bandwidth to put up a proof of concept of the eager mapping? We can test on our side and share the performance results if so. If you do not have the bandwidth, then can we work out an acceptable version of this PR to avoid blocking upstreaming greater memory protections for edk2 and have the eager mapping be revisted (tracked in a GH issue or bugzilla) when there is bandwidth? |
I am aware of that. But that doesn't mean it is a good idea.
Indeed. We'll always need to perform some allocations, but splitting block entries is tricky for multiple reasons, and there is some rather hairy code that fiddles with the MMU in order not to violate architectural rules regarding Break-Before-Make etc. In the early code, I don't think mapping eagerly is feasible, as memory might be restricted. But later on, it should be possible, given that the one thing we have in abundance in the boot stage is RAM.
Yeah, I should clarify that - see my long term plan below.
Boot performance on server systems is not going to be impacted by this. And especially on servers, fiddling with the MMU and TLBs etc is likely to have a performance impact as well.
Sure.
I have a short-term and a long-term plan: The short-term plan is to extend the existing API so that the call that remaps all unused memory RP does so eagerly, so that no additional page allocations are needed to remap these pages when they are allocated In the long term, what I would like to do is not map the page tables at all. Instead, we could have two sets of page tables, where the second set covers all of DRAM mapped lazily without restricted permissions, and this set is only used by the MMU library code while it is manipulating the mappings (with interrupts disabled). That way, all the dodgy code that fiddles with the MMU can go too, as the code no longer ever operates on live mappings. But it also means that page tables are never accessed via the primary set of page tables, and so all page tables can be unmapped (or mapped RP), and there is no reason to remap them writable, and that provides some robustness as well. That would also permit us to switch back to lazy mapping, but I honestly don't think it makes a difference. |
Thanks, I'll give it a test when it is ready.
This plan makes sense to me, thanks for driving this. |
PR can not be merged due to conflict. Please rebase and resubmit |
Description
Allocating memory when memory protection is active can cause the below infinite loop:
To fix this previously, CpuDxe would update conventional memory to be XN prior to installing the CpuArch protocol. However, when we transition to setting EFI_MEMORY_RP on free memory, this will no longer work. This a prerequisite to bring in the EFI_MEMORY_RP on free memory feature that has been discussed on the mailing list.
This PR updates ArmMmuLib to reserve page table memory for allocation during table spits to prevent the infinite loop. This follows the same pattern that the x86 CpuDxe does to preallocate page table memory:
edk2/UefiCpuPkg/CpuDxe/CpuPageTable.c
Line 1117 in f962adc
It also updates the consumers of ArmMmuLib to consume the PEI version of the lib in the same commit so as to not break them.
Continuous-integration-options: PatchCheck.ignore-multi-package
How This Was Tested
Tested on ArmVirtQemu by creating the scenario where the infinite loop (without the XN remap routine in place) and booting successfully. This was also tested using the EFI_MEMORY_RP on free memory feature that is pending upstreaming. This has been shipping in platforms.
Integration Instructions
Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
Platforms will also need to remove
gArmTokenSpaceGuid.PcdRemapUnusedMemoryNx
as it has been removed.