Skip to content

ovmf build fails #2

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

Closed
churkanerusskaya opened this issue Dec 7, 2020 · 4 comments
Closed

ovmf build fails #2

churkanerusskaya opened this issue Dec 7, 2020 · 4 comments

Comments

@churkanerusskaya
Copy link

Hello!

I am trying to compile the components for ses-es using the build script, however I get the same error every time :

...

nice build -q --cmd-len=64436 -DDEBUG_ON_SERIAL_PORT=TRUE -n 32 -t GCC5 -a X64 -p OvmfPkg/OvmfPkgX64.dsc
Build environment: Linux-4.15.0-126-generic-x86_64-with-Ubuntu-18.04-bionic
Build start time: 20:55:58, Dec.07 2020

WORKSPACE = /root/AMDSEV/build/ovmf
EDK_TOOLS_PATH = /root/AMDSEV/build/ovmf/BaseTools
CONF_PATH = /root/AMDSEV/build/ovmf/Conf
PYTHON_COMMAND = /usr/bin/python3.6

Processing meta-data ....... done!
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeHobLib/DxeHobLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiLib/UefiLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf [X64]
Building ... /root/AMDSEV/build/ovmf/PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BasePrintLib/BasePrintLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxePcdLib/DxePcdLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseLib/BaseLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf [X64]

build.py...
: error 7000: Failed to execute command
make tbuild [/root/AMDSEV/build/ovmf/Build/OvmfX64/DEBUG_GCC5/X64/MdePkg/Library/BaseCpuLib/BaseCpuLib]

build.py...
: error 7000: Failed to execute command
make tbuild [/root/AMDSEV/build/ovmf/Build/OvmfX64/DEBUG_GCC5/X64/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev]

build.py...
: error 7000: Failed to execute command
make tbuild [/root/AMDSEV/build/ovmf/Build/OvmfX64/DEBUG_GCC5/X64/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr]

build.py...
: error 7000: Failed to execute command
make tbuild [/root/AMDSEV/build/ovmf/Build/OvmfX64/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib]

build.py...
: error F002: Failed to build module
/root/AMDSEV/build/ovmf/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf [X64, GCC5, DEBUG]

  • Failed -
    Build end time: 20:56:07, Dec.07 2020
    Build total time: 00:00:09

ERROR: nice build -q --cmd-len=64436 -DDEBUG_ON_SERIAL_PORT=TRUE -n 32 -t GCC5 -a X64 -p OvmfPkg/OvmfPkgX64.dsc
root@unibox:~/AMDSEV/build#

I tried differnet OSes with the same result:
Ubuntu 18.04, Debian 10, Centos 7, Centos 8.

I guess that the problem is somewhere in the code of other repositories (probably the code was updated there) used for the build, but where exactly I could not figure out even with Google. Could you please help with this?

Thanks!

@tlendacky
Copy link
Collaborator

You can get more detailed error information by doing:
cd ~/AMDSEV/build/ovmf
. ./edksetup.sh
nice build -q --cmd-len=64436 -DDEBUG_ON_SERIAL_PORT=TRUE -n 32 -t GCC5 -a X64 -p OvmfPkg/OvmfPkgX64.dsc

@churkanerusskaya
Copy link
Author

Hello

Thanks for the answer, but no more detail info, unfortunately:

root@unibox:/AMDSEV/build# cd ovmf/
root@unibox:
/AMDSEV/build/ovmf# . ./edksetup.sh
Loading previous configuration from /root/AMDSEV/build/ovmf/Conf/BuildEnv.sh
WORKSPACE: /root/AMDSEV/build/ovmf
EDK_TOOLS_PATH: /root/AMDSEV/build/ovmf/BaseTools
CONF_PATH: /root/AMDSEV/build/ovmf/Conf
root@unibox:~/AMDSEV/build/ovmf# nice build -q --cmd-len=64436 -DDEBUG_ON_SERIAL_PORT=TRUE -n 32 -t GCC5 -a X64 -p OvmfPkg/OvmfPkgX64.dsc
Build environment: Linux-4.15.0-126-generic-x86_64-with-Ubuntu-18.04-bionic
Build start time: 21:39:27, Dec.07 2020

WORKSPACE = /root/AMDSEV/build/ovmf
EDK_TOOLS_PATH = /root/AMDSEV/build/ovmf/BaseTools
CONF_PATH = /root/AMDSEV/build/ovmf/Conf
PYTHON_COMMAND = /usr/bin/python3.6

