Skip to content
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

Pre-Allocate Page Table Memory in ArmMmuLib #220

Merged

Conversation

TaylorBeebe
Copy link
Contributor

@TaylorBeebe TaylorBeebe commented Mar 14, 2024

Description

Allocating memory when memory protection is active can cause the below infinite loop:

  1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
  2. ArmSetMemoryRegionReadOnly ()
  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.

  • Impacts functionality?
    • Functionality - Does the change ultimately impact how firmware functions?
    • Examples: Add a new library, publish a new PPI, update an algorithm, ...
  • Impacts security?
    • Security - Does the change have a direct security impact on an application,
      flow, or firmware?
    • Examples: Crypto algorithm change, buffer overflow fix, parameter
      validation improvement, ...
  • Breaking change?
    • Breaking change - Will anyone consuming this change experience a break
      in build or boot behavior?
    • Examples: Add a new library class, move a module to a different repo, call
      a function in a new library class in a pre-existing module, ...
  • Includes tests?
    • Tests - Does the change include any explicit test code?
    • Examples: Unit tests, integration tests, robot tests, ...
  • Includes documentation?
    • Documentation - Does the change contain explicit documentation additions
      outside direct code modifications (and comments)?
    • Examples: Update readme file, add feature readme file, link to documentation
      on an a separate Web page, ...

How This Was Tested

Tested on SBSA 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 branch.

Integration Instructions

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC modules will need to switch those module types to use ArmMmuPeiLib.

[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf

@TaylorBeebe TaylorBeebe force-pushed the pre_alloc_page_table_mem branch from 330b413 to d2d49fb Compare March 19, 2024 18:37
@TaylorBeebe TaylorBeebe force-pushed the pre_alloc_page_table_mem branch from d2d49fb to 5488b7c Compare April 18, 2024 01:06
@github-actions github-actions bot added the impact:breaking-change Requires integration attention label Apr 24, 2024
@TaylorBeebe TaylorBeebe added the type:design-change A new proposal or modification to a feature design label Apr 24, 2024
@TaylorBeebe TaylorBeebe merged commit 8e2ff32 into microsoft:release/202311 Apr 24, 2024
12 checks passed
@TaylorBeebe TaylorBeebe deleted the pre_alloc_page_table_mem branch April 24, 2024 21:44
os-d pushed a commit to os-d/mu_silicon_arm_tiano that referenced this pull request Jul 19, 2024
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
os-d pushed a commit to os-d/mu_silicon_arm_tiano that referenced this pull request Jul 19, 2024
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
os-d pushed a commit to os-d/mu_silicon_arm_tiano that referenced this pull request Jul 19, 2024
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
os-d pushed a commit to os-d/mu_silicon_arm_tiano that referenced this pull request Jul 19, 2024
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
os-d pushed a commit to os-d/mu_silicon_arm_tiano that referenced this pull request Jul 22, 2024
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
os-d pushed a commit that referenced this pull request Jul 22, 2024
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit to apop5/mu_silicon_arm_tiano that referenced this pull request Jan 17, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit to apop5/mu_silicon_arm_tiano that referenced this pull request Feb 5, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit to apop5/mu_silicon_arm_tiano that referenced this pull request Feb 11, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit to apop5/mu_silicon_arm_tiano that referenced this pull request Feb 13, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit to apop5/mu_silicon_arm_tiano that referenced this pull request Feb 13, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit to apop5/mu_silicon_arm_tiano that referenced this pull request Feb 17, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit to apop5/mu_silicon_arm_tiano that referenced this pull request Feb 17, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit to apop5/mu_silicon_arm_tiano that referenced this pull request Feb 24, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit to apop5/mu_silicon_arm_tiano that referenced this pull request Feb 24, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
apop5 pushed a commit that referenced this pull request Mar 3, 2025
Allocating memory when memory protection is active can cause the below
infinite loop:

1. MemoryAttributeProtocol->SetMemoryAttributes(EFI_MEMORY_RO)
2. ArmSetMemoryRegionReadOnly ()
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.

- [x] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [x] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

Tested on SBSA 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 branch.

Platforms which are using ArmMmuBaseLib for PEIM, PEI_CORE, and SEC
modules will need to switch those module types to use ArmMmuPeiLib.
```
[LibraryClasses.common.SEC, LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
impact:breaking-change Requires integration attention type:design-change A new proposal or modification to a feature design
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants