Releases: OpenDevicePartnership/patina
patina-v22.0.0
What's Changed
⚠️ Breaking Changes
-
[major] Simplify patina\_performance config, Add SMBIOS types to Patina, R-EFI 6.0 Migration @vineelko (#1548)
Change Details
## Description
1465: patina_performance: Simplify configuration
patina_performance has a confusing configuration story. Prior to this change, configuration was done via patina
Config, A platform could optionally register a secondary component that would read a HOB (if provided) and overwrite anyConfigwith the HOB configuration.This commit works to simplify the configuration story by making a couple of changes:
- Removal of the
Configobject. As stated in documentation throughout patina,Configis meant for configuration that is expected to be shared between multiple components. This particular configuration does not need to be shared, so it is moved to be private configuration of the component. - Removal of the optional HOB reader driver. Now, a private configuration of the component will allow you to specify if the HOB is able to override local configuration or not.
This new story reduces patina_performance setup from three different definitions (Config, performance component, and hob component) to only one, the performance component.
How This Was Tested
Reading final configuration of the performance component on Q35 with various configuration settings both in the component and via the HOB
Previous
use patina_dxe_core::*; struct Q35; impl ComponentInfo for Q35 { fn configs(mut add: Add<Config>) { add.config(patina_performance::config::PerfConfig { enable_component: true, enabled_measurements: patina::performance::Measurement::LoadImage | patina::performance::Measurement::StartImage } } fn components(mut add: Add<Component>) { add.component(patina_performance::component::performance_config_provider::PerformanceConfigurationProvider); add.component(patina_performance::component::performance::Performance); } }
After
use patina_dxe_core::*; use patina_performance::component::*; struct Q35; impl ComponentInfo for Q35 { fn components(mut add: Add<Component>) { // Records LoadImage and StartImage measurements unless configuration is overwritten by a HOB add.component(Performance::new().with_measurements(Measurement::LoadImage | Measurement::StartImage)); // Disabled. Enablement fully controlled by a HOB add.component(Performance::new()); }
1501: patina_smbios: Add SMBIOS types
Define types for SMBIOS records according the SMBIOS specs 3.0+ and update records to use types. These structs/enums/bitfields force typing when creating SMBIOS records.
How This Was Tested
cargo make all, plus patina-dxe-core-qemu integration: ported the Q35 and
SBSA SMBIOS platform components onto the new typed records, booted Q35 in
QEMU, and confirmedq35_smbios_ffi_testpasses against the published SMBIOS
table.Integration Instructions
Downstream consumers of
patina_smbiosType 0 / 1 / 2 / 3 / 4 / 7 / 16 / 17 /
19 records must construct fields with the new types instead of raw integers
(e.g.BiosCharacteristics::from_bits(0x08),WakeUpType::PowerSwitch,
BootUpState::Safe). For Type 4, setprocessor_family: u8 = 0xFEand put
the typed value inprocessor_family2.Co-Authored-By: Ansley Thompson ansley.thompson@dell.com
1480: Patina: R-EFI 6.0 migration
R-EFI 6.0 Migration
Upstream r-efi 6.0 marks all
extern "efiapi"function pointers in EFI Boot
Services, Runtime Services, and other protocols asunsafe, since their safety
cannot be enforced by the Rust type system at compile time.This PR audits almost all usage of UEFI service function pointers across the Patina
codebase for correctness and safety.-
There are three primary areas where
unsafeusage has been audited:- The FFI boundary - all
extern "efiapi"functions - The Patina wrappers - all functions within the
BootServicestrait that
eventually call into the FFI - Core Patina routines that implement the FFI functions
- The FFI boundary - all
-
Not all functions in the above categories need to be marked
unsafe. For
example,extern "efiapi" close_eventis not markedunsafebecause it can
safely be called with an arbitrary event parameter without causing undefined
behavior in the Patina implementation. Theeventparameter is treated as an
opaque pointer and is never dereferenced.That said, any indirect caller that dereferences this Boot Services function
pointer must still use anunsafeblock, since the function pointer itself is
defined asunsafein r-efi 6.0. In addition, inherently unsafe Rust
functions (such ascore_free_pool()) are now explicitly markedunsafe. -
Each inspected function or call site is documented with appropriate safety
comments where necessary, and with explanations whereunsafeis not
required. -
There are no functional changes.
-
Clippy flags public functions that accept raw pointer parameters and pass them
across an FFI boundary without being markedunsafe, with the following
warning:
"this public function might dereference a raw pointer but is not markedunsafe"unsafe extern "C" { fn some_ffi_call(ptr: *mut i32); } // Triggers clippy::not_unsafe_ptr_arg_deref: // - public function // - not marked `unsafe` // - raw pointer parameter `ptr` is passed into an `unsafe` block pub fn example(ptr: *mut i32) { unsafe { some_ffi_call(ptr) }; }In Patina, this pattern is common for functions that take
efi::Eventor
efi::Handleparameters and call Boot Services function pointers. We
explicitly suppress this lint for such functions because these types are
treated as opaque pointers and are never dereferenced:
#[allow(clippy::not_unsafe_ptr_arg_deref)]
Geiger Unsafe Stats
| | x86_64-unknown-uefi(before) | x86_64-unknown-uefi(after) | aarch64-unknown-uefi(before) | aarch64-unknown-uefi(after) | |-------------|-----------------------------|----------------------------|------------------------------|-----------------------------| | overall | 11.90% (yellow) | 16.30% (red) | 12.20% (yellow) | 16.30% (red) | | functions | 2.60% (green) | 11.40% (yellow) | 2.80% (green) | 11.40% (yellow) | | exprs | 12.40% (yellow) | 17.00% (red) | 12.60% (yellow) | 17.00% (red) | | item_impls | 12.50% (yellow) | 13.80% (yellow) | 13.80% (yellow) | 13.80% (yellow) | | item_traits | 12.10% (yellow) | 13.00% (yellow) | 13.00% (yellow) | 13.00% (yellow) | | methods | 5.60% (green) | 6.60% (green) | 5.60% (green) | 6.60% (green) |- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How this was tested
Verified booting to UEFI shell from Q35, SBSA
Integration Instructions
All consumers of Patina will need to pick the newer Patina version when published and also should update their R-EFI version to 6.0.0.
- Removal of the
Full Changelog: patina-v21.2.0...v22.0.0
patina-v21.2.0
What's Changed
-
[REBASE \& FF] Add Stack Overflow Hint in Exception Handlers @os-d (#1554)
Change Details
## Description
Stack overflows show up as page faults in the exception handler, which can be hard to distinguish from other kinds of page faults. This PR contains three commits to provide a hint that a stack overflow occurred.
x64: IDT: Use a Separate Stack for Page Fault Exceptions
Currently, only double faults use a separate stack. However, a stack overflow manifests as a page fault, so taking a stack overflow causes a double fault. This makes it harder to reason about what the fault was.
This commit instead using a separate stack for x64 page faults, aligning with the aarch64 side. This is in preparation for giving better information about stack overflows in the exception handlers.
exception handlers: Print Stack Overflow Hint
Currently, stack overflows show up as page faults in the exception handlers. This can make it hard to identify when a different page fault has occurred.
This commit introduces a heuristic to hint that a stack overflow likely occurred in the exception handler. It checks if the faulting address is on the same page as or one page lower than the stack pointer. In some cases, the stack pointer is incremented first, then data is written (in which case the faulting address is on the same page as the stack pointer) and in other cases the data is written before the stack pointer is decremented (so the faulting address is on the page below the stack pointer).
A pretty message is then printed to indicate a stack overflow occurred.
internal_cpu: Rename EfiExceptionStackTrace Trait
The EfiExceptionStackTrace trait is an internal trait that originally was just used so the common exception handler can use arch specific stack trace dumping.
However, this was expanded to also include dumping a page table walk, so the name is not accurate.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
In Q35 and SBSA testing stack overflows which now look like:
Integration Instructions
N/A.
-
patina: Add Memory Type Information HOB serialization to the SDK @makubacki (#1556)
Change Details
## Description
Adds a
HobSerDe::MemoryTypeInformationvariant so that GUID extension HOBs matchingMEMORY_TYPE_INFO_HOB_GUIDare serialized with their parsed payload instead of being collapsed into a genericGuidExtensionentry.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all
Integration Instructions
- N/A
-
Move Patina QEMU PR Validation workflows to patina-devops main branch @makubacki (#1555)
Change Details
## Description
The workflows were previously using a branch dedicated to creating the workflow. All of the changes are in main now, so the workflows can use the main branch instead.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
- All of the changes in the branch previously being used
patina_e2e_plat_validation
Integration Instructions
- N/A
-
Minor Test Bug Fix: Initialize GCD before allocating SystemTable @vineelko (#1551)
Change Details
## Description
Initialize GCD before allocating SystemTable, otherwise below is the call flow causing stack corruption.
test_init_driver_services() EfiSystemTable::allocate_new_table() EfiRuntimeServicesTable::allocate_new_table() Box::new_in(...) Box::try_new_uninit_in(...) uefi_allocator::...::allocate() fixed_size_block_allocator::...::allocate() self.allocate_from_gcd() // Attempts to allocate from uninitialized GCD!- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo nextest run driver_services::tests::test_init_driver_servicesIntegration Instructions
NA
-
patina\_internal\_collections: Replace array\_windows with windows (MSRV 1.89.0 compat) @makubacki (#1547)
Change Details
## Description
array_windowswas introduced in Rust 1.94 and to patina in commit 856bda1, our MSRV is 1.89.Replace
array_windowswithwindowsand adjust the loop body accordingly to pass the MSRV check.
Issue before:
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all- MSRV Check workflow being added in https://github.com/OpenDevicePartnership/patina/pull/1546
Integration Instructions
- N/A
-
[mm] Do not introduce `talk_to_supervisor` bit @kuqin12 (#1544)
Change Details
## Description
Even the status buffer definition from basecore has this bit set:
However, with the current usage of MM communicate, this bit is not needed for the proper communication invocation:
In addition, the updated MM supervisor will no longer rely on this bit to differentiate the target channel, thus will not need this bit in the future, either.
This change removes the bit definition and the associated usage.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
This was tested locally and booted to Windows desktop. Pipeline should verify the same as well.
Integration Instructions
N/A
</blockquote> <hr> </details>
🚀 Features & ✨ Enhancements
-
patina\_debugger: Do not initialize the transport by default @cfernald (#1550)
Change Details
## Description
This change removes the default behavior to initialize the debugger transport serial port. Most systems will use a shared transport, and so the re-initialization is at best unnecessary. In some scenarios the Patina serial transport initialization may stomp on the existing configuration. This has caused confusion on multiple platforms during enablement. It is best to just skip unless requested. This commit inverts the default, deprecates
without_transport_init, and introduceswith_transport_initfor the rare platforms that require this.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Tested that Q35 & SBSA debuggers still function
Integration Instructions
Platforms using
without_transport_init()may safely drop that function call. There are no known platforms that require transport initialization, but if so those should now callwith_transport_init()as needed.</blockquote> <hr> </details>
🐛 Bug Fixes
-
Ensure cache consistency when changing to uncached memory [FF \& REBASE] @cfernald (#1540)
Change Details
## Description
patina_internal_cpu: Flush data cache which switching to uncached
When switching memory from a cached normal memory to a uncached or device
memory, the cache lines may stuill exist. Some platforms may snoop this
cache, but this is not guaranteed. To ensure data consistency accross all
platforms, the data cache should be explicitly cleaned.This commit adds a arc architectural callout for when...
patina-v21.1.1
What's Changed
-
Add PEI memory bin support [Rebase \& FF] @makubacki (#1486)
Change Details
## Description
Closes #1175
A few small commits for miscellaneous changes followed by the main commit for PEI memory bins.
sdk: Derive Clone and Copy for EFiMemoryTypeInformation
Allow
EfiMemoryTypeInformationto be easily duplicated, as it is a simple struct containing onlyCopytypes.
sdk: Add
EFI_MAX_MEMORY_TYPEandINVALID_INFORMATION_INDEXconstantsProvide a stable constant to represent the maximum valid EFI memory instead of hardcoding the value based on the last valid memory type.
INVALID_INFORMATION_INDEXis added as a sentinel value to indicate an invalid memory type index in the memory type information table.
sdk: Add page_shift_from_alignment() to base.rs
Adds the following helper for working with page operations:
page_shift_from_alignment(alignment)- Converts a page-aligned byte granularity to the corresponding bit shift value. This is useful for determining the shift needed to convert between addresses and page frame numbers.
patina_dxe_core: Add PEI memory bin support
Memory bins are pre-allocated, per-type regions of memory for EFI runtime memory types (
ReservedMemory,RuntimeServicesCode,RuntimeServicesData,ACPIMemoryNVS,ACPIReclaimMemory). By over reserving these regions at a fixed size, the memory map presented to the OS has a much greater chance of remaining stable across boots, which is required for S4 (hibernate) resume.This commit adds support for PEI memory bins allocated prior to DXE, such as in PEI, where the bin information is given to the Patina DXE core via HOBs.
A new module called
MemoryBinManageris added. It tracks bin state: preferred ranges, allocation statistics, and the memory type information published to the EFI config table in addition to related bin logic for when producing the EFI memory map.Two initialization paths are supported:
-
Path A - PEI-provided bins: A Resource Descriptor HOB with owner GUID
gEfiMemoryTypeInformationGuiddescribes a contiguous region PEI set aside for bins. Bins are divided within that region with per-type granularity. Free GCD pages within each bin range are claimed with ownership preservation so other allocators cannot expand into them. -
Path B - DXE-allocated bins: If a PEI region HOB does not exist, each bin type is allocated directly from the GCD using allocate-then-free with ownership preservation.
After bin initialization,
seed_bin_statistics_from_hobs()scans Memory Allocation HOBs whose Name matchesgEfiMemoryTypeInformationGuidto account for these potential PEI-phase allocations inside bin regions in initial bin statistics.On every
AllocatePages()/FreePages()call,record_allocation()andrecord_free()update the bin statistics for the relevant type. On free, if the pages fall within a bin range, GCD ownership is re-established to prevent other allocators from reclaiming those pages.GetMemoryMap()callsapply_bin_descriptors()after populating the EFI memory map. This post-processing step convertsEfiConventionalMemoryentries that overlap bin ranges to the bin's memory type, splitting entries at bin boundaries as needed. The buffer-size calculation is updated to account for up to two extra descriptors per active bin.install_memory_type_info_table()is updated to use the bin manager's data.The previous
reserve_memory_pages()API onPageAllocatorandSpinLockedFixedSizeBlockAllocatoris removed with logic moved intoMemoryBinManager.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
- PEI bins active and inactive on QEMU Q35
- Boot to EFI shell with SBSA
- Boot to OS on 64-bit Intel physical platform
- Note: Some additional physical platform testing with various features such as performance enabled is still in progress (PR in draft until done)
Integration Instructions
- If using edk2, ensure edk2 PR 12086 is present
- If using Mu, ensure mu_basecore PR 1759 is present
- Set the Feature PCD
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiMemoryBinsEnabletoTRUE - Refer to edk2 memory bin and Patina memory bin documentation for further details
PEI Bins Active Example
PEI Output: Bin allocation
AllocateMemoryTypeInformationBins: Attempting to allocate 0xDBB000 bytes for all memory bins InitializeMemoryTypeInformationBins: Memory bins address range 0x7E233000 - 0x7EFEDFFFPatina DXE Output
memory_binlog target at trace
Patina DXE Output: Init
Found Memory Type Information HOB (48 bytes, 6 entries) MemTypeInfo: ACPIMemoryNVS pages=128 (GCD alloc will use 128) MemTypeInfo: ACPIReclaimMemory pages=43 (GCD alloc will use 43) MemTypeInfo: ReservedMemoryType pages=1296 (GCD alloc will use 1296) MemTypeInfo: RuntimeServicesCode pages=256 (GCD alloc will use 256) MemTypeInfo: RuntimeServicesData pages=1792 (GCD alloc will use 1792) Memory Type Information HOB found with 6 entries. Found MemoryTypeInformation Resource Descriptor HOB: base=0x7E233000 length=0xDBB000 Found PEI bin region at 0x7E233000, length 0xDBB000. Initializing memory bins from PEI range: base=0x7E233000 length=0xDBB000 total_needed=0xDBB000 Bin[10] ACPIMemoryNVS: base=0x7EF6E000 max=0x7EFEDFFF pages=0x80 (128 pages) Bin[9] ACPIReclaimMemory: base=0x7EF43000 max=0x7EF6DFFF pages=0x2B (43 pages) Bin[0] ReservedMemoryType: base=0x7EA33000 max=0x7EF42FFF pages=0x510 (1296 pages) Bin[5] RuntimeServicesCode: base=0x7E933000 max=0x7EA32FFF pages=0x100 (256 pages) Bin[6] RuntimeServicesData: base=0x7E233000 max=0x7E932FFF pages=0x700 (1792 pages) Memory bins initialized from pre-allocated range. Reserving bin[0] ReservedMemoryType range=[0x7EA33000..0x7EF42FFF] (1296 pages) Reserved bin[0] ReservedMemoryType: claimed=1296 pages, existing=0 pages, conflicting=0 pages (of 1296 total) Reserving bin[5] RuntimeServicesCode range=[0x7E933000..0x7EA32FFF] (256 pages) Reserved bin[5] RuntimeServicesCode: claimed=256 pages, existing=0 pages, conflicting=0 pages (of 256 total) Reserving bin[6] RuntimeServicesData range=[0x7E233000..0x7E932FFF] (1792 pages) Reserved bin[6] RuntimeServicesData: claimed=1663 pages, existing=129 pages, conflicting=0 pages (of 1792 total) Reserving bin[9] ACPIReclaimMemory range=[0x7EF43000..0x7EF6DFFF] (43 pages) Reserved bin[9] ACPIReclaimMemory: claimed=43 pages, existing=0 pages, conflicting=0 pages (of 43 total) Reserving bin[10] ACPIMemoryNVS range=[0x7EF6E000..0x7EFEDFFF] (128 pages) Reserved bin[10] ACPIMemoryNVS: claimed=128 pages, existing=0 pages, conflicting=0 pages (of 128 total) PEI seed: RuntimeServicesData +1 pages at 0x7E931000. total=1 PEI seed: RuntimeServicesData +64 pages at 0x7E8F1000. total=65 PEI seed: RuntimeServicesData +64 pages at 0x7E8B1000. total=129 Seeded bin statistics from 3 PEI Memory Allocation HOBs.Patina DXE Output: Memory Map
- Note: There are some expected
EfiReservedMemoryTypeallocations of RT types intentionally outside bin ranges.
DEBUG - GetMemoryMap: processing bin[0] ReservedMemoryType range=[0x7EA33000..0x7EF42FFF] DEBUG - GetMemoryMap: processing bin[5] RuntimeServicesCode range=[0x7E933000..0x7EA32FFF] DEBUG - GetMemoryMap: processing bin[6] RuntimeServicesData range=[0x7E233000..0x7E932FFF] DEBUG - GetMemoryMap: processing bin[9] ACPIReclaimMemory range=[0x7EF43000..0x7EF6DFFF] DEBUG - GetMemoryMap: processing bin[10] ACPIMemoryNVS range=[0x7EF6E000..0x7EFEDFFF] EfiReservedMemoryType at 0 for 80 pages EfiBootServicesData at 50000 for 1 pages EfiConventionalMemory at 51000 for 54 pages EfiBootServicesData at 87000 for 1 pages EfiConventionalMemory at 88000 for 24 pages EfiConventionalMemory at 100000 for 1856 pages EfiBootServicesData at 840000 for 3520 pages EfiConventionalMemory at 1600000 for 498110 pages EfiBootServicesData at 7AFBE000 for 32 pages EfiConventionalMemory at 7AFDE000 for 17 pages EfiBootServicesData at 7AFEF000 for 96 pages EfiConventionalMemory at 7B04F000 for 4353 pages EfiBootServicesData at 7C150000 for 1848 pages EfiBootServicesCode at 7C888000 for 27 pages EfiBootServicesData at 7C8A3000 for 538 pages EfiBootServicesCode at 7CABD000 for 1162 pages EfiBootServicesData at 7CF47000 for 256 pages EfiBootServicesCode at 7D047000 for 102 pages EfiBootServicesData at 7D0AD000 for 42 pages EfiConventionalMemory at 7D0D7000 for 1 pages EfiBootServicesData at 7D0D8000 for 4 pages EfiBootServicesCode at 7D0DC000 for 73 pages EfiBootServicesData at 7D125000 for 5 pages EfiBootServicesCode at 7D12A000 for 214 pages EfiBootServicesData at 7D200000 for 2562 pages EfiBootServicesCode at 7DC02000 for 28 pages EfiBootServicesData at 7DC1E000 for 32 pages EfiBootServicesCode at 7DC3E000 for 365 pages EfiBootServicesData at 7DDAB000 for 5 pages EfiBootServicesCode at 7DDB0000 for 19 pages EfiBootServicesData at 7DDC3000 for 1 pages EfiBootServicesCode at 7DDC4000 for 1 pages EfiBootServicesData at 7DDC5000 for 5 pages EfiBootServicesCode at 7DDCA000 for 1 pages EfiBootServicesData at 7DDCB000 for 1 pages EfiBootServicesCode at 7DDCC000 for 1 pages EfiBootServicesData at 7DDCD000 for 41 pages EfiBootServicesCode at 7DDF6000 for 16 pages EfiBootServicesData at 7DE06000 ...
patina-v21.1.0
What's Changed
-
[REBASE \& FF] Use CRLF for Log Messages @os-d (#1520)
Change Details
## Description
Currently Patina only uses LF for log message line endings. In some terminal emulators, the implicit CR is not added and so the logs look stilted, e.g.
INFO - Some Log Message INFO - Oops, no CRThis contains two commits to fix that. One is in the SDK to convert strings printed with log::!() to have CRLF as the line ending. The other is use write!() with CRLF explicitly stated instead of writeln!() as that only does LF.
Note: This matches edk2 behavior and C drivers using DEBUG(()) already get CRLF as their line ending: https://github.com/tianocore/edk2/blob/b03a21a63e3bd001f52c527e5a57feddb53a690b/MdePkg/Library/BasePrintLib/PrintLibInternal.c#L1107-L1136
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
On a physical ARM64 platform where the terminal emulator does not implicitly add CR.
Integration Instructions
N/A.
</blockquote> <hr> </details>
-
patina\_test: Gate component doctest on the test-runner feature (MSRV 1.89.0 compat) @makubacki (#1533)
Change Details
## Description
The
componentmodule is only public whenfeature = "test-runner"is enabled (or when rustdoc is generating docs withcfg(doc)).The
Filterdoctest in components/patina_test/src/component.rs imports from it.cargo test --docfails prior to 1.92.0 with: "E0603: modulecomponentis private"The behavior appears to have changed somewhere between the 2025-09-16 (fail) and 2025-12-04 (pass) nightly releases specifically.
It appears the logic to discover what's reachable changed such that rustdoc only extracts doctests from items that are reachable in the same configuration the library is built with.
The current MSRV is 1.89.0, so this change uses
cfg_attrto ignore the test when thetest-runnerfeature is not enabled this allows the doctest to be compiled and run when the feature is enabled and gives compatibility with older toolchains.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
BEFORE
-
cargo +nightly-2025-09-19 test -p patina_test---- components\patina_test\src\component.rs - component::Filter (line 26) stdout ---- error[E0603]: module `component` is private --> components\patina_test\src\component.rs:28:18 | 5 | use patina_test::component::{TestRunner, Filter}; | ^^^^^^^^^ private module | note: the module `component` is defined here --> C:\src\patina\components\patina_test\src\lib.rs:21:1 | 21 | mod component; | ^^^^^^^^^^^^^ error[E0603]: module `component` is private --> components\patina_test\src\component.rs:28:18 | 5 | use patina_test::component::{TestRunner, Filter}; | ^^^^^^^^^ ------ enum `Filter` is not publicly re-exported | | | private module | note: the module `component` is defined here --> C:\src\patina\components\patina_test\src\lib.rs:21:1 | 21 | mod component; | ^^^^^^^^^^^^^ -
cargo +nightly-2025-12-12 test -p patina_test
all doctests ran in 1.15s; merged doctests compilation took 1.05s
AFTER
Both commands pass.
Integration Instructions
- N/A
-
component: Normalize core::any::type\_name output (1.89.0 MSRV compat) @makubacki (#1531)
Change Details
## Description
Resolves #1530
The strings emitted by
core::any::type_name::<T>()are explicitly best-effort and documented to vary between rustc releases. Per the official documentation:This is intended for diagnostic use. The exact contents and format
of the string returned are not specified, other than being
best-effort description of the type. For example, amongst the
strings that type_name::<Option>() might return are
"Option" and "std::option::Optionstd::string::String".The returned string must not be considered to be a unique
identifier of a type as multiple types may map to the same type
name. Similarly, there is no guarantee that all parts of a type
will appear in the returned string. In addition, the output may
change between versions of the compiler. For example, lifetime
specifiers were omitted in some earlier versions.The current implementation uses the same infrastructure as
compiler diagnostics and debuginfo, but this is not guaranteed.https://doc.rust-lang.org/beta/core/any/fn.type_name.html
The component infrastructure embeds those strings directly in user-visible diagnostics (error messages, panic payloads,
MetaData::name) and a handful of unit tests assert against their exact form. These unit tests currently fail on the MSRV 1.89.0 (which means consumers on 1.89.0) also see different strings.For example, recent/current toolchains render lifetime-parameterized generics as
Config<'_, u32>while older ones render the same type asConfig<u32>, and three tests incomponent::paramsandcomponent::struct_componenthardcode the more recent rendered form.This change introduces a small internal helper,
component::type_name, that wrapscore::any::type_nameand strips anonymous lifetime tokens before returning the string.This stabilizes user-visible diagnostics, which always read
Config<T>regardless of which toolchain compiled the build.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
- 1.89.0 equivalent:
cargo +nightly-2025-06-23 test -p patina
- Current (1.93.1):
cargo test -p patina
Integration Instructions
- N/A
-
pi\_dispatcher: Add UI Names to Prints @os-d (#1514)
Change Details
## Description
Currently when various states occur, such as drivers not dispatched, only the GUID of the driver is printed. This is useful, but also it is nicer to have the UI name printed so the GUID does not have to be cross-referenced.
This parses the UI name from the FV, if present, and also prints it.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
N/A.
Integration Instructions
N/A.
-
patina\_dxe\_core: Drop alloc\_error\_handler feature @os-d (#1525)
Change Details
## Description
The unstable alloc_error_handler feature is no longer required as the default_alloc_error_handler is stabilized. Patina is not doing anything special in this case, just panicking, so drop the unstable feature.
Closes #807
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Booting Q35 to shell.
Integration Instructions
N/A.
-
patina\_dxe\_core: Fix test check for new goblin @cfernald (#1527)
Change Details
## Description
The updated goblin added some internal checks for PE consistency that is failing for aarch64 with our test binary. This commit updates the check to allow for either the patina or the goblin failures to be accepted.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Local test execution
Integration Instructions
N/A
-
patina\_dxe\_core: install always-enabled silent logger for tests @makubacki (#1521)
Change Details
## Description
init_test_logger()is used by various modules to set up logging during tests.This was originally setup to use
env_loggerwhenRUST_LOGis set allowing simple control of log messages during interactive test runs and providing partial coverage of log messages in tests with the following description given (#1093):Since Patina relies on the
log::*API for logging, not
configuring a default logger can causelog::*calls ...
patina-v21.0.4
What's Changed
-
[REBASE \& FF] patina\_debugger: Don't Touch Uncached Memory By Default @os-d (#1503)
Change Details
## Description
This PR contains two commits:
Debugger: Move to PatinaPageTable Trait
Currently, the debugger uses the PageTable trait from patina_paging directly. On X64, this does not allow getting caching attributes since they are managed by MTRRs.
In preparation for using caching attributes in the debugger, move to the PatinaPageTable trait from patina_internal_cpu to get caching attributes uniformly.
This requires a new API in patina_internal_cpu to get the existing page table instead of creating a new one.
patina_debugger: Don't Access Uncached Memory By Default
It has been observed on physical platforms that WinDbg can request addresses in uncached memory. This results in the debugger attempting to read them. It uses the poke test to tell if this is safe. Sometimes the poke test works, but in one case, a machine check is generated to all cpus and the poke test cannot recover from this.
This changes this to check if memory is uncached. If so, the debugger will fail to read it. A new monitor cmd will toggle the ability of the debugger to read uncached memory or not.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
On a physical Intel platform that was getting a #MC when an uncached range was requested to be read by WinDbg and so the debugger read it because it was mapped. After this, the #MC doesn't occur.
Integration Instructions
If uncached memory must be touched from the debugger, call
!uefiext.monitor toggle_uncached_access(or otherwise call the monitor command) to toggle the ability.
-
components: Fix grammatical error in patina\_adv\_logger code example @makubacki (#1504)
Change Details
## Description
Fixes duplicate articles ("a the") that has been observed in logs from a few platforms copying the example as-is.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all
Integration Instructions
- N/A
📖 Documentation Updates
-
mdbook: Add training videos page @makubacki (#1507)
Change Details
## Description
Make Patina training video content conveniently accessible from the documentation by adding a training video page.
Closes #1432
Closes #1433
Closes #1434
If you're going to preview the page, view the rendered mdbook content locally with
mdbook serve ./docs(not the GitHub markdown page).- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
mdbook build ./docs
Integration Instructions
- N/A
-
mdbook: Update intro material, add mdbook-linkcheck, minor fixes [Rebase \& FF] @makubacki (#1499)
Change Details
## Description
mdbook updates that at a high-level:
- Add mdbook-linkcheck as a backend
- Update introduction material
- Makes some miscellaneous fixes
.github/workflows/publish-mdbook.yml: Do not attempt to deploy on forks
Most forks are likely not intending to publish the Patina mdbook
on their fork repository. Skip the deployment step on forks.
docs: Sort links in SUMMARY.md
Make links easier to find by sorting them alphabetically.
mdbook: Update introduction material
Moves content in the navigation bar to prioritize key information
when less familiar with the project.Adds a new page on "Patina in the UEFI Rust Ecosystem" to provide more
context on how Patina fits into the broader UEFI Rust ecosystem.Minor other edits in introduction material to improve flow and
readability.
mdbook: Minor fixes and updates
- dxe_core/memory_management.md: Fixed a couple of typos
- patina.md: Fixed trailing whitespace and updated current code
coverage in the "Notable DXE Core Features" section
mdbook: Add linkcheck backend
Adds the mdbook-linkcheck backend to check for broken links in the
book.https://github.com/Michael-F-Bryan/mdbook-linkcheck
- mdbook-linkcheck added to rust-toolchain.toml
- Configuration is added to book.toml
- A few cases where square brackets were not escaped in md files
are fixed - publish-mdbook.yml is updated to upload artifacts from docs/book/html
instead of docs/book because when mdbook has multiple output backends
([output.html] and [output.linkcheck]), it nests output in
subdirectories under the build dir (e.g., book/html/, book/linkcheck/)
instead of writing directly to book/.
Since mdbook-linkcheck can run after these changes without warnings,
it is not marked as optional in the book.toml configuration and it is
installed in the CI workflow, so it can run like the other mdbook
tools.A broken link will fail
mdbook build, with a clear error message
about which link is broken:(mdbook::renderer): Invoking the "linkcheck" renderer error: File not found: todo!() ┌─ introduction.md:118:4 │ 118 │ 4. [Contributing to Patina](todo!()) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File not found: todo!() error: File not found: ../does_not_exist.md ┌─ dev/documenting/reference.md:15:1 │ 15 │ [Test Broken Link](../does_not_exist.md) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File not found: ../does_not_exist.md Error: One or more incorrect linksNote: The
follow-web-linksdefault option is left to its default
value offalseto avoid linkcheck attempting to validate external
links and potentially causing CI failures due to external sites being
down or rate-limiting requests.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
mdbook build ./docs- Run cspell on
./docs
Integration Instructions
- N/A
Full Changelog: patina-v21.0.3...v21.0.4
patina-v21.0.3
What's Changed
-
[REBASE \& FF] Add Ability To Hide Debugger Monitor Commands @os-d (#1477)
Change Details
## Description
patina_debugger: Allow Hidden Monitor Cmds
Patina adds some monitor cmds that are not intended to be run by a user, such as the reload cmd. UefiExt is expected to run this in response to the !loadcore cmd.
However, the monitor help will show this as a valid command for a user to run, which is confusing. This hides that command as well as generically providing a mechanism to do so.
Drop GCD Debugger Monitor Cmd
A more advanced GCD command is available as of UefiExt v0.5.0. Drop the monitor cmd.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Tested by connecting Q35 and a physical Intel platform to the debugger and confirming the reload and gcd monitor cmds do not show up any longer but that !loadcore still works.
Integration Instructions
Upgrade to the latest UefiExt release to ensure the UefiExt GCD command is available.
</blockquote> <hr> </details>
-
Drop abi\_x86\_interrupt Unstable Feature @os-d (#1478)
Change Details
## Description
The need for this feature was dropped in f0132a3, however, the feature was not removed. Remove it.
Closes #812
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
N/A.
Integration Instructions
N/A.
</blockquote> <hr> </details>
-
Updated EFI\_CPU\_ARCH\_PROTOCOL to provide DmaBufferAlignment @rogurr (#1468)
Change Details
* Updated CPU trait to provide cache granule size * Added granule size reporting to x86, arm, and stub components * Updated publishing of CPU architecture protocol to include granule size.
Description
Addressing Issue #1466
Current Behavior: The code file patina_dxe_core\src\cpu\cpu_arch_protocol.rs is publishing an EFI_CPU_ARCH_PROTOCOL that has a field called DmaBufferAlignment to provide the size, in bytes, of the alignment required for DMA buffer allocations which is currently publishing a byte size of 0. The value should be the largest cache line size of any cache in the system per the UEFI PI spec, version 1.9, section II-12.3.1.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Found bug when porting Patina to a private build chipset reference and attempting to instantiate the NVME.
Integration Instructions
N/A
</blockquote> <hr> </details>
-
Components: Print Before Dispatching Components @os-d (#1473)
Change Details
## Description
Currently, Patina only prints after dispatching a component. However, it is more valuable in debug logs to print before dispatching a component so that if it crashes or hangs, it is easy to tell from the log which component it was.
This changes Patina to print before dispatching a component and to drop the print that prints after dispatching a component if it successfully returns and only log/debug_assert if the component returns with a failure.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Running Q35 and seeing the dispatch print occur before the component is dispatched:
and seeing the failure print/debug_assert when a component fails:
Previously this was seen:
Integration Instructions
N/A.
</blockquote> <hr> </details>
🐛 Bug Fixes
-
patina\_performance: Log cross-module phase markers @cfernald (#1476)
Change Details
## Description
The current implement does not log the cross-module markers for the transitions
from PEI to DXE. In EDK2, these are logged by the DXE Core. Here we need
to do this from the component because it initializes the underlying
functionality. This is not ideal, but it is the best we can do without
merging the performance component into the core.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Dumped the performance data using
dpin the shellIntegration Instructions
N/A
</blockquote> <hr> </details>
📖 Documentation Updates
-
[REBASE \& FF] Move Architectural Interfaces to SDK @os-d (#1475)
Change Details
## Description
This contains three commits:
Drop x86_64 crate
Patina has light usage of the x86_64 crate and the main usage is for the IDT and GDT, where a different, simplified design is desired.
This updates all consumers to not use the crate and drops the crate.
Use Standard Exception Handler for #DF
Currently, a feature from x86_64 was being used to have special handling for a double fault. However, this is not required as we can use our standard exception handler and identify this is a double fault.
This commit drops use of the feature and instead handles the #DF as we normally do.
Move Architectural Interfaces to SDK's Arch Mod
Centralize architectural interfaces in the SDK instead of sprinkling them around the code.
As a result, the aarch64-cpu crate is no longer required.
This also fixes hyperlinks in the copilot-instructions.md doc.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Booting to Windows and Linux on Q35 and SBSA. Booting to Windows on a physical Intel device. On Q35 and the physical Intel device, connecting the debugger to confirm the IDT changes are working correctly.
Tested the #DF changes by generating a double fault on Q35 and a physical Intel platform by changing RSP to a bad value then generating a #PF.
Integration Instructions
N/A.
Full Changelog: patina-v21.0.2...v21.0.3
patina-v21.0.2
What's Changed
-
patina\_internal\_cpu: Remove redundant architecture cfg gates @makubacki (#1471)
Change Details
## Description
The aarch64 and x64 modules are already gated by
target_archat the parent module level, so the inner#[cfg(all(not(test), target_arch = "aarch64/x86_64"))]checks simplify to just#[cfg(not(test))].- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all
Integration Instructions
- N/A
-
Add AI code review customization files [Rebase \& FF] @makubacki (#1460)
Change Details
## Description
Closes #1453
Adds project-level AI customization files to support AI-assisted code review.
These files encode Patina's domain-specific conventions so that AI reviewers can flag violations locally, prior to human review.
The files are layered:
-
Always-on instructions (.github/copilot-instructions.md): Covers global conventions across the codebase.
-
File-based instructions (.github/instructions/): Currently, provides component-specific instructions in components.instructions.md(applyTo: components/**) to supplement the global instructions. These load only when editing matching files to minimize token cost.
-
Review prompt file (.github/prompts/review.prompt.md): A reusable /review slash command that defines a structured review checklist. This is to provide a convenient way to reliably perform the same set of review steps. Delegates convention details to the always-on instructions to avoid duplication.
-
Reviewer agent (.github/agents/reviewer.agent.md): A read-only review persona restricted to
searchandreadtool sets (no edit or execute tools). Includes a handoff to the default agent for implementing fixes after review.
References:
-
VS Code Customization Overview: https://code.visualstudio.com/docs/copilot/concepts/customization
-
Custom Instructions: https://code.visualstudio.com/docs/copilot/customization/custom-instructions
-
Prompt Files: https://code.visualstudio.com/docs/copilot/customization/prompt-files
-
Custom Agents: https://code.visualstudio.com/docs/copilot/customization/custom-agents
-
Impacts functionality?
-
Impacts security?
-
Breaking change?
-
Includes tests?
-
Includes documentation?
How This Was Tested
- Use the "Patina Code Reviewer" locally
Integration Instructions
- N/A
This PR is in draft as it serves as a starting open to changes from others before publishing for broader review.
-
-
Safety \& UB Updates [Rebase \& FF] @makubacki (#1470)
Change Details
## Description
Fixes some safety and undefined behavior (UB) issues.
Reported by Claude with a UB/safety focused prompt. Manually filtered out less severe issues, false positives, and made fixes.
boot_services: Fix UB in create_event_ex() Option transmute
create_event_ex() transmuted Option to extern fn, dropping
the Option wrapper. Passing None would produce a null function pointer
typed as fn(...) which is instant UB since fn pointers are guaranteed
non-null.Align create_event_ex() with create_event() by preserving the Option
wrapper through the transmute chain. Update create_event_ex_unchecked()
to accept Option matching create_event_unchecked().
patina_dxe_core: Fix TplGuard Deref lifetime unsoundness
TplGuard's Deref and DerefMut returned references with the mutex's
lifetime ('a) instead of the guard's lifetime. This allowed extracting
references that outlive the guard, accessing mutex-protected data
without the lock held.Tie the returned reference lifetime to &self (the guard) instead of
'a (the mutex), matching the correct pattern used in sdk/patina's
TplMutexGuard.
patina_macro: Reject records without #[string_pool] at compile time
The SmbiosRecordStructure trait requires string_pool_mut() to return
&mut Vec. Records without a#[string_pool]field previously
used a static mut Vec which was mutable aliasing UB.Replace with a compile-time error requiring all records to declare a
#[string_pool]field for trait conformance, even if never populated.
This makes the invalid state unrepresentable rather than deferring to
runtime.
patina_sdk: Replace unreachable_unchecked() with unreachable in Service Deref
The downcast failure path used unreachable_unchecked() which is UB if
reached. While all intended construction paths guarantee correct types,
the public From<&'static dyn Any> impl accepts any dyn Any, creating a
reachable path to UB. Replace with unreachable! which provides a safe
panic with a diagnostic message if the invariant is ever violated.
boot_services: Use NonNull::dangling for ZST protocol references
The ZST protocol path returned &'static mut T from a shared static (),
creating aliasing &mut references across concurrent callers.Use NonNull::dangling() instead, which gives each caller a unique
aligned pointer without shared state.
runtime: Use raw pointers for linked list manipulation to avoid aliasing
When the runtime image/event lists are empty, the previous code created
two &mut references to the same image_head/event_head field on the same
line.Follow the advice in https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html#managing-stacked-borrows
and use pointers with addr_of_mut! throughout the list code.
fv: Use checked arithmetic for FV read address calculation
saturating_add() silently produces usize::MAX on overflow instead of
returning an error. A malformed FV with large LBA values could trigger
this, leading to a wild pointer in from_raw_parts().Switch to checked_add and propagate InvalidParameter on overflow.
fw_fs: Use read_unaligned() for FV header parsing from byte buffer
The byte buffer has alignment 1 but fv::Header contains u32/u64 fields
requiring higher alignment. Creating a reference via &*(ptr as *const
fv::Header) is UB on unaligned data.Use ptr::read_unaligned() to safely copy the header out of the buffer,
matching the approach used in patina_ffs.
hob_list: Guard against zero-length or overflowing HOB entries
A malformed HOB with length 0 causes an infinite loop, and a very
large length can wrap the pointer on 32-bit targets. Break out of
the parsing loop if the length is too small to contain a HOB header
or if the pointer addition overflows.
patina_mm: Use read_unaligned() for communicate buffer header parsing
The communicate buffer header fields were read with ptr::read() which
requires aligned pointers. The buffer comes from firmware memory that
may not be aligned to BinaryGuid or usize requirements depending on
the platform. Switch to ptr::read_unaligned() to be correct regardless
of alignment.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all
Integration Instructions
- N/A
-
Project convention updates [Rebase \& FF] @makubacki (#1469)
Change Details
## Description
A few miscellaneous changes to update code not complying with the project instructions in #1460.
patina_stacktrace: Replace mod.rs with named module files
Move x64/mod.rs to x64.rs and aarch64/mod.rs to aarch64.rs to follow
the project convention of using named module files instead of mod.rs.
patina_mm: Replace mod.rs in integration test with a named module file
Rename mod.rs to tests_root.rs and update the test entry point to use
a #[path] attribute redirect, eliminating mod.rs while preserving the
existing module hierarchy and crate-level import paths.
Replace unwrap() with expect() in a few locations
We prefer expect() in production code to provide more context in the
event of an error.Add descriptive messages to unwrap() calls in:
- rbt.rs: RBT rebalancing where sibling/parent nodes are guaranteed
to exist by the algorithm invariants - x64/runtime_function.rs: PE .pdata chunk reads validated by
preceding size checks - aarch64/runtime_function.rs: same pattern for AArch64 .pdata parsing
components: Enforce missing_docs lint in all component crates
Add #![deny(missing_docs)] to component crate lib.rs files to enforce
documentation requirements on public items.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all
Integration Instructions
- N/A
- rbt.rs: RBT rebalancing where sibling/parent nodes are guaranteed
patina-v21.0.1
What's Changed
-
[patina\_mm] refactor current folder structure to allow external consumption @kuqin12 (#1413)
Change Details
## Description
Current patina_mm carries some definitions that can be shared by external users (mm communication header, buffer status, etc).
This change moves those files to a sub-module that does not require alloc.
It also separates the supervisor related definitions into its own file.
Resolves #1437.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
This was tested with local builds and booted to UEFI shell.
Integration Instructions
N/A
📖 Documentation Updates
-
Add unsafe CPUID support for Rust `<=1.93` Toolchains @kouchekiniad (#1448)
Change Details
## Description
This change adds
unsafe { }wrappers around the patina_dxe_core's use of__cpuid, adding back support for Rust <= 1.93 toolchains where these are considered unsafe calls. To prevent warnings about these wrappers being unnecessary on Rust >= 1.94 (or >=nightly-2025-12-27) toolchains, this change additionally adds#[allow(unused_unsafe)]declarations to the wrappers.This change additionally updates the patina-mtrr dependency to a version which adds these same wrappers to it's own usage.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Built x86_64 Patina binaries successfully with Rust 1.93 and Rust 1.94 toolchains.
Integration Instructions
N/A
Full Changelog: patina-v21.0.0...v21.0.1
patina-v21.0.0
What's Changed
⚠️ Breaking Changes
-
[CHERRY-PICK] Merge major branch into main @Javagedes (#1445)
Change Details
## Description
Cherry-pick of breaking changes from major branch into main.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
N/A
Integration Instructions
Refer to Integration notes for:
-
[CHERRY-PICK] Merge major branch into main. @Javagedes (#1440)
Change Details
## Description
Cherry-pick of breaking changes from major branch into main.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
N/A
Integration Instructions
Refer to Integration notes for:
</blockquote> <hr> </details>
📖 Documentation Updates
-
Update synchronization documentation. @joschock (#1439)
Change Details
## Description
Cleans up and clarifies some elements of existing docs, adds a new section for rules of thumb for synchronization within Patina.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
Passes md lint.
Integration Instructions
N/A - documentation.
-
[CHERRY-PICK] Merge major branch into main. @Javagedes (#1440)
Change Details
## Description
Cherry-pick of breaking changes from major branch into main.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
N/A
Integration Instructions
Refer to Integration notes for:
</blockquote> <hr> </details>
Full Changelog: patina-v20.1.3...v21.0.0
patina-v20.1.3
What's Changed
-
pecoff: Miscellaneous fixes/updates for load\_resource\_section [Rebase \& FF] @makubacki (#1431)
Change Details
## Description
pecoff: Fix resource string offset and UTF-16LE comparison
The HII string lookup in
load_resource_sectioncalculated the string
data offset asname_offset + 1, butDirectoryStringhas a
2-byte length field (followed by the string data), so the correct
offset isname_offset + sizeof(DirectoryString)."Resource Directory String" is defined here in the PE/COFF spec:
https://learn.microsoft.com/windows/win32/debug/pe-format#resource-directory-string
The comparison constant used was
[0x00, 0x48, 0x00, 0x49, 0x00, 0x49]
which matched the shifted byte sequence from the wrong offset instead
of the correct UTF-16LE bytes for "HII" which is:
[0x48, 0x00, 0x49, 0x00, 0x49, 0x00].
pecoff: Advance iteration in resource directory parsing
Today, the code in
load_resource_sectioniterates the number of
named entry times but doesn't actually update thedirectory_entry
to the offset for the current iteration. This change makes that
adjustment.This worked before because images with HII resource sections either
had a sinlge section or the HII section was the first section.I couldn't find any existing images that have more than one resource
directory entry, so I had to create a simple section with two entries
in the unit test.
pecoff: Prevent potential overflow in load_resource_section
Since
resource_directory_string.lengthis au16, a.length
value of > 32767 could cause an overflow when multiplied by 2
since the multiplication done before the cast tousize.This change updates the code to perform the multiplication after the
cast tousizewhich is the type the result is assigned to
(the type ofname_end_offset).
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all- Q35 and SBSA boot to EFI shell
Integration Instructions
- N/A
-
[patina\_internal\_cpu] remove alloc usage @kuqin12 (#1423)
Change Details
## Description
Patina internal CPU hosts the interrupt manager and other fundamental functionalities, which should not work on top of the allocator.
Admittedly, the current crate can support more advanced components that works on top of exception forwarding, but this should not be treated as a required dependency.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
This was tested on QEMU Q35 and booted to UEFI shell.
Integration Instructions
N/A
</blockquote> <hr> </details>
-
patina\_dxe\_core: Add DxeDispatch service for driver dispatch @kat-perez (#1421)
Change Details
## Description
Add a
DxeDispatchservice trait in the SDK and aCoreDxeDispatch
implementation in patina_dxe_core that delegates to the PI dispatcher.
The service is registered alongside other core services (MemoryManager,
PerfTimer, etc.) and consumed via dependency injection by components
that need to trigger driver dispatch passes.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
- Built SBSA DXE core binary with
BootDispatcher+SimpleBootManagerconsuming the service via DI - Booted Windows ARM64 under QEMU SBSA-ref with Patina BDS handling the full boot flow
- Connect-dispatch interleaving discovered AHCI device, expanded partial device path, loaded Windows bootloader, ExitBootServices completed
- 106 on-system unit tests passed (0 fails)
Integration Instructions
The
DxeDispatchservice is registered automatically by the DXE core.
Components consume it via dependency injection:fn entry_point(self, dxe_dispatch: Service<dyn DxeDispatch>) -> Result<()> { dxe_dispatch.dispatch()?; Ok(()) }
</blockquote> <hr> </details>
-
patina\_mm: Make MmCommunicator::mm\_executor non-dyn [Rebase \& FF] @makubacki (#1428)
Change Details
## Description
Two commits to address backlog issues.
patina_mm: Drop communicator pointer
Removes the
communicatorpointer from theProtocolNotifyContext
struct and referencing code. This pointer has not been used since a
refactor and is only used for a debug print.
patina_mm: Make MmCommunicator::mm_executor non-dyn
Closes #874
Replaces
Box<dyn MmExecutor>with a generic type parameter
(E: MmExecutor + 'static) that defaults toRealMmExecutor. This
keeps the expected default executor for non-test scenarios while
allowing test code to specify other executor types without needing
to box them.Generic methods (e.g.
with_executor()andset_test_comm_buffers())
are split into a separateimpl<E>block since#[component]applies
to the default-type impl only.DebugandMmCommunicationimpls are
similarly updated to be generic overE.Unit and integration tests now use concrete executor types directly
instead of boxing them.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all- QEMU Q35 boot to EFI shell using
patina_mmcomponents
Integration Instructions
- Review the changes to the
MmCommunicatorpublic structure to determine if any code that might be using it needs to be updated.
Note: This is not being marked as a breaking change per Patina "semantic preserving" guidelines.
-
perf: Simplify generic type parameters in performance entry points @makubacki (#1426)
Change Details
## Description
Closes #750
Reduces the number of generic type parameters in performance component functions by dropping the
BB/BandRR/Rindirection pattern.That pattern used a wrapper type (
BB: AsRef<B>) alongside its underlying trait (B: BootServices). TheAsRefindirection is not needed sinceStandardBootServicesandMockBootServicesboth implementBootServices + Clone.Generic reductions:
_entry_point()from 6 generics (BB, B, RR, R, P, F) to 4 (B, R, P, F)report_fbpt_record_buffer()from 5 generics (BB, B, RR, R, F) to 3 (B, R, F)fetch_and_add_mm_performance_records()from 3 generics (BB, B, F) to 2 (B, F)MmPerformanceEventContext()from 3 generics (BB, B, F) to 2 (B, F)
Also:
- Replaces
.as_ref().method()calls withdirect .method()calls - Replaces
BB::clone(&x)withx.clone() - Removes
Rcwrapping from performance tests
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
cargo make all- Q35 boot with performance component enabled
Integration Instructions
- N/A
Note: This is to close an old backlog item as mentioned in the link GitHub issue.
-
.github: Pass head-sha to QEMU validation workflows @makubacki (#1425)
Change Details
## Description
A new
head-shainput parameter was added to the QEMU validation workflows. This allows the workflow to have access to the head SHA of the PR, which is useful for applying status check results.- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
- patina fork
Integration Instructions
-
N/A - Only impacts local workflows in repo CI
</blockquote> <hr>
-
.github: Add integration changes for PR validation status check @makubacki (#1424)
Change Details
## Description
Contributes to OpenDevicePartnership/patina-devops#108
Passes
head-shaandconclusionargs to the QEMU post-processing workflow.This allows the post-processing workflow to set commit status including cases like when the workflow is cancelled.
- Impacts functionality?
- Impacts security?
- Breaking change?
- Includes tests?
- Includes documentation?
How This Was Tested
- Run success...