Processing meta-data ...... done!
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeHobLib/DxeHobLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxeLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiLib/UefiLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf [X64]
Building ... /root/AMDSEV/build/ovmf/PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BasePrintLib/BasePrintLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxePcdLib/DxePcdLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseLib/BaseLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf [X64]
Building ... /root/AMDSEV/build/ovmf/OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf [X64]

build.py...
: error 7000: Failed to execute command
make tbuild [/root/AMDSEV/build/ovmf/Build/OvmfX64/DEBUG_GCC5/X64/MdePkg/Library/BaseCpuLib/BaseCpuLib]

build.py...
: error 7000: Failed to execute command
make tbuild [/root/AMDSEV/build/ovmf/Build/OvmfX64/DEBUG_GCC5/X64/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev]

build.py...
: error 7000: Failed to execute command
make tbuild [/root/AMDSEV/build/ovmf/Build/OvmfX64/DEBUG_GCC5/X64/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr]

build.py...
: error 7000: Failed to execute command
make tbuild [/root/AMDSEV/build/ovmf/Build/OvmfX64/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib]

build.py...
: error F002: Failed to build module
/root/AMDSEV/build/ovmf/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf [X64, GCC5, DEBUG]

  • Failed -
    Build end time: 21:39:34, Dec.07 2020
    Build total time: 00:00:07

root@unibox:~/AMDSEV/build/ovmf#

@tlendacky
Copy link
Collaborator

Try removing the -q and adding -v to the build command and see if that helps.

@churkanerusskaya
Copy link
Author

-v is much more informative - iasl&nasm were missing. I would never have guessed.
Thanks a lot!

codomania added a commit that referenced this issue Mar 16, 2021
The PEI phases uses the MemEncryptSevSnpValidateSystemRam() to validate
the complete system RAM. The MemEncryptSev{Set,Clear}PageEncMask() are
later used by libraries/drivers to change the page state from private
to shared and vice versa.

The AmdSevDxe driver calls the MemEncryptSevClearPageEncMask() to remove
the encryption attribute from the reserved and non-existent memory regions.
Since these regions where not part of system RAM, and was not validated
during by the MemEncryptSevSnpValidateSystemRam() so we fail to
change the page state for these regions.

There are multiple approaches to fix it:

1) Add a new parameter to MemEncryptSevClearPageEncMask() that should be
   set by the caller to indicate whether the region is RAM or not.
OR
2) Lookup the address in the interval tree maintained by the
   MemEncryptSevSnpValidateSystemRam() to determine whether we validated
   the page in the past.
OR
3) Iterate through the Memory space GCD to calculate if the address
   the range is RAM.

For now, we chose #2 because it does not require a change to all the
caller of MemEncryptSevClearPageEncMask() and lookup routine is
already available.

Extend the SEV-ES workarea to pass the interval tree root pointer
so that we can perform the lookup. If the specified address
was not present in the tree, then do not invalidate the page as it
could result in page state change failure.

Cc: James Bottomley <jejb@linux.ibm.com
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
codomania added a commit that referenced this issue Mar 16, 2021
The PEI phases uses the MemEncryptSevSnpValidateSystemRam() to validate
the complete system RAM. The MemEncryptSev{Set,Clear}PageEncMask() are
later used by libraries/drivers to change the page state from private
to shared and vice versa.

The AmdSevDxe driver calls the MemEncryptSevClearPageEncMask() to remove
the encryption attribute from the reserved and non-existent memory regions.
Since these regions where not part of system RAM, and was not validated
during by the MemEncryptSevSnpValidateSystemRam() so we fail to
change the page state for these regions.

There are multiple approaches to fix it:

1) Add a new parameter to MemEncryptSevClearPageEncMask() that should be
   set by the caller to indicate whether the region is RAM or not.
OR
2) Lookup the address in the interval tree maintained by the
   MemEncryptSevSnpValidateSystemRam() to determine whether we validated
   the page in the past.
OR
3) Iterate through the Memory space GCD to calculate if the address
   the range is RAM.

For now, we chose #2 because it does not require a change to all the
caller of MemEncryptSevClearPageEncMask() and lookup routine is
already available.

Extend the SEV-ES workarea to pass the interval tree root pointer
so that we can perform the lookup. If the specified address
was not present in the tree, then do not invalidate the page as it
could result in page state change failure.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
codomania added a commit that referenced this issue Mar 19, 2021
The PEI phases uses MemEncryptSevSnpValidateSystemRam() to validate
the system RAM. MemEncryptSev{Set,Clear}PageEncMask() is
later used by libraries/drivers to change the page state from private
to shared and vice versa.

