On 10/02/19 17:15, Laszlo Ersek wrote: > Adding Phil. > > I'm looking at this patch only because one thing caught my attention in > the previous one, "OvmfPkg: Add support for SEV-ES AP reset vector > re-directing": > > On 09/19/19 21:53, Lendacky, Thomas wrote: >> From: Tom Lendacky <thomas.lenda...@amd.com> >> >> BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198 >> >> Typically, an AP is booted using the INIT-SIPI-SIPI sequence. This >> sequence is intercepted by the hypervisor, which sets the AP's registers >> to the values requested by the sequence. At that point, the hypervisor can >> start the AP, which will then begin execution at the appropriate location. >> >> Under SEV-ES, AP booting presents some challenges since the hypervisor is >> not allowed to alter the AP's register state. In this situation, we have >> to distinguish between the AP's first boot and AP's subsequent boots. >> >> First boot: >> Once the AP's register state has been defined (which is before the guest >> is first booted) it cannot be altered. Should the hypervisor attempt to >> alter the register state, the change would be detected by the hardware >> and the VMRUN instruction would fail. Given this, the first boot for the >> AP is required to begin execution with this initial register state, which >> is typically the reset vector. This prevents the BSP from directing the >> AP startup location through the INIT-SIPI-SIPI sequence. >> >> To work around this, provide a four-byte field at offset 0xffffffd0 that >> can contain an IP / CS register combination, that if non-zero, causes >> the AP to perform a far jump to that location instead of a near jump to >> EarlyBspInitReal16. Before booting the AP for the first time, the BSP >> should set the IP / CS value for the AP based on the value that would be >> derived from the INIT-SIPI-SIPI sequence. > > I don't understand how this can work: the guest-phys address 0xffffffd0 > is backed by read-only pflash in most OVMF deployments. > > In addition: > > [...] > >> @@ -1002,6 +1204,7 @@ WakeUpAP ( >> CpuMpData->InitFlag != ApInitDone) { >> ResetVectorRequired = TRUE; >> AllocateResetVector (CpuMpData); >> + AllocateSevEsAPMemory (CpuMpData); >> FillExchangeInfoData (CpuMpData); >> SaveLocalApicTimerSetting (CpuMpData); >> } >> @@ -1038,6 +1241,15 @@ WakeUpAP ( >> } >> } >> if (ResetVectorRequired) { >> + // >> + // For SEV-ES, set the jump address for initial AP boot >> + // >> + if (CpuMpData->SevEsActive) { >> + SEV_ES_AP_JMP_FAR *JmpFar = (SEV_ES_AP_JMP_FAR *)0xFFFFFFD0; >> + >> + JmpFar->ApStart.Rip = 0; >> + JmpFar->ApStart.Segment = (UINT16) (ExchangeInfo->BufferStart >> 4); >> + } > > Even if the address is backed by a single "unified" pflash, mapped r/w > -- which we can call a "non-standard OVMF deployment" nowadays --, a > normal store doesn't appear sufficient to me. The first write to pflash > will flip it to "programming mode", and the values stored are supposed > to be pflash commands (not just the raw data we intend to put in place). > > See for example the QemuFlashWrite() function in > "OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c". (But, again, that > is used with the pflash chip that hosts the variable store, and is > therefore mapped r/w.) > > > Taking a step back... I don't think APs execute any code from pflash, > when MpInitLib boots them. > > In OVMF, PcdCpuApLoopMode is ApInHltLoop (value 1), therefore > "CpuMpData->WakeUpByInitSipiSipi" should be TRUE, and > "ResetVectorRequired" too should be TRUE, at first AP boot. > Consequently, the reset vector seems to be allocated with > AllocateResetVector(). > > AllocateResetVector() has separate implementations for PEI and DXE, but > in both cases, it returns RAM. So I don't see where the AP accesses (or > executes) pflash.
... I believe I understand that this is precisely what cannot work under SEV-ES -- because we cannot launch an AP at an address that's dynamically chosen by the firmware (and passed to the hypervisor), like with INIT-SIPI-SIPI. And so firmware and hypervisor have to agree upon a *constant* AP reset vector address, in advance. We have two options: - pick the reset vector address *constant* such that it falls into RAM, or - let the AP reset vector reside in pflash, but then the code in pflash has to look for a parameter block at a fixed address in RAM. So in the end, both options require the same -- we need a RAM address constant that is determined at firmware build time. Either for the reset vector itself, or for the reset vector's parameter block. Thanks Laszlo -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#48377): https://edk2.groups.io/g/devel/message/48377 Mute This Topic: https://groups.io/mt/34203585/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-