The various cores all attempt to print the EfiFileName when
loading/dispatching drivers, but they are not unified on
approach. This commit ensures they are using the same buffer
size and the loop parsing variables are unsigned, as we should
not have a negative index.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
Today, DXE/PEI/SMM Core's image loaders only print driver load messages
if debug code is enabled. However, these are some of the most
important prints in the codebase: on a given system even if you
have nothing else to debug with, you can see the last driver
executed.
Debug code blocks are used to skip logic that only exists for
debug purposes and wastes time on a release build. However, the
logic to print a line and determine the filename from the PDB
is not extensive and provides critical information, so it is
inappropriate to wrap in a debug code section.
Platforms can still choose to disable logging at DEBUG_INFO/DEBUG_LOAD
and will not see the error messages.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
Currently, if the DebugClearMemory bit is set in the
PcdDebugPropertyMask, CoreConvertPagesEx will attempt to write
a pattern to the pages being freed. However, it does not check
that the page is writeable, which will cause a page fault if not.
Furthermore, if NX protections are not enabled, the core does not
ensure that any freed pages are RW, which is the state expected
when they are allocated next. If they are not RW, the allocating
driver will crash trying to use them.
This patch updates the page freeing code to query the memory
attributes protocol, if present, for the attributes. If this call
fails or the attributes are not RW at a minimum, the core leaks
the memory (returning success to the caller). If the memory
attribute protocol is not present (either because a platform doesn't
produce it or it is before the protocol has been produced, the core
continues with freeing memory. This is either before the CPU Arch
protocol is available (so drivers can't change memory attributes) or
otherwise matches existing behavior. This was deemed the best
approach to let memory that can't be guaranteed to be RW leak
instead of letting a driver crash when allocating it. It was deemed
less brittle to simply leak the memory instead of attempting to
change the attributes.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
Currently DxeIpl attempts to set page 0 to all 0's and to
create a memory allocation HOB for it. However, DxeIpl will
also unmap the page when mapping page tables and if null
detection is not enabled, DxeCore will set the page to 0,
regardless of allocation status.
Because no consumers are using the memory allocation HOB for
page 0, drop it. Instead, ensure that PeiCore and DxeCore do
not allow allocating page 0; it should always be reserved for
null pointer detection. It also complicates the story for
platforms that are attempting to audit the system and ensure that
no modules are using page 0. With these memory allocation HOBs
in place, it is difficult to tell if it is simply DxeIpl who
has allocated the memory or another module.
This commit drops the memory allocation HOB publishing and ensures
that DxeCore and PeiCore do not allocate page 0. DxeCore already
will not allocate page 0 to callers of AllocatePages who call with
a type other than AllocateAddress, this just changes so that
AllocateAddress cannot allocate at page 0 (which if null detection
is enabled will cause a page fault). PeiCore does not have
AllocateAddress and so this ensures standard allocations do not
receive page 0.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
This change adds a check to ensure the incoming buffer is correctly using
MM communicate v3 header before dereferencing the content.
Signed-off-by: Kun Qin <kun.qin@microsoft.com>
The DebugImageInfoTable contains an array of image info
structures. The current implementation removes an entry by
freeing the info structure and putting NULL in that entry of
the array. It then decrements the table size tracked in the table.
However, the array is invalid at this point, it contains a NULL
entry, which the UEFI spec does not envision and it contains a valid
entry past the end of the array as tracked in the spec defined config
table. If the table is consumed at this point it can lead to an
invalid assessment of the image state, which defeats the purpose of
the table.
When a new info structure is added, it then scans for the first NULL
entry adds a pointer to the new info structure there and increments
the table size to cover the entrythat was formerly past the end of
the array.
The current implementation requires that once an unload happens,
more loads happen than unloads and that the last operation is not
an unload (which won't be true in the shell, e.g.). This is
needlessly complex, as the order of the table doesn't matter
(and in fact this implementation doesn't preserve image loading
order either).
This patch updates the removal function to free the desired
info structure, move the last entry of the array to this freed
spot, mark the last entry as NULL, and decrement the table count.
The entry addition function then just always puts a new entry at
the end of the array, expanding it as necessary. This simplifies
the logic and covers the gaps that were present.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
Commit 5ccb5fff02 updated the
image memory protection code to set the protection
attributes through the GCD instead of directly to the page
table. However, this code had an implicit assumption that
each base address passed to it was the beginning of a GCD
descriptor. On the virtual platforms tested, this was the case.
However, on a physical platform, a scenario was encountered
where the base address was not the beginning of a GCD
descriptor, thus causing memory attributes to be applied
incorrectly.
This assumption does not need to be made and this patch
updates the code to handle the case where the base address
is not the beginning of a GCD descriptor.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
CoreDumpGcdMemorySpaceMap() gets called on every update to
the GCD, but it only prints if DEBUG_GCD is set. However,
the compiler is not smart enough to remove all of this logic
if we are not printing anything, so we end up needlessly
allocating memory for the copy of the map and spending many
cycles looping through each entry, only to not print anything.
This code is compiled out on release builds, but slows down
debug builds that aren't printing at DEBUG_GCD level.
This patch updates CoreDumpGcdMemorySpaceMap() to shortcircuit
and immediately exit if DEBUG_GCD is not set. It also adds
the same logic to CoreDumpGcdIoSpaceMap(), which is called
less frequently, but has the same issue.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
Today, SetUefiImageMemoryAttributes calls directly to the
CPU Arch protocol to set EFI_MEMORY_XP or EFI_MEMORY_RO on
image memory. However, this bypasses the GCD and so the GCD
is out of sync with the actual state of memory.
This can cause an issue in the scenario where a new attribute
is being set (whether a virtual attribute or a real HW attribute),
if the GCD attributes are queried for a region and the new attribute
is appended to the existing GCD attributes (which are incorrect),
then the incorrect attributes can get applied. This can result in
setting EFI_MEMORY_XP on code sections of images and causing an
execution fault.
This patch updates SetUefiImageMemoryAttributes to call into the
GCD to update the attributes there and let the GCD code call into
the CPU Arch protocol to update the page table.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
The print that describes memory attributes being applied to image
memory sections is currently at info level and very noisy, being
printed multiple times per image.
Reduce this to the verbose logging level.
Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
With current implemenation, all 3 SmmCommunication* functions go through
the same routine, which will dereference the incoming pointer to inspect
whether this is a V3 buffer or not.
However, the caller always pass in the physical addresses, which could
cause the system to page fault after OS take over the runtime control.
This change reverted the common routine to its previous form to handle MM
communicate v1 and v2. Additionally, a specific communicate function for
v3 was created to support MM communicate v3.
Co-authored-by: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Kun Qin <kun.qin@microsoft.com>
Hot Pluggable resource attribute was introduced in UEFI 2.11 and PI 1.9
specifications.
This type should have an entry in the Attribute Conversion Table.
Signed-off-by: Sachin Ganesh <sachinganesh@ami.com>
Add the EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE resource attribute as
per the PI 1.8 spec. This flag is used to indicate that the memory
should be treated as special purpose memory (SPM).
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
Handle.c:1302:24: error: 'Prot' may be used uninitialized
in this function [-Werror=maybe-uninitialized]
*Interface = Prot->Interface;
~~~~^~~~~~~~~~~
cc1: all warnings being treated as errors
Signed-off-by: Mike Maslenkin <mike.maslenkin@gmail.com>
Dispatcher.c:1639:34: error: 'FvMigrationFlags' may be used uninitialized
in this function [-Werror=maybe-uninitialized]
(((FvMigrationFlags & FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY) == 0) ||
~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
Signed-off-by: Mike Maslenkin <mike.maslenkin@gmail.com>
PeiCoreBuildHobHandoffInfoTable() always returns EFI_SUCCESS, and also
its return is not consumed at all, so this patch removes return for
PeiCoreBuildHobHandoffInfoTable().
Signed-off-by: Star Zeng <star.zeng@intel.com>
Add a late initialize in DxeMain for the debug agent. This is required
for the debug agent to be able to setup events to handle image loads,
exit boot services, and other important callbacks.
Define a reinitialize debug agent.
Signed-off-by: Aaron Pop <aaronpop@microsoft.com>
The scratch buffer (EfiBootServicesData) is assigned to extract DXE FVs
that are compressed. The matching decompression library returns the buffer
size as below. The buffer is no longer used after completing extraction.
Need to free the buffer to optimize memory allocation and usage.
BaseUefiDecompressLib : sizeof (SCRATCH_DATA)
LzmaCustomDecompressLib : SCRATCH_BUFFER_REQUEST_SIZE (64KB)
BrotliCustomDecompressLib : From EncodeData header (usually, xxMB checked)
In case of Brotli decompression, it is found that a big chunk of memory is
required, based on EncodeData header. (e.g. a 4MB compressed FV reports
about 39MB scratch size)
Signed-off-by: Phil Noh <Phil.Noh@amd.com>
According to UEFI spec 2.10 errata A section 7.4.6
"All events from the EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES and
EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event notification groups as well
as events of type EVT_SIGNAL_EXIT_BOOT_SERVICES must be signaled
before ExitBootServices() returns EFI_SUCCESS. The events are only
signaled once even if ExitBootServices() is called multiple times."
So keep track of whether ExitBootServices() has been called, and signal
the event group EFI_EVENT_GROUP_BEFORE_EXIT_BOOT_SERVICES only the first
time around.
EFI_EVENT_GROUP_EXIT_BOOT_SERVICES will only be signalled if
ExitBootServices() is going to run to [successful] completion, after
which calling it a second time is not possible anyway. So for this case,
no special handling is needed.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4873
Currently the function does not cover the 5 level paging case. it will
casued pagetable protection region set incorrectly. This patch do the
enhancemant and with the patch protection region has been set correctly.
Signed-off-by: Ning Feng <ning.feng@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Instead of using bit shift operations, it is preferable to use BaseLib
bit shift functions to prevent compilers from inserting intrinsics.
Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
I recently ran into an AllocatePages() hang. It turns out that
AllocatePages() does not account for the Memory Allocation HOB when it
makes the decision of allocating out of free memory.
Here is the scenario:
FreeMemoryTop - 0x71C03000
FreeMemoryBottom - 0x71BDBFD8
=> We have 159,784 bytes left => ~39.0098 pages left.
We attempt to allocate 39 pages. There are enough pages left but
allocating those pages requires to allocate a Memory Allocation HOB
which needs an extra 48 bytes. But once the pages are allocated,
there are only 40 bytes left.
In addition to taking into account the Memory Allocation HOB size,
this commit reverses the condition to keep it simple.
Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
Check that the next map entry is valid before dereferencing to merge the
guard pages. If the final entry is at the end of a page with no valid page
following it, then this can cause an access violation.
Signed-off-by: Kenneth Lautner <kenlautner3@gmail.com>
Comments out a redundant call to RestoreTpl(). While this does not
technically violate spec on raise/restore TPL, TPL should already be at
the specified level. This extra call introduces an asymmetry between
RaiseTpl and RestoreTpl calls, which makes analysis of TPL correctness
more difficult and hampers certain non-standard TPL usages that some
platforms require. Additionally, the two TPL variables were renamed to
provide context for each of them.
Signed-off-by: Kenneth Lautner <kenlautner3@gmail.com>
REF : https://bugzilla.tianocore.org/show_bug.cgi?id=4817
Before entering BIOS setup, CoreValidateHandle function executed
over 600,000 times during BDS phase on latest 8S server platform.
In CoreValidateHandle function, current implementation will go
through the doubly-linked list handle database in each call, and
this will have big impact on boot performance.
The optimization is using Red-black tree to store the EFI handle
address when insert each EFI handle into the handle database, and
remove the handle from Red-black tree if the handle is removed
from the handle database. CoreValidateHandle function changed to
go through the Red-black tree.
After verification on latest 8S server platform, BDS boot time can
save 20s+ after this change.
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Andrew Fish <afish@apple.com>
Tested-by: Xiaoqiang Zhang <xiaoqiang.zhang@intel.com>
Currently whenever gDS->SetMemorySpaceCapabilities() is called, it
attempts to set the corresponding attributes in the gMemoryMap
descriptor. However, gMemoryMap only contains entries from GCD types
EfiGcdMemoryTypeSystemMemory and EfiGcdMemoryTypeMoreReliable, so
for all other types a failure is reported in the code. This is a
failure that is expected, so it does not provide value and can
lead to real failures being ignored.
This patch updates the gDS->SetMemorySpaceCapabilities() code to
only call into updating gMemoryMap if the GCD type is SystemMemory
or MoreReliable, to avoid spurious errors being reported. This
also avoids the expensive operation of searching through gMemoryMap
for entries we know we will fail to find.
Signed-off-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Per UEFI spec 2.10 section 4.6.3 EFI_MEMORY_ATTRIBUTES_TABLE,
"The Memory Attributes Table is currently used to describe memory
protections that may be applied to the EFI Runtime code and data
by an operating system or hypervisor. Consumers of this table must
currently ignore entries containing any values for Type except for
EfiRuntimeServicesData and EfiRuntimeServicesCode to ensure
compatibility with future uses of this table."
However, the current MAT code also enforces attributes for
EfiMemoryMappedIo and EfiMemoryMappedIoPortSpace, which it should
not be. Per
https://edk2.groups.io/g/devel/topic/patch_v1_mdemodulepkg/105570114?p=,,,20,0,0,0::recentpostdate/sticky,,,20,2,0,105570114,
it was suggested to remove these types from the MAT logic.
This patch removes EfiMemoryMappedIo and EfiMemoryMappedIoPortSpace
from the MAT logic in accordance with the UEFI spec.
Signed-off-by: Oliver Smith-Denny <osde@linux.microsoft.com>
REF : https://bugzilla.tianocore.org/show_bug.cgi?id=4750
Migrate the FV that doesn't contain the currently executing PEI Core
when permanent memory is initialized but PEI Core is still potentially
running from faster memory (Tepmorary RAM). This may reduce the time
required to migrate FVs to permanent memory. The FV containing PEI
Core is migrated after the PEI Core reentry when it is executed from
permanent memory.
This may or may not improve performance depending on the behavior of
temporary RAM and the actual performance changes must be measured with
the feature enabled and disabled.
This migration algorithm is only used for FVs specified in the
gEdkiiMigrationInfoGuid HOB and built with flag
FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY.
Signed-off-by: Awiral Shrivastava <awiral.shrivastava@intel.com>
Now that all of the EFI_MEMORY_* defines live in the
EFI_MEMORY_TYPE enum, remove the old defines.
Signed-off-by: Oliver Smith-Denny <osde@linux.microsoft.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2411
With Use-After-Free heap guard feature enabled, the DxeCore would blindly
attempt to "level-up" when the `GuardAllFreedPages` inspect a non-max
level table entry from the last loop. This could cause the next round of
inspection to dereference a potentially null pointer and as such causing
a page fault.
This change adds a null pointer check to prevent such case from happening.
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Kun Qin <kun.qin@microsoft.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4653
In DxeIplFindDxeCore function, there exists different behavior between
Debug and Release built BIOS. This change is used to unify both of
the code flow and fix the potential overflow of "Instance" variable.
In this change,
[1] Move the ASSERT_EFI_ERROR (Status) in failure to find DxeCore
in any firmware volume condition.
[2] Break the while-loop when not found required DxeCore.
This would make the Instance variable not overflow in while-loop.
[3] Add the CpuDeadLoop () in the end of the function and do not
return since DxeCore is mandatory for the following booting
to hand-off the PEI phase to DXE phase.
[4] In case of the CpuDeadLoop () is de-assert by debugger,
return the NULL pointer.
Signed-off-by: Jason1 Lin <jason1.lin@intel.com>
Removes an assert if PeiAllocatePool() fails to allocate memory to
defer error handling to the caller so the error can be handled
gracefully or asserted at that location which is more specific to
the call that led to the allocation.
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
HBM/CXL memory systems are treated as special purpose memories. In many
cases it is desirable not to use special purpose memory for regular edk2
usages as these memories (HBm/CXL) are either meant for special purposes
or are less reliable to be used. Until such memory systems evolve and
we have better clarity from UEFI spec, avoid using them for edk2
boot memory purposes.
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Oliver Smith-Denny <osde@linux.microsoft.com>
Signed-off-by: Dhaval Sharma <dhaval@rivosinc.com>
Co-authored-by: Tim Wawrzynczak <tim@rivosinc.com>
Add a new entry into GCD attribute conversion table to convert
EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE to EFI_MEMORY_SP.
Signed-off-by: Du Lin <du.lin@intel.com>
The local variable 'WillReturn' was being used without prior
initialization in some code paths.
This patch ensures that 'WillReturn' is properly initialized
to prevent undefined behavior.
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
This patch fix a use-after-free issue where unregistering an
SMI handler could lead to the deletion of the SMI_HANDLER while it is
still in use by SmiManage(). The fix involves modifying
SmiHandlerUnRegister() to detect whether it is being called from
within the SmiManage() stack. If so, the removal of the SMI_HANDLER
is deferred until SmiManage() has finished executing.
Additionally, due to the possibility of recursive SmiManage() calls,
the unregistration and subsequent removal of the SMI_HANDLER are
ensured to occur only after the outermost SmiManage() invocation has
completed.
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
The functionality to create and delete Image Records has been
consolidated in a library and ensured that MemoryProtection.c's
usage is encapsulated there.
This patch moves MemoryProtection.c to reuse the code in the lib
and to prevent issues in the future where code is updated in one
place but not the other.
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Taylor Beebe <taylor.d.beebe@gmail.com>
Acked-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Oliver Smith-Denny <osde@linux.microsoft.com>