The AmdSevDxe driver calls the MemEncryptSevClearPageEncMask() to remove
the encryption attribute from the reserved and non-existent memory regions.
Those regions where not part of system RAM, and was not pre-validated
during PEI phase, so we fail to change the page state for it.

There are multiple approaches to fix it:

1) Add a new parameter to MemEncryptSevClearPageEncMask(), that should be
   set by the caller to indicate whether the region is RAM.
OR
2) Lookup the address in the interval tree maintained by the
   MemEncryptSevSnpValidateSystemRam() to determine whether we validated
   the page in the past.
OR
3) Iterate through the Memory space GCD to calculate if the address range
   is RAM.

For now, we have chosen #2, it does not require a changes to the
caller of MemEncryptSevClearPageEncMask() and lookup routine is
already available.

Extend the SEV-ES workarea to pass the interval tree root pointer
so that we can perform the lookup later. If the specified address
was not present in the tree, then do not invalidate the page as it
could result in page state change failure.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
codomania added a commit that referenced this issue Mar 19, 2021
The PEI phases uses MemEncryptSevSnpValidateSystemRam() to validate
the system RAM. MemEncryptSev{Set,Clear}PageEncMask() is
later used by libraries/drivers to change the page state from private
to shared and vice versa.

The AmdSevDxe driver calls the MemEncryptSevClearPageEncMask() to remove
the encryption attribute from the reserved and non-existent memory regions.
Those regions where not part of system RAM, and was not pre-validated
during PEI phase, so we fail to change the page state for it.

There are multiple approaches to fix it:

1) Add a new parameter to MemEncryptSevClearPageEncMask(), that should be
   set by the caller to indicate whether the region is RAM.
OR
2) Lookup the address in the interval tree maintained by the
   MemEncryptSevSnpValidateSystemRam() to determine whether we validated
   the page in the past.
OR
3) Iterate through the Memory space GCD to calculate if the address range
   is RAM.

For now, we have chosen #2, it does not require a changes to the
caller of MemEncryptSevClearPageEncMask() and lookup routine is
already available.

Extend the SEV-ES workarea to pass the interval tree root pointer
so that we can perform the lookup later. If the specified address
was not present in the tree, then do not invalidate the page as it
could result in page state change failure.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
codomania added a commit that referenced this issue Mar 23, 2021
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The PEI phases uses MemEncryptSevSnpValidateSystemRam() to validate
the system RAM. MemEncryptSev{Set,Clear}PageEncMask() is
later used by libraries/drivers to change the page state from private
to shared and vice versa.

The AmdSevDxe driver calls the MemEncryptSevClearPageEncMask() to remove
the encryption attribute from the reserved and non-existent memory regions.
Those regions where not part of system RAM, and was not pre-validated
during PEI phase, so we fail to change the page state for it.

There are multiple approaches to fix it:

1) Add a new parameter to MemEncryptSevClearPageEncMask(), that should be
   set by the caller to indicate whether the region is RAM.
OR
2) Lookup the address in the interval tree maintained by the
   MemEncryptSevSnpValidateSystemRam() to determine whether we validated
   the page in the past.
OR
3) Iterate through the Memory space GCD to calculate if the address range
   is RAM.

For now, we have chosen #2, it does not require a changes to the
caller of MemEncryptSevClearPageEncMask() and lookup routine is
already available.

Extend the SEV-ES workarea to pass the interval tree root pointer
so that we can perform the lookup later. If the specified address
was not present in the tree, then do not invalidate the page as it
could result in page state change failure.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
codomania pushed a commit that referenced this issue Apr 9, 2021
MpInitLib contains a function MicrocodeDetect() which is called by
all threads as an AP procedure.
Today this function contains below code:

    if (CurrentRevision != LatestRevision) {
      AcquireSpinLock(&CpuMpData->MpLock);
      DEBUG ((
        EFI_D_ERROR,
        "Updated microcode signature [0x%08x] does not match \
        loaded microcode signature [0x%08x]\n",
        CurrentRevision, LatestRevision
        ));
      ReleaseSpinLock(&CpuMpData->MpLock);
    }

When the if-check is passed, the code may call into PEI services:
1. AcquireSpinLock
   When the PcdSpinTimeout is not 0, TimerLib
   GetPerformanceCounterProperties() is called. And some of the
   TimerLib implementations would get the information cached in
   HOB. But AP procedure cannot call PEI services to retrieve the
   HOB list.

