> On Jan 22, 2021, at 4:25 PM, Laszlo Ersek wrote: > > On 01/22/21 23:40, Tom Lendacky wrote: > >> Can SetVirtualAddressMap() be called more than once? > > According to the UEFI spec: no, it can't. > > The call to SetVirtualAddressMap() must be done with the physical > mappings. On successful return from this function, the system must > then make any future calls with the newly assigned virtual mappings. > > [...] > > The SetVirtualAddressMap() and ConvertPointer() services are only > callable in physical mode, so they do not need to be converted from > physical pointers to virtual pointers. > > [...] > > A virtual address map may only be applied one time. Once the runtime > system is in virtual mode, calls to this function return > EFI_UNSUPPORTED. > > (I seem to detect a bit of contradiction between quotes #1+#2 and #3 -- > the first two quotes seem to explain that a second call is expected to > be impossible, whereas the third quote explains how a second or later > call should behave. But, anyway, the intent is clear.) > Laszlo, So the answer is no you can’t call it more than once. While the text is confusing it describes the only possible behavior. If you look at the EFI_UNSUPPORTED Status Codes Returned: "EFI firmware is not at runtime, or the EFI firmware is already in virtual address mapped mode.” This is what the edk2 implementation does [1]. And combine that with this text "Once all events have been notified, the EFI firmware reapplies image “fix-up” information to virtually relocate all runtime images to their new addresses. “. So basically that implies that after the1st call all the Runtime drivers have been fixed up to run at their virtual address. So if you called them again at their physical mode address they would likely crash. That crash could be implementation dependent I guess based on when the EFI virtual mappings are produced. It is perfectly legal to only produce them in kernel after ExitBootServices. Remember all the notification functions are registered via their physical address. [1] https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/RuntimeDxe/Runtime.c#L245 it enforces the call only once. // // Can only switch to virtual addresses once the memory map is locked down, // and can only set it once // if (!mRuntime.AtRuntime || mRuntime.VirtualMode) { return EFI_UNSUPPORTED; } // // Only understand the original descriptor format // if (DescriptorVersion != EFI_MEMORY_DESCRIPTOR_VERSION || DescriptorSize < sizeof (EFI_MEMORY_DESCRIPTOR)) { return EFI_INVALID_PARAMETER; } // // We are now committed to go to virtual mode, so lets get to it! // mRuntime.VirtualMode = TRUE; Thanks, Andrew Fish > Thanks, > Laszlo > > > > > >