DasharoPayloadPkg/DasharoPayloadPkg.dsc: add -mno-mmx -mno-sse

In the spirit of commit 4a8266f570 ("OvmfPkg: Work around issue seen
with kvm + grub2 (efi)") build the package without using MMX and SSE
instruction sets.

This is done to work around GCC generating MOVAPS (aligned move) to
save/restore MMX registers in functions of EFI runtime services and
causing a misaligned accesses by not keeping the stack aligned to 16
bytes.  Saving/restoring the registers is a side-effect of MS ABI
calling conventions on those functions.  The misaligned accesses are a
problem when an OS configures CPU to trap such accesses like FreeBSD
kernel does.

Had to make an exception for CrScreenshotDxe which is used before any OS
had a chance to run.  A cleaner fix is to inline one function there, so
it compiles with `-mno-mmx -mno-sse`, but then need to fork that
submodule or send the change upstream first.

The original idea was to add flags related to alignment, but that did
not produce expected results.  The alignment looked correct only with
`-mpreferred-stack-boundary=4 -mincoming-stack-boundary=3` which is
basically lying that the caller uses 8 byte alignment when it's not the
case (UEFI requires the caller to align the stack to 16 bytes) and
doesn't seem to be a nice workaround.  Also couldn't make GCC generate
MOVUPS (unaligned move) instead of MOVAPS.

Not using MMX/SSE in the firmware should not affect functionality and
reduces stack usage while getting rid of lots of moves.

Example of bad alignment:
```
00000000000011a3 <VariableServiceGetVariable>:
    11a3:       41 57                   push   %r15
    11a5:       41 56                   push   %r14
    11a7:       41 55                   push   %r13
    11a9:       49 89 d5                mov    %rdx,%r13
    11ac:       41 54                   push   %r12
    11ae:       55                      push   %rbp
    11af:       57                      push   %rdi
    11b0:       56                      push   %rsi
    11b1:       53                      push   %rbx
    #                  should really be $0x100 vvvvv
    11b2:       48 81 ec f8 00 00 00    sub    $0xf8,%rsp
    # alternatively, need `and $0xfffffffffffffff0,%rsp` here
    11b9:       48 85 d2                test   %rdx,%rdx
    11bc:       0f 94 c0                sete   %al
    11bf:       4d 85 c9                test   %r9,%r9
    11c2:       0f 29 74 24 50          movaps %xmm6,0x50(%rsp)
```

Some more details can be read in [0].  This behaviour may very well be a
bug in GCC, see [1], [2], [3], [4] for similarly-looking issues.

[0]: https://github.com/Dasharo/dasharo-issues/issues/1001#issuecomment-3307379806
[1]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49001
[2]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56597
[3]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54412
[4]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90065

Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
This commit is contained in:
Sergii Dmytruk
2025-09-26 14:28:45 +03:00
parent fa9e6087d5
commit 89bbcfa1aa
+6 -2
View File
@@ -146,7 +146,7 @@
DEFINE NETWORK_IPXE = FALSE
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -Wno-stringop-overflow
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES -Wno-stringop-overflow -mno-mmx -mno-sse
!if $(USE_CBMEM_FOR_CONSOLE) == FALSE
GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG
@@ -858,7 +858,11 @@ OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrd
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
DasharoPayloadPkg/BlSupportDxe/BlSupportDxe.inf
CrScreenshotDxe/CrScreenshotDxe.inf
CrScreenshotDxe/CrScreenshotDxe.inf {
<BuildOptions>
# floats are used for encoding PNGs from firmware's UI
GCC:*_*_*_CC_FLAGS = -mmmx -msse
}
#
# SMBIOS Support