2. DEBUG
   Certain DebugLib relies on ReportStatusCode services and the
   ReportStatusCode PPI is retrieved through the PEI services.
   DebugLibSerialPort should be used.
   But when SerialPortLib is implemented to depend on PEI services,
   even using DebugLibSerialPort can still cause AP calls PEI
   services resulting hang.

It causes a lot of debugging effort on the platform side.

There are 2 options to fix the problem:
1. make sure platform DSC chooses the proper DebugLib and set the
   PcdSpinTimeout to 0. So that AcquireSpinLock and DEBUG don't call
   PEI services.
2. remove the AcquireSpinLock and DEBUG call from the procedure.

Option #2 is preferred because it's not practical to ask every
platform DSC to be written properly.

Following option #2, there are two sub-options:
2.A. Just remove the if-check.
2.B. Capture the CurrentRevision and ExpectedRevision in the memory
     for each AP and print them together from BSP.

The patch follows option 2.B.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
codomania added a commit that referenced this issue Apr 9, 2021
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The PEI phases uses MemEncryptSevSnpValidateSystemRam() to validate
the system RAM. MemEncryptSev{Set,Clear}PageEncMask() is
later used by libraries/drivers to change the page state from private
to shared and vice versa.

The AmdSevDxe driver calls the MemEncryptSevClearPageEncMask() to remove
the encryption attribute from the reserved and non-existent memory regions.
Those regions where not part of system RAM, and was not pre-validated
during PEI phase, so we fail to change the page state for it.

There are multiple approaches to fix it:

1) Add a new parameter to MemEncryptSevClearPageEncMask(), that should be
   set by the caller to indicate whether the region is RAM.
OR
2) Lookup the address in the interval tree maintained by the
   MemEncryptSevSnpValidateSystemRam() to determine whether we validated
   the page in the past.
OR
3) Iterate through the Memory space GCD to calculate if the address range
   is RAM.

For now, we have chosen #2, it does not require a changes to the
caller of MemEncryptSevClearPageEncMask() and lookup routine is
already available.

Extend the SEV-ES workarea to pass the interval tree root pointer
so that we can perform the lookup later. If the specified address
was not present in the tree, then do not invalidate the page as it
could result in page state change failure.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
codomania added a commit that referenced this issue Apr 28, 2021
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3275

The PEI phases uses MemEncryptSevSnpValidateSystemRam() to validate
the system RAM. MemEncryptSev{Set,Clear}PageEncMask() is
later used by libraries/drivers to change the page state from private
to shared and vice versa.

The AmdSevDxe driver calls the MemEncryptSevClearPageEncMask() to remove
the encryption attribute from the reserved and non-existent memory regions.
Those regions where not part of system RAM, and was not pre-validated
during PEI phase, so we fail to change the page state for it.

There are multiple approaches to fix it:

1) Add a new parameter to MemEncryptSevClearPageEncMask(), that should be
   set by the caller to indicate whether the region is RAM.
OR
2) Lookup the address in the interval tree maintained by the
   MemEncryptSevSnpValidateSystemRam() to determine whether we validated
   the page in the past.
OR
3) Iterate through the Memory space GCD to calculate if the address range
   is RAM.

For now, we have chosen #2, it does not require a changes to the
caller of MemEncryptSevClearPageEncMask() and lookup routine is
already available.

Extend the SEV-ES workarea to pass the interval tree root pointer
so that we can perform the lookup later. If the specified address
was not present in the tree, then do not invalidate the page as it
could result in page state change failure.

Cc: James Bottomley <jejb@linux.ibm.com>
Cc: Min Xu <min.m.xu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
tlendacky pushed a commit that referenced this issue Jul 28, 2022
The AP vector consists of 2 parts:
1. the initial 16-bit code that should be under 1MB and page aligned.
2. the 32-bit/64-bit code that can be anywhere in the memory with any
   alignment.

The need of part #2 is because the memory under 1MB is temporary
"stolen" for use and will "give" back after all AP wake up. The range
of memory is not marked as code page in page table. CPU may trigger
exception as soon as NX is enabled.

The part #2 memory allocation can be done in the MpInitLibInitialize.

