On April 16, 2022 11:09 PM, Lendacky, Thomas wrote:
On 4/15/22 20:57, Xu, Min M wrote:
On April 16, 2022 4:52 AM, Lendacky, Thomas wrote:
Unfortunately, this driver also breaks SEV-ES. I bypassed the TDX code in the SEC library, but then hit an issue because this driver is loaded before the AmdSevDxe driver. The AmdSevDxe driver performs a MemEncryptSevClearMmioPageEncMask() call against the PcdPciExpressBaseAddress range to mark it shared/unencrypted. However, the TdxDxe driver is loaded before the AmdSevDxe driver, and it appears the dependencies result in an MMIO being performed to an address in the PcdPciExpressBaseAddress range. Since the range has not been marked shared/unencrypted, the #VC handler terminates the guest for trying to do MMIO to an encrypted region.
I carefully check the code TdxDxeEntryPoint@.... If the working guest is NOT td guest, before it returns, it just does below: 1. check if the GuidHob exists 2. Set PcdOvmfHostBridgePciDevId with the information in the GuidHob
SetMmioSharedBit() is called if the working guest is Td guest. So if it is sev
guest, SetMmioSharedBit will not be called.
I don't have a SEV-ES in hand. Can you help to add some debug
information in TdxDxe to see what the last code before the exception is triggered?
I don't think it is anything in your code, I think it is another library that is being loaded based on dependencies. I put a DEBUG statement at the start of TdxDxeEntryPoint() and never see the output before the crash.
I check the libraries loaded by TdxDxe and AmdSev and find that they load different PciLib. TdxDxe load PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf. AmdSev load PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf. PciLib is consumed by DxeAcpiTimerLib. In the AcpiTimerLibConstructor@DxeAcpiTimerLib there is below code: mAcpiTimerIoAddr = (PciRead32 (Pmba) & ~PMBA_RTE) + ACPI_TIMER_OFFSET; I think this is the root cause of the exception. There are 2 options to fix this issue. 1. Load AmdSev before TdxDxe 2. Make TdxDxe to import BasePciLibCf8.inf instead of DxePciLibI440FxQ35.inf (just like AmdSev) I tried above 2 options in my Tdx guest and both work. Tom, Can you help to try above 2 options in your SEV guest to see whether they work?
BTW, have you tried to load AmdSev.inf before TdxDxe.inf? I tried it in my
TDX guest and it works fine.
Yes, moving AmdSevDxe.inf ahead of TdxDxe.inf does fix this issue. Do you want to submit the patch or do you want me to?
If above option 2 works, I prefer this option to fix the issue. Because there is still potential issues in option 1. I will submit the patch.
I added the same library class override to TdxDxe and, yes, option 2 worked.