Signed-off-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
tlendacky pushed a commit that referenced this issue Jan 26, 2024
Root cause:
1. Before DisableReadonlyPageWriteProtect() is called, the return
address (#1) is pushed in shadow stack.
2. CET is disabled.
3. DisableReadonlyPageWriteProtect() returns to #1.
4. Page table is modified.
5. EnableReadonlyPageWriteProtect() is called, but the return
address (#2) is not pushed in shadow stack.
6. CET is enabled.
7. EnableReadonlyPageWriteProtect() returns to #2.
#CP exception happens because the actual return address (#2)
doesn't match the return address stored in shadow stack (#1).

Analysis:
Shadow stack will stop update after CET disable (DisableCet() in
DisableReadOnlyPageWriteProtect), but normal smi stack will be
continue updated with the function called and return
(DisableReadOnlyPageWriteProtect & EnableReadOnlyPageWriteProtect),
thus leading stack mismatch after CET re-enabled (EnableCet() in
EnableReadOnlyPageWriteProtect).

According SDM Vol 3, 6.15-Control Protection Exception:
Normal smi stack and shadow stack must be matched when CET enable,
otherwise CP Exception will happen, which is caused by a near RET
instruction.

CET is disabled in DisableCet(), while can be enabled in
EnableCet(). This way won't cause the problem because they are
implemented in a way that return address of DisableCet() is
poped out from shadow stack (Incsspq performs a pop to increases
the shadow stack) and EnableCet() doesn't use "RET" but "JMP" to
return to caller. So calling EnableCet() and DisableCet() doesn't
have the same issue as calling DisableReadonlyPageWriteProtect()
and EnableReadonlyPageWriteProtect().

With above root cause & analysis, define below 2 macros instead of
functions for WP & CET operation:
WRITE_UNPROTECT_RO_PAGES (Wp, Cet)
WRITE_PROTECT_RO_PAGES (Wp, Cet)
Because DisableCet() & EnableCet() must be in the same function
to avoid shadow stack and normal SMI stack mismatch.

Note: WRITE_UNPROTECT_RO_PAGES () must be called pair with
WRITE_PROTECT_RO_PAGES () in same function.

Change-Id: I4e126697efcd8dbfb4887da034d8691bfca969e3
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Zeng Star <star.zeng@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
mdroth pushed a commit that referenced this issue Mar 29, 2024
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4535

Bug Details:
PixieFail Bug #2
CVE-2023-45230
CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H
CWE-119 Improper Restriction of Operations within the Bounds
 of a Memory Buffer

Changes Overview:
> -UINT8 *
> +EFI_STATUS
>  Dhcp6AppendOption (
> -  IN OUT UINT8   *Buf,
> -  IN     UINT16  OptType,
> -  IN     UINT16  OptLen,
> -  IN     UINT8   *Data
> +  IN OUT EFI_DHCP6_PACKET  *Packet,
> +  IN OUT UINT8             **PacketCursor,
> +  IN     UINT16            OptType,
> +  IN     UINT16            OptLen,
> +  IN     UINT8             *Data
>    );

Dhcp6AppendOption() and variants can return errors now.  All callsites
are adapted accordingly.

It gets passed in EFI_DHCP6_PACKET as additional parameter ...

> +  //
> +  // Verify the PacketCursor is within the packet
> +  //
> +  if (  (*PacketCursor < Packet->Dhcp6.Option)
> +     || (*PacketCursor >= Packet->Dhcp6.Option +
 (Packet->Size - sizeof (EFI_DHCP6_HEADER))))
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }

... so it can look at Packet->Size when checking buffer space.
Also to allow Packet->Length updates.

Lots of checks added.

Cc: Saloni Kasbekar <saloni.kasbekar@intel.com>
Cc: Zachary Clark-williams <zachary.clark-williams@intel.com>

Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
mdroth pushed a commit that referenced this issue Mar 19, 2025
This patch does not impact functionality. It aims to clarify the
synchronization flow between the BSP and APs to enhance code
readability and understanding:

Steps #6 and #11 are the basic synchronization requirements for all
cases.

Steps #1 is additional requirements if the MmCpuSyncModeTradition
mode is selected.

Steps #1, #2, #3, #4, #5, #7, #8, #9, and #10 are additional
requirements if the system needs to configure the MTRR.

Steps #9 and #10 are additional requirements if the system needs to
support the mSmmDebugAgentSupport.

Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
mdroth pushed a commit that referenced this issue Mar 19, 2025
… func

This patch is for PiSmmCpuDxeSmm driver to add one round wait/release sync
for BSP and AP to perform the SMM CPU Platform Hook before executing MMI
Handler: SmmCpuPlatformHookBeforeMmiHandler (). With the function, SMM CPU
driver can perform the platform specific items after one round BSP and AP
sync (to make sure all APs in SMI) and before the MMI handlers.

After the change, steps #1 and #2 are additional requirements if the
MmCpuSyncModeTradition mode is selected.

Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants